Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F0: заморочка с UART
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
k000858
Сколько переюзал юартов на разных линейках STM32 впервые столкнулся с такой заморочкой: принимаю простым поллингом байты по UART. Если следующий байт пришел раньше чем я забрал предыдущий, UART перестает работать - в регистре предпоследний пришедший байт, при всех последующих пришедших байтах соответствующий RXNE флаг не взводится.

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

STM32F030x08

Быть может кто нибудь встречался с таким?
Может у F0 линейки какой то особенный UART?
Genadi Zawidowski
Он ещё и у 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 просто выводит в тот же порт строчку "посмертного дампа", пользуясь программным опросом готовности.
k000858
то есть надо в ожидании флага RXNE так же считывать флаг ошибки и фрейма, иначе, если он возведен - следующий байт не придет пока мы его не сбросим (прочитав его). так?
Genadi Zawidowski
Ну упрощённо говоря так. Кроме того, в F0 эти два флага надо явным образом сбросить через ICR
k000858
Цитата(Genadi Zawidowski @ Mar 18 2016, 10:22) *
Ну упрощённо говоря так. Кроме того, в F0 эти два флага надо явным образом сбросить через ICR

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

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

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

Если кто то столкнется с таким эффектом (аномалией, багом или особенностью - называйте как хотите) при использовании HAL, решение простое: перед вызовом блокирующей функции приема байта(ов)
Код
HAL_UART_Receive(&UartHandle, &byte, 1, 1000)
, вызывать макрос
Код
__HAL_UART_CLEAR_OREFLAG(&UartHandle);
для сброса флага overrun'а.
Genadi Zawidowski
В F4 есть аномалия (и в STM32F429 и в STM32F446). В F7 поведение документировано (а кубом/hal не пользуюсь).
k000858
Цитата(Genadi Zawidowski @ Mar 18 2016, 12:16) *
В 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'а.


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

Смысла чинить ХАЛ - НЕТ !!!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.