Перейти к содержанию
    

STM32F0: заморочка с UART

Сколько переюзал юартов на разных линейках STM32 впервые столкнулся с такой заморочкой: принимаю простым поллингом байты по UART. Если следующий байт пришел раньше чем я забрал предыдущий, UART перестает работать - в регистре предпоследний пришедший байт, при всех последующих пришедших байтах соответствующий RXNE флаг не взводится.

 

Говоря простым языком, если принимать байты медленнее, чем они приходят, UART становится глухим.

 

STM32F030x08

 

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

Может у F0 линейки какой то особенный UART?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Он ещё и у F7 и у F3 особенный...

Появившийся флаг overflow или frame error тоже надо снимать. Даже если прерывания по нему не разрешены.

У F4 есть такой эффект (у него другой блок), но там связь между этими флагами не описана в документации. И не каждый раз возникает.

Где-то тут я уже жаловался на найденную аномалию поведения.

 

...
#elif CPUSTYLE_STM32F30X || CPUSTYLE_STM32F0XX || CPUSTYLE_STM32L0XX || CPUSTYLE_STM32F7XX

    void USART1_IRQHandler(void)
    {
        const uint_fast32_t isr = USART1->ISR;

        if (isr & USART_ISR_RXNE)
            cat_parsechar(USART1->RDR);
        if (isr & USART_ISR_ORE)
        {
            USART1->ICR = USART_ICR_ORECF;
            cat_rxoverflow();
        }
        if (isr & USART_ISR_FE)
            USART1->ICR = USART_ICR_FECF;
        if (isr & USART_ISR_TXE)
            cat_sendchar();
    }
#endif

 

И для случия поллинга:

 

...
#elif CPUSTYLE_STM32F30X || CPUSTYLE_STM32F0XX || CPUSTYLE_STM32L0XX || CPUSTYLE_STM32F7XX
    const uint_fast32_t isr = USART1->ISR;
    if (isr & USART_ISR_ORE)
        USART1->ICR = USART_ICR_ORECF;
    if (isr & USART_ISR_FE)
        USART1->ICR = USART_ICR_FECF;
    if ((isr & USART_ISR_RXNE) == 0)
        return 0;
    * cp = USART1->RDR;

#endif

 

Оффтопик:

 

Вот люди с аномалией в F4 возились...

 

https://my.st.com/public/STe2ecommunities/m...rrentviews=1896

 

А вот моё:

 

Продолжаю разбираться.

Получи все-таки ситуацию (Не на единичных байтах).

В статусном регистре (после входа в обработчик) нет установленного бита готовности данных приёмника, но есть бит ошибки ORE. Но это после нескольких килобайт… Перед этим пара правильных срабатываний (и данные и флаг ORE) проходит.

 

Вот так выглядит выдача:

 

$$$$ rxc=61847, ovf=1008, sr=00000008, SR=000000D8, CR1=000020AC, CR2=00000000

$$$$ rxc=351, ovf=1004, sr=00000008, SR=000000D8, CR1=000020AC, CR2=00000000

 

А вот код:

            void USART1_IRQHandler(void)
            {
                        static unsigned long ovf = 0;
                        static unsigned long rxc = 0;
                        const unsigned long sr = USART1->SR;
                        uint_fast8_t f = 0;

                        if (sr & USART_SR_RXNE)
                        {
                                   (void) USART1->DR;
                                   f=1;
                                   ++ rxc;
                        }
                        if (sr & USART_SR_ORE)
                                   ++ ovf;
                        if (sr & USART_SR_TXE)
                        {
                                   USART1->DR = 0x01;
                                   f=1;
                        }

                        if (f == 0)
                        {
                                   static int cnt = 1000;
                                   if (-- cnt == 0)
                                   {
                                               char buff [128];

                                               local_delay_ms(100);    // чтобы успело ещё множество байт прилететь - скорость 115200
                                               local_snprintf_P(
                                                           buff, sizeof buff / sizeof buff [0], 
                                                           PSTR("\n$$$$ rxc=%lu, ovf=%lu, sr=%08lX, SR=%08lX, CR1=%08lX, CR2=%08lX\n"), 
                                                           rxc,
                                                           ovf, 
                                                           sr, 
                                                           USART1->SR, 
                                                           USART1->CR1,
                                                           USART1->CR2
                                                           );

                                               hdbg_puts_impl(buff);
                                               for (;;)
                                                          ;
                                   }
                        }
            }

Функция hdbg_puts_impl просто выводит в тот же порт строчку "посмертного дампа", пользуясь программным опросом готовности.

Изменено пользователем Genadi Zawidowski

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

то есть надо в ожидании флага RXNE так же считывать флаг ошибки и фрейма, иначе, если он возведен - следующий байт не придет пока мы его не сбросим (прочитав его). так?

Изменено пользователем k000858

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну упрощённо говоря так. Кроме того, в F0 эти два флага надо явным образом сбросить через ICR

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну упрощённо говоря так. Кроме того, в F0 эти два флага надо явным образом сбросить через ICR

Спасибо за информацию. Разрешилась моя заморочка.

 

HAL/SPL минус бал за отсутствие обработки такой ситуации.

 

отругал STшников https:/my.st.com/cf00cd8e

 

Если кто то столкнется с таким эффектом (аномалией, багом или особенностью - называйте как хотите) при использовании HAL, решение простое: перед вызовом блокирующей функции приема байта(ов)

HAL_UART_Receive(&UartHandle, &byte, 1, 1000)

, вызывать макрос

__HAL_UART_CLEAR_OREFLAG(&UartHandle);

для сброса флага overrun'а.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В F4 есть аномалия (и в STM32F429 и в STM32F446). В F7 поведение документировано (а кубом/hal не пользуюсь).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В F4 есть аномалия (и в STM32F429 и в STM32F446). В F7 поведение документировано (а кубом/hal не пользуюсь).

Еще раз благодарю за решение. Так бы долго еще просидел.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Минус в огород Хала/Hal . На STM32F2xx - те же грабли. Только при испытаниях HAL на электрические помехи на линии UART обнаружилось некорректная обработка условий LOW NOISE, STOP BIT. В общем долго рассказывать не надо удалили весь мусор, а его там 100 %.

 

Что делает ХАЛ , что можно было не делать или сделать лучше:

 

1. Включает лишние прерывания по ошибкам (LN , FE) и "индусы" запутались с обработкой этих битов. В итоге - не выходит с прерываний вообще.

2. Включает лишний код по обработке четности, когда не заказывали вообще.

3. И что незачем читать постоянно регистр SR , так как он влияет на аппаратный механизм сброса большинства условий.

4. "Индусы" не понимают что значит сократить код.

 

HAL_UART_Receive(&UartHandle, &byte, 1, 1000), вызывать макрос

Код

__HAL_UART_CLEAR_OREFLAG(&UartHandle); для сброса флага overrun'а.

 

Это помогает лишь в некоторых случаях.

 

Смысла чинить ХАЛ - НЕТ !!!

Изменено пользователем картошка

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...