|
问题及解决方法 当STM32使用HAL库进行开发时,偶尔会遇到串口收发数据量大时,会出现问题。比如同时串口同时收发,一段时间后就只能发送,接收不工作。或是只接收,但数据量大时也不工作。下面对这些问题和其解决办法进行整理。
' Z- I; m+ T8 m- ~. n9 @ 问题1:串口溢出当数据量过大且传输频率快时,串口可能会因为溢出,而不进入串口中断。
( {3 O' H5 D9 x% @; h 解决方法使能RXNE中断和ORE中断: - if(HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer,RXBUFFERSIZE)!-HAL_OK)
- X1 _0 F8 V# o' I& D* ~ - {1 B* M5 Z: d- j8 G( N
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_ERR);
" O; G5 E0 d. Q - }
复制代码
4 y% B) n9 p" ]在usart.c中加入串口错误中断回调函数的定义 - /* 中断错误处理函数,在此处理overrun错误 */6 P: e. U" ]$ U* p8 C
- void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
: d; v& I7 E& `+ I% x1 L - {- U( Q- }8 e; s
- uint8_t i = 0;
6 ]" v* j5 V4 Q% }# F- N: W
: x% x7 `+ @5 d) C0 v- if(__HAL_UART_GET_FLAG(huart,UART_FLAG_ORE) != RESET) + b0 R' l' k% \+ l9 O( ]$ S% q& |
- {
o2 ~( N$ j( A7 M: C6 \( R# o) K - __HAL_UART_CLEAR_OREFLAG(huart);
5 |' F' B$ y* Z0 A3 u. \, Q - HAL_UART_Receive_IT(huart,(u8 *)&i,1);% v. [ |5 [ w& L- }. ~+ H+ I
- }
, E& J! |6 B V2 s' I* e; i - }
复制代码. M* T- J) V# M" v
问题2:串口同时收发,一段时间后串口接收不工作 明明STM32的串口通信是全双工的,但使用HAL库的STM32串口收发时发现,数据量大时,同时收发会出现问题。' T+ P+ f* U3 y+ `, y
问题的原因锁定在, STM32 HAL库在处理接收的时候会锁一下串口一会,导致变成某个短时间的“半双工”,这个时候如果同时收发就会出现问题。 在HAL_UART_Receive_IT函数中,开始处进行了上锁
2 ]4 _4 A: s. j& L" D, k3 q/ u! T7 u
8 {" d L0 N! i% W( O
虽然最后在UART_Start_Receive_IT中进行了解锁,
. T2 z7 b- t9 G# R
) z* a2 d- x! V0 H但有多种情况会导致不能解锁,从而影响到了串口接收。
! c4 l. |% L( o3 {' L* _在使用HAL_UART_Transmit时,可以看到,此函数的源码中,也有上锁和解锁,而且还是和UART_Start_Receive_IT控制的是一个锁!!!好好的全双工被HAL库搞成了半双工。
% k3 P8 c" }& i- n6 E2 v7 p4 A 解决办法手动解锁 - return_state=HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer,RXBUFFERSIZE);
( P& f* r. ?, N, W. S0 ^, a) b% f, j - if(return_state!=HAL_OK): ?! U" ~7 Y L1 _8 E( F
- {
F/ V5 G4 ]& a, t! F9 u5 T - //解除忙状态(由ORE导致,清零ORE位)
0 ]8 j2 Y6 h) D - if(return_state == HAL_BUSY)7 i. f+ w0 \. z9 ^% O4 z: S
- {
0 B# F3 @/ ]3 w4 N0 W0 Y" |" d - //清除ORE错误" B5 l% B1 b, i" M' ]/ F" x
- // __HAL_UART_CLEAR_OREFLAG(&huart1);//清楚ORE标志位" M/ w+ ~( C% z4 X( A" Y4 b* T
- // huart1.RxState=HAL_UART_STATE_READY;
1 I; G5 |7 s @ - huart1.Lock=HAL_UNLOCKED;
* k! P' L5 a+ x8 p - //重新开始接收1 c7 i0 H. z8 h4 f# @; n
- return_state=HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer,RXBUFFERSIZE);
7 b& }/ e+ {) ]' c0 k, j0 ]6 t - }
8 n! F8 a1 T) Y: S4 M& I f - }
复制代码 ) ^' y% i9 n- M. s
转载自: 物联网知识 如有侵权请联系删除
8 l5 U% D/ L5 C8 m$ c$ a |