Например TDA7294

Форум РадиоКот :: Просмотр темы - Автоматический выход из ждущего режима uart_receive();
Форум РадиоКот
https://radiokot.ru/forum/

Автоматический выход из ждущего режима uart_receive();
https://radiokot.ru/forum/viewtopic.php?f=57&t=184057
Страница 1 из 2

Автор:  Sulik [ Вт авг 09, 2022 15:52:47 ]
Заголовок сообщения:  Автоматический выход из ждущего режима uart_receive();

Код:
 #define F_CPU 16000000UL          // Тактовая частота микроконтроллера
#define BAUD 9600UL                                 // Скоорость приемо-передачи для консоли
#define MYUBRR (F_CPU/(BAUD*16)-1)        // Согласно заданной скорости подсчитываем значение для регистра UBRR

 

void uart_init(void)                         // Объявление функции UART для скорости приемо передачи
 {
    UBRR0H=(MYUBRR>>8);               // Старшие 8 бит
    UBRR0L=MYUBRR;                                      // Младшие 8 бит)
    UCSR0B|=(1<<TXEN0)|(1<<RXEN0);                   // Бити разрешения приемо-передачи
    UCSR0C|=(1<<UCSZ00)|(1<<UCSZ01);                   // Устанавливем формат 8 бит данных
 }
 
 void uart_transmit(unsigned char data)                 // Объявление функции трансляции (вывода на экран)
 {
    while (!(UCSR0A & (1<<UDRE0)));                // Ожидаем когда очистится буфер передачи
   
   UDR0 = data;                                        // Помещаем данные в буфер, начинаем передачу
 }


 unsigned char uart_receive(void)
 {
   
   while(!(UCSR0A & (1<<RXC0)));                      // Ожидаем пока данные будут получены
   return UDR0;                               // Возврат 8-bit данные
                                         
 }

void USART_Flush(void){
   unsigned char dummy;
   while (UCSR0A & (1<<RXC0)) dummy = UDR0;
}


Добрый день! уважаемые форумчане, есть такая необходимость, как выход из ждущего режима например с = uart_receive(); по приему символа чтоб при получение некоторых данных на другие пины от датчика или от другого МК, выходил на короткое время пока не выводится некоторые символы с помощью функции uart_transmit(data[i]); в основном цикле из массива данных а потом сразу же после вывода символов данных, чтоб вернулся в режим готовности для приема символа с клавиатуры с = uart_receive();.
Что только не пробовал но никак не могу заставить UNO автоматически чтоб выходил из ждущего режима при получении данных для выполнения в основном цикле по выводу на консоль, данные будут выводиться на консоль Putty, как можно эту задачу организовать?

Автор:  COKPOWEHEU [ Ср авг 10, 2022 08:40:34 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

Изучайте прерывания и организовывайте обмен по-человечески, без "тупых" задержек.

Автор:  AlexandrRa [ Ср авг 10, 2022 09:51:56 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

Цитата:
unsigned char uart_receive(void)
{

while(!(UCSR0A & (1<<RXC0))); // Ожидаем пока данные будут получены
return UDR0; // Возврат 8-bit данные

}


Не проще ли организовать прерывание по приёму, чтоб не ждать флаг получения данных?

Добавлено after 20 minutes 49 seconds:
Код:
void USART1_IRQHandler(void)
{
  switch (регистр флагов прерывний(или событий))
  case (флаг принятых данных):
    принимаем данные;
    break; (или retutn данные)
  case (флаг передачи данных):
    делае чего нить после передачи данных (или не делаем);
    break;
  case (флаг пустого ругистра Rx/Tx):
    делае чего нить после (или не делаем);
    break;
  ...
  break;
}

Что-то вроде этого должно быть, нужно только правильно настроить прерывания по UART

Добавлено after 1 minute 20 seconds:
Сорят на АшиПки :)))

