STMCU小助手
发布时间:2022-4-15 10:00
|
问题表现 在MCU系统负载较重、串口收发数据频率很高、多个中断存在(如同时有定时器更新中断、外部中断、DMA中断、串口接收中断)的情况下,容易出现串口溢出错误(ORE)。该错误的主要显现形式是:程序莫名卡死在串口中断之中(单片机失去响应)。: d% N1 U; W A, k S) g 0 H+ {5 }/ x$ A3 d, `% W 解决方法 ORE标志位在USART_SR寄存器,当我们打开串口接收中断时,同时也就打开了ORE中断,串口的overload错误会导致程序反复进入串口中断服务程序。在中断服务程序中增加处理overload的处理,顺序执行对USART_SR和USART_DR寄存器的读操作可以复位ORE位,以防止程序反复进入串口中断服务程序。示例代码如下:. p9 A: o. U# L0 Q+ n " ^+ ]4 Z1 p7 m* Y! @ 在STM32中断函数增加USART_IT_ORE等异常中断的处理,执行USART_GetFlagStatus(USART1, USART_FLAG_ORE),会对USART_SR进行了一次读操作,然后再执行USART_ReceiveByte(USART1),会对USART_DR进行一次读操作,从而复位了ORE位。 ) D3 Z' B+ F. T* y /**. T& }. C$ H9 T, m * @brief Checks whether the specified USART flag is set or not. * @param USARTx: Select the USART or the UART peripheral. " U" U2 J" _( j f. f8 h; l * This parameter can be one of the following values: * USART1, USART2, USART3, UART4 or UART5.& n# t% Z5 g+ a, f# J$ K * @param USART_FLAG: specifies the flag to check.6 B0 v, L& T5 I; y3 X * This parameter can be one of the following values:8 Q8 M9 d1 b/ s' T- L* V+ s4 r6 S * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5)- W: s! u: @+ \0 n3 J9 [$ e * @arg USART_FLAG_LBD: LIN Break detection flag* I- e; H, V7 \' [7 ^& U * @arg USART_FLAG_TXE: Transmit data register empty flag: U( n: S% l, N# J) b& E' A * @arg USART_FLAG_TC: Transmission Complete flag# E6 q9 y2 o3 d1 ]8 s * @arg USART_FLAG_RXNE: Receive data register not empty flag% h( y5 ^4 m3 k0 I/ w * @arg USART_FLAG_IDLE: Idle Line detection flag, c9 x) a3 @1 ~ * @arg USART_FLAG_ORE: OverRun Error flag * @arg USART_FLAG_NE: Noise Error flag * @arg USART_FLAG_FE: Framing Error flag * @arg USART_FLAG_PE: Parity Error flag * @retval The new state of USART_FLAG (SET or RESET). */" ?1 |$ V+ d( J( N1 Q6 b7 e5 g FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG) { FlagStatus bitstatus = RESET;# Q# _0 J& x3 d+ n+ y /* Check the parameters */5 K1 h& x# F% A) { assert_param(IS_USART_ALL_PERIPH(USARTx)); assert_param(IS_USART_FLAG(USART_FLAG));# R# [0 Y2 Q* l$ M: i /* The CTS flag is not available for UART4 and UART5 */, l8 s* f: L3 n$ |+ ` if (USART_FLAG == USART_FLAG_CTS), A2 |4 w' p0 g" o { assert_param(IS_USART_123_PERIPH(USARTx)); } s- V( \9 U* {# H5 ~2 m- c% ~ if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET)' g1 y, |' W* ]0 I9 Q( _' W { bitstatus = SET;5 @0 L: K7 f" ^$ M1 P! s } else { bitstatus = RESET; } return bitstatus; }2 F# j3 N! R1 [+ g6 h6 q+ C/ D* \ + k: y" Y& E2 O- C $ x; N7 U' Q4 J! W: L /**% d/ m! s( r. W * @brief Returns the most recent received data by the USARTx peripheral.' Q7 ?# m% x/ S1 U * @param USARTx: Select the USART or the UART peripheral. * This parameter can be one of the following values:8 h- V5 A6 ~& i1 F' ^. b" x * USART1, USART2, USART3, UART4 or UART5. * @retval The received data. */ uint16_t USART_ReceiveByte(USART_TypeDef* USARTx)( D! |5 |& J/ s( @/ B {* A3 a e1 \7 d: R! C /* Check the parameters */ assert_param(IS_USART_ALL_PERIPH(USARTx)); 3 q; j* c0 N1 }& E /* Receive Data */ return (uint16_t)(USARTx->DR & (uint16_t)0x01FF);1 Z( @6 D9 S! k4 f# |2 ~ }, X2 U4 b/ p& [$ J; `9 Z* F% k " {% I- f+ ~; v! D void USART1_IRQHandler(void) { /**5 m: y" e4 R! {+ m N * 如果使能串口接收中断,那么ORE为1时也会产生中断。8 d0 P# a) u8 T6 N- B * 在应用中对ORE标志进行处理,当判断发生ORE中断的时候, * 我们再读一次USART_DR的值, E! {+ D8 l, }8 t: T# k * 这样如果没有新的Overrun 溢出事件发生的时候,ORE会被清除,+ h& X7 D0 E$ n, z * 然后程序就不会因为ORE未被清除而一直不断的进入串口中断# O' w7 b- k9 t# [) O' s! B! T4 u' d */ ) Z9 Z1 R# Y. y6 ^! E4 g7 z0 {6 Z& B //没有使能USART_IT_ERR中断时,ORE中断只能使用USART_GetFlagStatus(USART1, USART_FLAG_ORE)读到, [* H+ A, R. Q0 d, u if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET) {& Y, N t5 C2 G //(void)USARTx->SR;0 y: `# L8 [$ ~% H //(vois)USARTx->DR; //先读SR再读DR寄存器4 n. }$ i- i) ?1 V7 f5 r * G5 Y! @5 s5 `" T3 y# R, r USART_ReceiveByte(USART1); //USART_ClearFlag(USART1, USART_FLAG_ORE); }* e" N3 w9 ~- n* @ ) D2 O- o- a5 h- f3 V //处理接收到的数据(示例为FIFO缓冲队列) if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {0 B" A1 \( E* Q' K* k* m6 t USART_ClearITPendingBit(USART1, USART_IT_RXNE); *USART_RevPointer[0][0] = (u8) USART_ReceiveByte(USART1);1 H+ Z. }$ b0 Q USART_RevPointer[0][0]++; USART_RevCount[0]++; " t4 L+ I$ h7 W+ @! {% u# ~& W if (USART_RevPointer[0][0] >= USART_RevBuffer[0] + USART_BufferSize[0])6 S) w4 D- H' Z. ~. v USART_RevPointer[0][0] = USART_RevBuffer[0]; } }* ?' w" d& q3 X: Z1 Z" ^& g* m / d" l3 _5 F9 O4 e3 j' j9 A 3 D; f* g2 ?3 {$ o' M J8 @& M# o- F* J/ T) C |
【经验分享】STM32语音识别的智能蓝牙音箱(源程序+原理图+PCB+设计说明书+PPT)
想找个ST芯片
[GPIO] 使用新型抽象开始C++嵌入式编程,从GPIO开始
技术手册stm32f1xx中的一个小问题
【经验分享】STM32 HAL库移植FreeModbus详细步骤
【逢7发帖赢大礼】STM32开发之IC门禁卡UID读取方法!
实战经验 | Keil工程使用NEAI库的异常问题
经验分享 | FDCAN数据段波特率增加后发送失败的问题分析
STM32几种流行开发环境的优缺点
好用软件推荐-TouchGFX Designer
微信公众号
手机版