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

HAL_UART_IRQHandler的几个bug

[复制链接]
gkcclm 发布时间:2015-5-22 23:01
STM32 HAL  V1.1.2的HAL_UART_IRQHandler似乎有几个bug(完整代码请参见HAL源文件):1. 假设调用UART_Transmit_IT发送,如果此时Rx有多于一个字节的数据过来,那么就会出现Overrun Err,HAL_UART_IRQHandler会被调用,并且进入处理错误的代码中- R  F  l5 E$ J( b6 C5 }+ q
  1.    /* UART Over-Run interrupt occured -----------------------------------------*/
    / e& R" a6 v* r
  2.   if((__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET))
    ( ~8 F! G% M. P
  3.   {
    ) l4 n' H  d/ H/ ~  `, U0 ?
  4.     __HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);
    2 n5 Z! }1 `3 v3 ]" l" b
  5.    
    % J8 f/ ]0 W1 m$ o
  6.     huart->ErrorCode |= HAL_UART_ERROR_ORE;
    - L. M0 I  Y, s. z/ F7 d3 B; `5 z  r8 E
  7.     /* Set the UART state ready to be able to start again the process */2 X( Y' w) l8 w# g- R
  8.     huart->State = HAL_UART_STATE_READY;5 Z" O* j; P& k2 J& x# g# o
  9.   }
复制代码

/ w! I2 I& W, F8 b4 k8 s9 m, o, x8 `. h  k- b* A0 S& L
这时候State变成了Ready。那么当前字节发送完成后,再次进入HAL_UART_IRQHandler,调用UART_Transmit_IT( I; |7 O' Z: j& e2 e8 P# O9 ~
/ [/ K2 [0 G' ~- Z  A
& y0 m6 r% e  B6 p; t. X$ E
  1.   /* UART in mode Transmitter ------------------------------------------------*/
    9 F$ I/ S: N7 e$ |# M8 `
  2.   if((__HAL_UART_GET_IT(huart, UART_IT_TXE) != RESET) &&(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE) != RESET))9 k  z) Q* @. T: Y* {
  3.   {
    0 ^& W- f& h; T' B' _6 b
  4.     UART_Transmit_IT(huart);  q! R3 t# O/ X/ G9 U( H
  5.   }
复制代码
UART_Transmit_IT先检查State是否为Tx或者RxTx。由于这时候State是Ready,所以直接返回Busy。退出IRQ。由于TXE仍然是Set的,所以又进入IRQ,但是又被UART_Transmit_IT返回Busy。导致Tx用于无法完成,并且IRQ一直在运行。
' I/ U. [" w% J* x8 y) l" t4 I8 s' ]" I/ w2 L; e' K& K$ C
2. UART_Receive_IT应该也有问题:
. P. r1 F' R4 o- q
  1. if(--huart->RxXferCount == 0)! l4 T& @5 F' B
  2.     {
    4 W. @. }; ^7 P5 n' C# V
  3.       while(HAL_IS_BIT_SET(huart->Instance->ISR, UART_FLAG_RXNE))        //等待RXNE Clear。如果由于Rx后面立即有数据过来,可能会导致RXNE Set。由于这时候不再读取RDR了,RXNE永远是Set的,就永远死循环在这里了。/ p3 M; {7 m" X$ o+ F- k; h
  4.       {
    7 X6 g" {* f3 g; |  M+ l
  5.       }
    - m6 H9 G9 o6 D; n1 ]" G/ Q
  6.       __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