Автор:  COKPOWEHEU [ Ср авг 10, 2022 09:57:07 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

void USART1_IRQHandler(void)

Что-то вроде этого должно быть, нужно только правильно настроить прерывания по UART

Это же AVR, там у UART отдельный вектор на каждое событие

Автор:  AlexandrRa [ Ср авг 10, 2022 11:15:53 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

Цитата:
Это же AVR, там у UART отдельный вектор на каждое событие


Тогда вообще париться не нужно. Берёшь книжку Естевтеева про микроконтроллеры AVR (Если не ошибаюсь в фамилии автора) и читаешь что нужно делать. Там всё расписано до мелочей. Ну или наконец прочесть даташит. :))

Добавлено after 1 minute 19 seconds:
Кстати автор не написал каким МК пользуется...

Автор:  >TEHb< [ Ср авг 10, 2022 11:49:46 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

AlexandrRa, ардуиной. Думаю, мега328.

Автор:  Sulik [ Ср авг 10, 2022 15:02:54 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

Цитата:
Это же AVR, там у UART отдельный вектор на каждое событие


Тогда вообще париться не нужно. Берёшь книжку Естевтеева про микроконтроллеры AVR (Если не ошибаюсь в фамилии автора) и читаешь что нужно делать. Там всё расписано до мелочей. Ну или наконец прочесть даташит. :))

Добавлено after 1 minute 19 seconds:
Кстати автор не написал каким МК пользуется...

Автор:  codenamehawk [ Ср авг 10, 2022 15:19:36 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

Код:


 unsigned char uart_receive(void)
 {
   
   while(!(UCSR0A & (1<<RXC0)));                      // Ожидаем пока данные будут получены
   return UDR0;                               // Возврат 8-bit данные
                                         
 }


Добрый день! уважаемые форумчане, есть такая необходимость, как выход из ждущего режима например с = uart_receive();


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


Код:
 unsigned char uart_receive(void)
 {
   
   if ((UCSR0A & (1<<RXC0)))
       {             
          // Проверяем без ожидания, если данные получены, выставляем флаг ==1, если не получены сбрасываем флаг.
          bait_prochitan = 1;
        }else
        {
           bait_prichitan = 0; //нового байта нет
         }
         return bait_prochitan;
}

там где было с = uart_receive();
меняете на
if ( uart_receive() )
{
 c =  UDR0;
}

                                         
 }

