Например TDA7294

Форум РадиоКот • Просмотр темы - Автоматический выход из ждущего режима uart_receive();
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Вс сен 28, 2025 06:33:39

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 31 ]    , 2
Автор Сообщение
Не в сети
 Заголовок сообщения: Re: Автоматический выход из ждущего режима uart_receive();
СообщениеДобавлено: Чт авг 11, 2022 16:15:46 
Родился

Зарегистрирован: Чт мар 18, 2021 16:47:20
Сообщений: 11
Рейтинг сообщения: 0
AlexandrRa писал(а):
так правильней.

Да хоть так, главная тут задача, отвязаться от c = uart_receive(); на время выполнения условия с циклом for, вот никак не смог отвязать разве что часто нажатием какой нибудь клавиши


Последний раз редактировалось Sulik Чт авг 11, 2022 21:14:51, всего редактировалось 3 раз(а).

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Автоматический выход из ждущего режима uart_receive();
СообщениеДобавлено: Чт авг 11, 2022 16:23:22 
Открыл глаза

Карма: 3
Рейтинг сообщений: 9
Зарегистрирован: Чт ноя 26, 2020 13:19:49
Сообщений: 74
Рейтинг сообщения: 0
Код:
void uart_handler_RX(void)
{
if (y < Size_data)  // если весь пакет не принят
  {
    data[y] = UDR0;  // запись следующего байта data[y]
    y++;  // счётчик байт
    return;
  }
  y=0;
}

И добавь прерывание по приёму

Добавлено after 2 minutes 18 seconds:
Код:
uint8_t flag = 0;
uint8_t Size_data = 12; // например передаём 12 байт

ISR(PCINT0_vect){
   if(PINB & (1 << PB0)) flag = 1; // Разрешение передачи данных
}