复制代码
我接触ST才几天,这些问题是我在运行Example中实际遇到的。总体感觉这个HAL库bug很多,特别是UART,非常的不好用(感觉只能当作玩具)。当然,其他部分我没有怎么用,所以不清楚是否有问题。
2 }( X8 h+ Z, o) y6 t' G% O9 x# _3 C% [$ [% ^
不知道大家有没有遇到这些问题。) d" x7 H# Y5 `" ~
( K% r# w6 d# @9 O6 w' l+ d! K

+ L" C$ R5 `8 U% X9 Z) k- {多谢6 ]. D, B; R: n% F$ c) E  t
收藏 2 评论14 发布时间:2015-5-22 23:01

举报

14个回答
waiman 回答时间:2015-5-23 09:07:00
小数据还行。大数据传输还是自己写循环指针好一些
netlhx 回答时间:2015-5-25 09:40:57
要先检测计数器,如果计数器为0才会出现这种情况
captainliuy 回答时间:2015-6-3 17:50:22
串口确实不好用,我最近的工程是使用DMA循环模式接收1字节,回调中写入buffer中
captainliuy 回答时间:2015-6-3 17:52:08
提供的接口是不太好用,但是最近工程用了四个串口也都跑下来了
captainliuy 回答时间:2015-6-3 18:09:17
串口是双工的,可以接收也可以发送,但是处理器处理可不是双工的,发送的时候,如果进来2个以上的数据自然会产生溢出错误,这时候在设为Ready后会调用HAL_UART_ErrorCallback,具体看你自己怎么处理了
wolfgang 回答时间:2015-11-27 16:02:38
最近调试STM32L4的串口,也发现了多多少少的问题。HAL的串口是不怎么好用。要自己改造。
tangxhhh 回答时间:2016-3-17 07:58:38
captainliuy 发表于 2015-6-3 18:09# Q) W' Q3 @: U! r
串口是双工的,可以接收也可以发送,但是处理器处理可不是双工的,发送的时候,如果进来2个以上的数据自然 ...

" e' f9 U0 l4 ]3 r: A  R请问应该怎么处理?
. x4 e3 O3 B" O4 Y7 z8 [* \$ c我刚用STM32不久,急着做一个项目,但是串口经常报OVERRUN错误,不知怎么解决,请赐教!
bfl111 回答时间:2017-2-22 14:52:11
想请前辈指点一下怎么解决的OVERRUN的错误的?
jackten 回答时间:2017-4-25 17:22:44
楼主   在哪里拿到uart接收到的数据?能截个图看看吗
feixiang20 回答时间:2017-5-29 23:36:02
有点难度            
小一兄弟 回答时间:2019-6-24 15:05:53
captainliuy 发表于 2015-6-3 18:09
$ w0 H0 ?! W/ B) N1 L& E串口是双工的,可以接收也可以发送,但是处理器处理可不是双工的,发送的时候,如果进来2个以上的数据自然 ...
- m3 B/ m$ _2 Q
我现在正好遇到超过接收两个以上字节的数据就会出现这个问题,不明白原因,请大侠指教
小一兄弟 回答时间:2019-6-24 15:23:17
captainliuy 发表于 2015-6-3 18:09, ^+ Z; c, C9 O" z- C
串口是双工的,可以接收也可以发送,但是处理器处理可不是双工的,发送的时候,如果进来2个以上的数据自然 ...
% v6 G" R+ Q! o! Z$ u
a.接收到一个数据完成  串口进入中断 将数据从 串口数据寄存器搬运到指定的内存BUF里面,这个步骤需要进入HAL_UART_IRQHandler(&huart2);中完成数据处理。
* q  `! r7 C) j. Kb.进入串口打印数据,串口打印调用的是UART_Transmit_IT(huart); 这个函数也是需要调用HAL_UART_IRQHandler(&huart2);进行数据处理从内存BUF里面帮运到串口发送数据寄存器中间。. \: F+ \1 R" S
c.如果当串口正在进行数据打印的时候进来第二个数的时候就会卡在数据寄存器等待。
2 d1 ]8 r0 F$ n" Ud.但是当串口发送数据完成以后会继续把串口接收数据寄存器的数据接收到内存BUF中间,但是这个过程已经存在串口接收数据溢出中断(overrun溢出中断)。5 w* R4 W8 b7 z2 E& `) r: G- b& F  A

2 F7 E1 }. T( J4 s8 Z6 O+ x- E- C' B. K$ @! p) }
我是这样分析对吗??求指教
Kevin_G 回答时间:2019-6-28 17:48:47
最近做串口,发现HAL库直接用还是挺不好用的。
streamlee 回答时间:2019-7-8 10:54:39
接收用DMA啊

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版