你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32开发项目:处理串口溢出中断(ORE)

[复制链接]
STMCU小助手 发布时间:2022-4-15 10:00
问题表现
7 C" t9 t  }# j2 N+ x& z' X在MCU系统负载较重、串口收发数据频率很高、多个中断存在(如同时有定时器更新中断、外部中断、DMA中断、串口接收中断)的情况下,容易出现串口溢出错误(ORE)。该错误的主要显现形式是:程序莫名卡死在串口中断之中(单片机失去响应)。: d% N1 U; W  A, k  S) g
0 H+ {5 }/ x$ A3 d, `% W
解决方法
5 t& N* |2 m: I2 \- |3 AORE标志位在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位。
4 Y) D$ i: [/ ]" |8 \+ a6 [) D3 Z' B+ F. T* y
/**. T& }. C$ H9 T, m
  * @brief  Checks whether the specified USART flag is set or not.
! `3 R' p$ ~, Y+ e% T  * @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:
8 Y  l0 c0 F* C  *   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
9 o- T8 J5 D0 g- L9 r  *     @arg USART_FLAG_NE:   Noise Error flag
2 I" B. z1 B* \- h* C. P& M  *     @arg USART_FLAG_FE:   Framing Error flag
( c1 P, r" S- m; o: V0 m  *     @arg USART_FLAG_PE:   Parity Error flag
$ G) j* P* y( ]  * @retval The new state of USART_FLAG (SET or RESET).
# Y) a+ j- r0 b  */" ?1 |$ V+ d( J( N1 Q6 b7 e5 g
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
; L2 g1 o; G3 q$ L0 o{
1 X' {( T# _+ E" Y0 e/ Q  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));
4 c7 t5 Q/ ^% m. p* `+ L6 N  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
  {
& a* S8 w/ j4 g& d* N/ V: j    assert_param(IS_USART_123_PERIPH(USARTx));
( }8 r' L0 Z2 p" l  s5 }$ f, k  }  
+ y- a1 r- }# @0 T9 Y, ~# e  s- V( \9 U* {# H5 ~2 m- c% ~
  if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET)' g1 y, |' W* ]0 I9 Q( _' W
  {
( g0 z6 O* L- F  B: O; \    bitstatus = SET;5 @0 L: K7 f" ^$ M1 P! s
  }
3 a; A. x' E' l& H; F; ]+ Y9 P# U  else
+ ~* J0 ~7 v; X+ S  {
& u% J6 l2 L+ H    bitstatus = RESET;
; u$ n7 p1 o7 k! H4 j( k  }
' u# M+ J1 v1 y" T6 X( F$ I  return bitstatus;
3 C8 y( w+ O; Q. C  W% P4 O9 [}2 F# j3 N! R1 [+ g6 h6 q+ C/ D* \

  o5 w% A7 U! I4 p+ 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.
, n+ O+ M9 A; a- `; a/ p  *   This parameter can be one of the following values:8 h- V5 A6 ~& i1 F' ^. b" x
  *   USART1, USART2, USART3, UART4 or UART5.
5 u; s3 ]6 R2 c5 @& }; c  * @retval The received data.
. W/ s  K% L9 B/ i  */
. y" n3 O  P* C0 ]uint16_t USART_ReceiveByte(USART_TypeDef* USARTx)( D! |5 |& J/ s( @/ B
{* A3 a  e1 \7 d: R! C
  /* Check the parameters */
6 I& e2 J" m" q8 x4 y  assert_param(IS_USART_ALL_PERIPH(USARTx));
1 i5 L8 U7 O: Z$ y. W; G5 w3 q; j* c0 N1 }& E
  /* Receive Data */
. C" L8 h/ i5 Y) y+ g  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

9 `: o8 |. O# |/ }  R" {% I- f+ ~; v! D

: k% P* E+ f# q3 M1 Jvoid USART1_IRQHandler(void)
$ k8 {% i' ?& q' z8 P8 g! [1 t/ H{
- y  g' \5 V/ K# v        /**5 m: y" e4 R! {+ m  N
         * 如果使能串口接收中断,那么ORE为1时也会产生中断。8 d0 P# a) u8 T6 N- B
         * 在应用中对ORE标志进行处理,当判断发生ORE中断的时候,
: N& o7 T4 [! k% k# A- ?         * 我们再读一次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
         */
7 |* E/ X) o3 c0 _: G4 G         ) 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)
) W, F! \% p5 P, c# b        {& 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);
9 w- t5 }  [# M; Q* X8 g               
8 e1 F$ N& R. X- n                //USART_ClearFlag(USART1, USART_FLAG_ORE);
+ ?' B0 M, W( B! w" g        }* e" N3 w9 ~- n* @
        ) D2 O- o- a5 h- f3 V
        //处理接收到的数据(示例为FIFO缓冲队列)
0 y& i: I6 }" T  h        if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
& e) Q, J2 ^" ?) b9 J$ f        {0 B" A1 \( E* Q' K* k* m6 t
                USART_ClearITPendingBit(USART1, USART_IT_RXNE);
' O9 c6 C1 }  q$ x                *USART_RevPointer[0][0] = (u8) USART_ReceiveByte(USART1);1 H+ Z. }$ b0 Q
                USART_RevPointer[0][0]++;
% U1 @: ~" D7 p0 n" ^                USART_RevCount[0]++;
3 q& z- [* B7 M1 [; Q% y4 f2 r& h" 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];
0 e+ X4 V# e0 u1 d- D* _2 l: B        }
9 j$ L0 s: C! d0 h# q- H}* ?' 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
赞 收藏 评论0 发布时间:2022-4-15 10:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版