int main(){
   UART_init();
   interrupt_init();
   sei();
   
   while(1){
      if (flag){
         for (y = 0; y < Size_data ; y++){
            uart_transmit(data[y]);
         }
       flag = 0; // Данные переданы
      }
}


и с на фиг ненужно стало

Добавлено after 3 minutes 10 seconds:
Что за МК хоть?


Последний раз редактировалось AlexandrRa Чт авг 11, 2022 16:26:00, всего редактировалось 1 раз.

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Автоматический выход из ждущего режима uart_receive();
СообщениеДобавлено: Чт авг 11, 2022 16:29:34 
Родился

Зарегистрирован: Чт мар 18, 2021 16:47:20
Сообщений: 11
Рейтинг сообщения: 0
AlexandrRa писал(а):
И не закрывай посылку значением данных в передаче. Отучайся от этого.

Иногда очень необходимо бывает закрыться именно "\0", есть такие моменты в коде где именно так необходимо учитывая, что количество символов в одном массиве данных могут быть разной длины, то увеличится эта длина то уменьшится.

Добавлено after 2 minutes 34 seconds:
AlexandrRa писал(а):
Что за МК хоть?
Atmega 328P

Добавлено after 2 minutes 59 seconds:
AlexandrRa писал(а):
И добавь прерывание по приёму

Это у меня добавлено, просто код я привел как пример


Последний раз редактировалось Sulik Чт авг 11, 2022 21:07:56, всего редактировалось 1 раз.

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Автоматический выход из ждущего режима uart_receive();
СообщениеДобавлено: Чт авг 11, 2022 16:31:09 
Открыл глаза

Карма: 3
Рейтинг сообщений: 9
Зарегистрирован: Чт ноя 26, 2020 13:19:49
Сообщений: 74
Рейтинг сообщения: 0
Передавай в первом байте размер пакета. Аналогично и при приёме делай. Избежишь проблем. Представь что у тебя в пакете байт по середине указывает на открытие или закрытия 8 дверей. В какой то момент можно передать не всю посылку, а лишь часть её.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Автоматический выход из ждущего режима uart_receive();
СообщениеДобавлено: Чт авг 11, 2022 16:42:22 
Родился

Зарегистрирован: Чт мар 18, 2021 16:47:20
Сообщений: 11
Рейтинг сообщения: 0
AlexandrRa писал(а):
и с на фиг ненужно стало

Он нужен в другом коде, просто приведенном мною примере он не нужен, но он нужен это для приема неких команд и отправка этих команд в нужное условие с данными

Добавлено after 6 minutes 32 seconds:
Задача тут очень понятная, например консоль putty будет постоянно открыть по UART с МК, ждет ввода команд с клавы, но в то же время как только придет нужное прерывание отвязаться от uart_receive(); и начал обрабатывать другое условие с циклом с выводом данных на консоль и после обработки вернулась в тот же режим uart_receive();


Последний раз редактировалось Sulik Чт авг 11, 2022 21:07:09, всего редактировалось 1 раз.

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Автоматический выход из ждущего режима uart_receive();
СообщениеДобавлено: Чт авг 11, 2022 18:52:34 
Модератор
Аватар пользователя

Карма: 153
Рейтинг сообщений: 2925
Зарегистрирован: Сб авг 14, 2010 15:05:51
Сообщений: 18831
Откуда: г. Озерск, Челябинская обл.
Рейтинг сообщения: 0
Медали: 1
Лучший человек Форума 2017 (1)
Sulik, смотри, в каком сообщении ты жмешь кнопку "цитата".
а то получается, что всё тобой процитированное, написано тобой, а не тем человеком, откуда ты взял цитату.

_________________
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Автоматический выход из ждущего режима uart_receive();
СообщениеДобавлено: Пт авг 12, 2022 07:46:36 
Открыл глаза

Карма: 3
Рейтинг сообщений: 9
Зарегистрирован: Чт ноя 26, 2020 13:19:49
Сообщений: 74
Рейтинг сообщения: 0
Цитата:
Задача тут очень понятная, например консоль putty будет постоянно открыть по UART с МК, ждет ввода команд с клавы, но в то же время как только придет нужное прерывание отвязаться от uart_receive(); и начал обрабатывать другое условие с циклом с выводом данных на консоль и после обработки вернулась в тот же режим uart_receive();

Нафига сидеть и ждать приёма? За этим прекрасно сможет следить флаг прерывания. А нужное прерывание смотри по флагу или данным в основном цикле. В этом случае ты всегда будешь отвязан от uart_receive(). И я бы лучше уходил в сон во время ожидания приёма, вместо того чтобы жрать энергию.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Автоматический выход из ждущего режима uart_receive();
СообщениеДобавлено: Пт авг 12, 2022 14:25:10 
Мудрый кот

Карма: 20
Рейтинг сообщений: 145
Зарегистрирован: Вс дек 25, 2016 08:34:54
Сообщений: 1849
Рейтинг сообщения: 0
Sulik писал(а):
Задача тут очень понятная,
Вам командная консоль нужна или как?
А команды какого вида, по символьные или пакетные, заканчивающие определенным символом или еще как?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Автоматический выход из ждущего режима uart_receive();
СообщениеДобавлено: Пт авг 12, 2022 14:54:10 
Мучитель микросхем

Карма: 4
Рейтинг сообщений: 38
Зарегистрирован: Вт фев 09, 2010 17:52:26
Сообщений: 469
Рейтинг сообщения: 0
Не советую так делать, есть возможность прочитать не тот байт или потерять вообще всю посылку. Т. к. чтение данных будет только один раз за цикл. А если данные приходят несколько раз за цикл и неизвестно когда по времени? Очень легко пропустить посылку.

Расскажите это тем кто написал и тем кто применяет software serial.

Если бездумно сидеть в цикле, то всегда существует вероятность потерять данные, даже если применяются прерывания.

Приведенный код будет работать, но если есть аппаратная поддержка, то не применять аппаратные прерывания нет смысла.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Автоматический выход из ждущего режима uart_receive();
СообщениеДобавлено: Пт авг 12, 2022 16:17:40 
Родился

Зарегистрирован: Чт мар 18, 2021 16:47:20
Сообщений: 11
Рейтинг сообщения: 0
Sulik писал(а):
Задача тут очень понятная,
Вам командная консоль нужна или как?
А команды какого вида, по символьные или пакетные, заканчивающие определенным символом или еще как?

Да именно консоль, а команды могут быть и те и другие, по ситуации.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Автоматический выход из ждущего режима uart_receive();
СообщениеДобавлено: Пт авг 12, 2022 18:09:14 
Мудрый кот

Карма: 20
Рейтинг сообщений: 145
Зарегистрирован: Вс дек 25, 2016 08:34:54
Сообщений: 1849
Рейтинг сообщения: 0
Вот пример, смотрите
Спойлерреализован кольцевой буфер приема
поддержка по символьных или пакетных команд, заканчивающих символом ENTER
поддержка примитивного редактирования при помощи backspace

код написан под компилятор CVAVR, то есть под компилятор winavr (interrupt [USART_RXC] void usart_rx_isr(void)) надо поменять на ISR(USART_RX_vect) и #asm("sei") на sei();

по умолчанию строка вида '0' - turn off LED располагается в RAM ее надо перенести во FLASH
Код:
#include <mega328p.h>

// Standard Input/Output functions
#include <stdio.h>

// Declare your global variables here

#define DATA_REGISTER_EMPTY (1<<UDRE0)
#define RX_COMPLETE (1<<RXC0)
#define FRAMING_ERROR (1<<FE0)
#define PARITY_ERROR (1<<UPE0)
#define DATA_OVERRUN (1<<DOR0)

// USART Receiver buffer
#define MAX_DMA_BUFFERS_COUNT 32     // 4 8 16 32 64 128
#define BUFFER_MASK (MAX_DMA_BUFFERS_COUNT-1)
volatile unsigned char BUFF_RX_BUF[MAX_DMA_BUFFERS_COUNT]={0};
volatile unsigned char DMA_WR_BUF = 0;
volatile unsigned char DMA_RD_BUF = 0;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   { 
      BUFF_RX_BUF[DMA_WR_BUF] = data;
      DMA_WR_BUF++;
     DMA_WR_BUF &= BUFFER_MASK;   
   }
}