Автор:  AlexandrRa [ Ср авг 10, 2022 15:33:18 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

Цитата:
Это надо самому придумать, конечно если нет желания использовать прерывания.
Введите еще одну переменную, в которой будет хранится информация приняли ли байт.


Не советую так делать, есть возможность прочитать не тот байт или потерять вообще всю посылку. Т. к. чтение данных будет только один раз за цикл. А если данные приходят несколько раз за цикл и неизвестно когда по времени? Очень легко пропустить посылку.

Автор:  Sulik [ Ср авг 10, 2022 16:04:25 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

Как на этом сайте вообще цитировать выделенный кусок текста и на этот косок текста ответить?

Автор:  >TEHb< [ Ср авг 10, 2022 16:29:20 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

Sulik, надо нажать "редактор", а уже дальше выделять нужный текст и нажимать на цитирование.

Автор:  Sulik [ Ср авг 10, 2022 16:36:19 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

>TEHb< писал(а):
надо нажать "редактор", а уже дальше выделять нужный текст и нажимать на цитирование.

Спасибо! на этом сайте чуть по другому эта система работает.

Автор:  Sulik [ Чт авг 11, 2022 03:07:37 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

В общем пришлось запихнуть циклы for по выводу данных в прерывания, по другому никак не получилось.

Автор:  Starichok51 [ Чт авг 11, 2022 10:07:21 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

AlexandrRa писал(а):
Берёшь книжку Естевтеева про микроконтроллеры AVR (Если не ошибаюсь в фамилии автора)
если не помнишь фамилию, то прежде, чем её писать, нужно сначала её найти, а не писать хаотический набор букв.

Автор:  COKPOWEHEU [ Чт авг 11, 2022 11:32:37 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

В общем пришлось запихнуть циклы for по выводу данных в прерывания, по другому никак не получилось.

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

Автор:  AlexandrRa [ Чт авг 11, 2022 13:24:00 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

Цитата:
Если я правильно понял написанное, вы только что подложили себе здоровенную мину.
:shock: :kill:
Согласен! Код в прерываниях должен быть минимальным. Я например в большинстве случаев там флаг сработки обычно ставлю. И НИКАКИХ ЦИКЛОВ В ПРЕРЫВАНИЯХ И ТЕМБОЛЕЕ ЗАДЕРЖЕК!!! Потом кода нужно, смотрю флаг и выполняю от этого флага всё что нужно (или не выполняю :)) ).

Добавлено after 6 minutes 16 seconds:
Код:
union Flags
{
    uint8_t TIM2_Flag: 1;       // сработка прерывания Timer2
    uint8_t TIM1_Flag: 1;       // сработка прерывания Timer1
    unit8_t  EXTI3_Flag: 1;    // сработка прерывания EXTI3
    uint8_t : 5;                // Резерв
} Status;

......

if (Status.EXTI3_Flag)
{
  ......
  Status.EXTI3_Flag= 0;
}

void EXTI3_IRQHandler(void)
{
  Status.EXTI3_Flag= 1;
/* Сброс флагов прерывания */
  EXTI_ClearITPendingBit(EXTI_Line3);
}



Что-то вроде этого...

Автор:  Sulik [ Чт авг 11, 2022 13:49:01 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

Starichok51 писал(а):
Какие еще циклы в прерываниях?!

например таких несколько штук
Код:
for(y = 0; data[y] != '\0'; y++){
            uart_transmit(data[y]);
        }

без каких либо задержек в delay, пока что работает без проблем.

Автор:  AlexandrRa [ Чт авг 11, 2022 14:41:32 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

Лучше сделать
Код:
  if (!Flag_data)  // Проверка на начало приёма пакета
  {
   uart_transmit(data[0]);  // в первом байте размер пакета
   Flag_data=1;
  }
  else  if (data[0] != y)  // если весь пакет не принят
  {
    y++;  // счётчик байт
    uart_transmit(data[y]);  // запись следующего байта data[y]
    return;
  }
  Flag_data=0;


Добавлено after 4 minutes 34 seconds:
СТОП!!! uart_transmit(data[y]) это же передача. Тогда годится. У меня uart_transmit нужно заменить на uart_receive :)) :)) :))

Добавлено after 2 minutes 48 seconds:
Но лучше "0" пакет не закрывать. Лучше так.
Код:
for(y = 0; y <= SizePack; y++){
            uart_transmit(data[y]);
        }

Автор:  Sulik [ Чт авг 11, 2022 15:04:51 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

Sulik писал(а):
У меня uart_transmit нужно заменить на uart_receive

Вот проверь например в протеусе, уверен не заработает как надо если там будет присутствовать например char c = uart_receive();

Добавлено after 15 minutes 39 seconds:
Код:
char c;
uint8_t flag = 0;

ISR(PCINT0_vect){
   if(PINB & (1 << PB0)){
      flag = 1;
   }else{
      flag = 0;
   }
}

int main(){
   interrupt_init();
   sei();
   
   while(1){
      if(flag == 1){
         for(y = 0; data[y] != '\0'; y++){
            uart_transmit(data[y]);
         }
      }
      c = uart_receive();
   }
   
}


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

Автор:  AlexandrRa [ Чт авг 11, 2022 16:10:08 ]
Заголовок сообщения:  Re: Автоматический выход из ждущего режима uart_receive();

Код:
char c;
uint8_t flag = 0;
uint8_t Size_data = 12; // например передаём 12 байт

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

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


так правильней. И не закрывай посылку значением данных в передаче. Отучайся от этого.

Страница 1 из 2 Часовой пояс: UTC + 3 часа
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/