Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STR912 и UART FIFO режим
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
SimpleSoft
День добрый.

Контроллер STR912FAW44 захватывает на скорости 460800 bps данные с UART2. Хотелось бы реализовать RX через FIFO.

Кто возился с FIFO: Подскажите, как правильно обслуживать приём данных через FIFO и для каких случаев лучше 1/8, а для каких 1/2?

Спасибо.
MALLOY2
Возьмем следующие варианты приема с UART

1) Прием используя DMA.

При использовании DMA сомнительно что нужно FIFO UART, исключением может составлять только блочная пересылка данных если это поддерживает DMA (не помню есть ли такая фича в STR912), да и от нее сомнительная польза.

2) Прием используя полинг (постоянно опрашивая флаг) этот метод имеет эфективность только в программах с использованием OS(сомнительно) или в программах которые только UARTом и занимаются. В данном варианте не имеет смысла задавать пороги FIFO т.к. этот порог только устанавливает запрос на ISR.
Это самый простой метод, и в тоже время самый не эффективный есть возможность потерять данные если программа чем то долго была занята и не опрашивала FIFO. UART относительно медленный интерфейс и тратить на него ресурс производительности на постоянное опрашивание FIFO иногда расточительно. Чтение с блокировкой, тобиш когда мы ждем какое-то количество данных имет место только в OS.

Алгоритм:
Код
while (!(UART->FR & FLAG_RXFE)))  //крутимся пока RX FIFO не станет пустым
        {
            buffer = UART->DATA;       //читаем в какойто буфер данные с FIFO
         };


Это примитивный кусок кода, надо еще учитывать ошибки приема, переполнение FIFO, управление принимающим буфером и т.д.

3) Прием используя прерывания, на мой взгляд наиболее эффективный метод как в приложениях с OS так и без нее, исключением является метод с использованием DMA (особенно когда идут потоковые данные без останова, для приложений типа консоль не слишком эфективно использование DMA). Смысл этого метода заключается в следующем, разрешаем прерывания по срабатыванию тригера FIFO и обезательно по TIMEOUT (примечание: в мануалах на разные процы TIMEOUT по разному называют, timeout, idle, может еще как.... нажо читать мануал). Выбираем режим срабатывания тригера как можно выше, чтобы как можно меньше дергал проц прерыванием, для STR912 выставляем уровень 7/8 (тригер срабатывает когда в FIFO больше или равно 11 символов). При срабатывании прерывания переписываем содержимое FIFO в более большой программный буфер, так же здесь делается управление программным буфером, контроль ошибок если это надо, синхронизация евенты и т.д.

Примерчик простенького куска обработчика прерывания для STR912

Код
if ((UART->MIS & MASK_RX_TRX))       //прием RX и TIMEOUT (0x50)
    {
      while (!(UART->FR & FLAG_RXFE))  // FLAG_RXFE == (1<<4), крутимся пока в FIFO UART есть данные
        {
          tmp = UART->DATA;               //считываем 16 бит данные с FIFO
          last_err |= (tmp >>8) & 0x0F;  //маска на биты ошибок, сохраняем состояние битов ошибок принятого символа
          data = (u8_t)tmp & 0xff;          //маска на данные
          if (++rx_size >= rx_buff_size)  //проверка места в буфере
            {
               last_err |= ....;  //Ошибка, переполнение программного буфера
            }
          else
            {
                  rx_buff[rx_wr_ptr] = data; //записи в буффер
                  if (++>rx_wr_ptr >= rx_buff_size)  rx_wr_ptr = 0; //организация кольца
            };    
        }
      UART->ICR = MASK_CLR_RX_TRX;  //очиистить прерывание
    };


По поводу порога срабатывания опускать его имеет смысл если прерывания на долгое время отключаются что вызsвает переполнение FIFO UART, но это уже неправельное построение программы.....

Ну вроде вкратце рассказал .....
SimpleSoft
Спасибо за подробный ответ. Буду реализовывать - скорее всего появятся ещё вопросы по ходу реализации.
P.S.: Для UART2 нет возможности пользовать DMA, насколько я помню.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.