#include <string.h>

char b_start=0, b_end=0, len_buff=0, len=0;
bit flag=0;
char buff[24]; // максимальная длинна команды
unsigned long main_p=0;

unsigned long my_atoi(char *str)
{
   unsigned long result = 0;

   if ('0'>*str || *str>'9')
   {
      str++;
   }
   while (*str != '\0')
   {
      if ('0'> *str || *str>'9')
         break;
      else
         result = result * 10 + (*str++ - '0');
   }
   return result;
}

static char respcmp(char *s, const char  *resp){
   while(*resp)
      if(*resp++ != *s++) return 0;
   return 1;
}

void usart_send_str(const char* str)
{
    while(*str) {
    while (!(UCSR0A & (1<<UDRE0))) {}
       UDR0 = *str++;
    }
}

#define SEND(str) usart_send_str(str)

void help(void)      // HELP
{
   SEND("\r\n");
   SEND("\t'0' - turn off LED\r\n");
   SEND("\t'1' - turn on LED\r\n");
   SEND("\t'LED ON' - turn on LED\r\n");
   SEND("\t'LRD OFF' - turn off LED\r\n");
   SEND("\t'TOGGLE' - turn toggle LED\r\n");
   SEND("\t'COUNT=N' - set all value by N (decimal):\r\n");
   SEND("\tSTAT - shows which mode the automatic/off mode is in\r\n");

   SEND("\tHELP - help\r\n");
   SEND("\r\n");
}

// print 32bit unsigned int
void printu(unsigned long val){
    char bufa[11];
    char bufb[10];
    int i;
    int l = 0, bpos = 0;
    if(!val){
        bufa[0] = '0';
        l = 1;
    }else{
        while(val){
            bufb[l++] = val % 10 + '0';
            val /= 10;
        }
        bpos += l;
        for(i = 0; i < l; ++i){
            bufa[--bpos] = bufb[i];
        }
    }
    bufa[l + bpos] = 0;
    SEND(bufa);
}

