k000858 0 18 марта, 2016 Опубликовано 18 марта, 2016 · Жалоба Сколько переюзал юартов на разных линейках STM32 впервые столкнулся с такой заморочкой: принимаю простым поллингом байты по UART. Если следующий байт пришел раньше чем я забрал предыдущий, UART перестает работать - в регистре предпоследний пришедший байт, при всех последующих пришедших байтах соответствующий RXNE флаг не взводится. Говоря простым языком, если принимать байты медленнее, чем они приходят, UART становится глухим. STM32F030x08 Быть может кто нибудь встречался с таким? Может у F0 линейки какой то особенный UART? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 18 марта, 2016 Опубликовано 18 марта, 2016 (изменено) · Жалоба Он ещё и у 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 просто выводит в тот же порт строчку "посмертного дампа", пользуясь программным опросом готовности. Изменено 18 марта, 2016 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k000858 0 18 марта, 2016 Опубликовано 18 марта, 2016 (изменено) · Жалоба то есть надо в ожидании флага RXNE так же считывать флаг ошибки и фрейма, иначе, если он возведен - следующий байт не придет пока мы его не сбросим (прочитав его). так? Изменено 18 марта, 2016 пользователем k000858 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 18 марта, 2016 Опубликовано 18 марта, 2016 · Жалоба Ну упрощённо говоря так. Кроме того, в F0 эти два флага надо явным образом сбросить через ICR Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k000858 0 18 марта, 2016 Опубликовано 18 марта, 2016 · Жалоба Ну упрощённо говоря так. Кроме того, в F0 эти два флага надо явным образом сбросить через ICR Спасибо за информацию. Разрешилась моя заморочка. HAL/SPL минус бал за отсутствие обработки такой ситуации. отругал STшников https:/my.st.com/cf00cd8e Если кто то столкнется с таким эффектом (аномалией, багом или особенностью - называйте как хотите) при использовании HAL, решение простое: перед вызовом блокирующей функции приема байта(ов) HAL_UART_Receive(&UartHandle, &byte, 1, 1000) , вызывать макрос __HAL_UART_CLEAR_OREFLAG(&UartHandle); для сброса флага overrun'а. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 18 марта, 2016 Опубликовано 18 марта, 2016 · Жалоба В F4 есть аномалия (и в STM32F429 и в STM32F446). В F7 поведение документировано (а кубом/hal не пользуюсь). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k000858 0 18 марта, 2016 Опубликовано 18 марта, 2016 · Жалоба В F4 есть аномалия (и в STM32F429 и в STM32F446). В F7 поведение документировано (а кубом/hal не пользуюсь). Еще раз благодарю за решение. Так бы долго еще просидел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Hiehachi 0 8 апреля, 2016 Опубликовано 8 апреля, 2016 (изменено) · Жалоба Минус в огород Хала/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'а. Это помогает лишь в некоторых случаях. Смысла чинить ХАЛ - НЕТ !!! Изменено 8 апреля, 2016 пользователем картошка Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться