STM32 HAL V1.1.2的HAL_UART_IRQHandler似乎有几个bug(完整代码请参见HAL源文件):1. 假设调用UART_Transmit_IT发送,如果此时Rx有多于一个字节的数据过来,那么就会出现Overrun Err,HAL_UART_IRQHandler会被调用,并且进入处理错误的代码中
% \% J9 x3 K2 A+ ^ q- /* UART Over-Run interrupt occured -----------------------------------------*/, `" r1 O" b) N3 W6 i
- if((__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET))
& D+ b3 W! C+ P9 ^% i z. j - {
9 a7 S. [4 O8 S7 h6 w9 b4 s. ^ - __HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);
( W( {# `' c8 e - / j' d0 `7 K& B- | L9 B
- huart->ErrorCode |= HAL_UART_ERROR_ORE;
6 |4 k" v. U% G8 t/ \ - /* Set the UART state ready to be able to start again the process */
" p- k: g$ |. q- b, k: O0 l - huart->State = HAL_UART_STATE_READY;$ D- p5 P: r+ H. h% g9 y
- }
复制代码 1 O* I! S/ W8 F. _
7 s v8 a! g$ C# P- L
这时候State变成了Ready。那么当前字节发送完成后,再次进入HAL_UART_IRQHandler,调用UART_Transmit_IT! `4 ^, {+ X+ f; q c* n" @
7 F* J. G/ @* h7 m. p
/ w3 j9 J5 c( ]) @. @' @+ J- /* UART in mode Transmitter ------------------------------------------------*/: a) [4 u0 _/ {+ V6 h
- if((__HAL_UART_GET_IT(huart, UART_IT_TXE) != RESET) &&(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE) != RESET))1 P; x% e' d' N: j3 b
- {1 R; v! O; A# `9 C3 U4 `
- UART_Transmit_IT(huart);
! p6 ~* _9 y: c6 d8 Z - }
复制代码 UART_Transmit_IT先检查State是否为Tx或者RxTx。由于这时候State是Ready,所以直接返回Busy。退出IRQ。由于TXE仍然是Set的,所以又进入IRQ,但是又被UART_Transmit_IT返回Busy。导致Tx用于无法完成,并且IRQ一直在运行。$ t# n+ ~6 W c9 h
: t8 C# c c. @ A% p2. UART_Receive_IT应该也有问题:
0 `* j3 S: O' v( s4 T1 |- if(--huart->RxXferCount == 0)
7 l) _4 B# D4 Q' | P) v2 u* ] - {
# g; S! Q5 x5 r) g: _; w - while(HAL_IS_BIT_SET(huart->Instance->ISR, UART_FLAG_RXNE)) //等待RXNE Clear。如果由于Rx后面立即有数据过来,可能会导致RXNE Set。由于这时候不再读取RDR了,RXNE永远是Set的,就永远死循环在这里了。 H: ]7 ~# S/ e( _7 I
- {
6 q$ v" K6 `+ @( E! Z - }8 r: }, J+ H9 ?
- __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
复制代码 我接触ST才几天,这些问题是我在运行Example中实际遇到的。总体感觉这个HAL库bug很多,特别是UART,非常的不好用(感觉只能当作玩具)。当然,其他部分我没有怎么用,所以不清楚是否有问题。
+ g2 I( c8 U) `$ S; T5 [5 Y1 O5 T- l# m
不知道大家有没有遇到这些问题。1 ]* D( z, i2 x$ q$ E, S* _
; m" V( x+ w* h, E9 e
" K( S1 b/ e' \% y/ f
多谢6 J" H8 p. P( A# L: h1 S
|
请问应该怎么处理?
我刚用STM32不久,急着做一个项目,但是串口经常报OVERRUN错误,不知怎么解决,请赐教!
我现在正好遇到超过接收两个以上字节的数据就会出现这个问题,不明白原因,请大侠指教
a.接收到一个数据完成 串口进入中断 将数据从 串口数据寄存器搬运到指定的内存BUF里面,这个步骤需要进入HAL_UART_IRQHandler(&huart2);中完成数据处理。# K7 ]0 g1 I2 G# Y& m6 w P
b.进入串口打印数据,串口打印调用的是UART_Transmit_IT(huart); 这个函数也是需要调用HAL_UART_IRQHandler(&huart2);进行数据处理从内存BUF里面帮运到串口发送数据寄存器中间。 C. U/ `4 I0 R4 t, c6 h# O
c.如果当串口正在进行数据打印的时候进来第二个数的时候就会卡在数据寄存器等待。
d.但是当串口发送数据完成以后会继续把串口接收数据寄存器的数据接收到内存BUF中间,但是这个过程已经存在串口接收数据溢出中断(overrun溢出中断)。: X1 J4 z) d2 z& s( n* w" p( n
o9 K4 B4 E/ i: k. Z8 |2 @
2 @5 G9 R+ \+ c: \& `2 F
我是这样分析对吗??求指教