void main(void)

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART0 Mode: Asynchronous
// USART Baud Rate: 9600
UCSR0A=(0<<RXC0) | (0<<TXC0) | (0<<UDRE0) | (0<<FE0) | (0<<DOR0) | (0<<UPE0) | (0<<U2X0) | (0<<MPCM0);
UCSR0B=(1<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (1<<RXEN0) | (1<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);
UCSR0C=(0<<UMSEL01) | (0<<UMSEL00) | (0<<UPM01) | (0<<UPM00) | (0<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00) | (0<<UCPOL0);
UBRR0H=0x00;
UBRR0L=0x67;

// Global enable interrupts
#asm("sei")

while (1)
      {
      // Place your code here

        while (DMA_RD_BUF != (DMA_WR_BUF)) {
       
            b_start =  DMA_RD_BUF;  // Копируем позиции начала           
            DMA_RD_BUF++;
         DMA_RD_BUF &= BUFFER_MASK;
            b_end = DMA_RD_BUF;    // и конца буфера 
           
            // сборка команды
           len_buff = strlen((void*)buff); // определяем длину
           
            if(b_start < b_end) {
           len = b_end-b_start;
           memcpy(&buff[len_buff],(void*)&BUFF_RX_BUF[b_start],len);
           buff[len_buff+len]=0;
           }

           if(b_start > b_end) {
           len = MAX_DMA_BUFFERS_COUNT-b_start;
           memcpy(&buff[len_buff],(void*)&BUFF_RX_BUF[b_start],len);
           memcpy(&buff[len],BUFF_RX_BUF,b_end);
           buff[len_buff+len+b_end]=0;
           }

           // если BkSp - сдвигаем назад
           len_buff = strlen((void*)buff)-1; // определяем длину
           if((buff[len_buff] == 0x08)|| (buff[len_buff] == 0x7f)){
           // стираем символ
           // но не левее начала буфера
           if(len_buff > 0) buff[len_buff-1]=0; else buff[len_buff]=0;
           }

           // если Enter - ввод закончен
           if(((buff[len_buff] == '\n') || (buff[len_buff] == '\r'))) {
           flag=1; buff[len_buff]='\0'; // стираем символ Enter, заменяем концом строки \0
           }
        }
       
        // поиск обработчика
       if(flag) {
       
        len_buff = strlen((void*)buff); // определяем длину команды
        // если не использовать по символьные команды, то len_buff не нужен

       if(respcmp((void*)buff, "1") && len_buff == strlen("1")) { // это просто пример
            PORTB |= (1<<(0));
       }       

        if(respcmp((void*)buff, "0")&& len_buff == strlen("0")) {
            PORTB &= ~(1<<(0));
       }         
               
       if(respcmp((void*)buff, "LED ON") && len_buff == strlen("LED ON")) {
            PORTB |= (1<<(0));
       }
      
        if(respcmp((void*)buff, "LED OFF") && len_buff == strlen("LED OFF")) {
            PORTB &= ~(1<<(0));
       }
      
        if(respcmp((void*)buff, "TOGGLE") && len_buff == strlen("TOGGLE")) {
            PORTB ^= (1<<(0));
       }
                   
       if(respcmp((void*)buff, "COUNT=")) {
            main_p = my_atoi((buff + sizeof("COUNT=")-1));
       }
       
        if(respcmp((void*)buff, "PRINT") && len_buff == strlen("PRINT")) {
           SEND("\r\nPRINT= "); printu(main_p);SEND("\r\n");
       }
       
       if(respcmp((void*)buff, "HELP") && len_buff == strlen("HELP")) {
            help();
       }       
       
        buff[0]=0;
       flag=0;             
      }
  }

}
на CVAVR этот код занимает 405 байт RAM и 2156 байт FLASH


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 31 ]    , 2

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 13


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y