Он ещё и у 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