реклама на сайте
подробности

 
 
> STM32F0: заморочка с UART
k000858
сообщение Mar 18 2016, 05:12
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 31-01-12
Пользователь №: 69 978



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

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

STM32F030x08

Быть может кто нибудь встречался с таким?
Может у F0 линейки какой то особенный UART?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Genadi Zawidowsk...
сообщение Mar 18 2016, 06:07
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Он ещё и у 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 - Mar 18 2016, 06:13
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 31st July 2025 - 13:32
Рейтинг@Mail.ru


Страница сгенерированна за 0.01396 секунд с 7
ELECTRONIX ©2004-2016