请选择 进入手机版 | 继续访问电脑版

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

STM32 UART中断接收,每次都出现overun错误

[复制链接]
watershade 提问时间:2021-6-11 21:48 / 未解决
现在使用的STM32G031开发程序。对方设备是收发一体的UART(半双工),我是发完之后立刻切换到中断接收模式。数据量不大,但是每次都有overrun错误。不清楚到底是什么原因导致的。
(最初其实是不知道overrun错误的。只是单纯的收不到任何数据。单很奇怪的是每次用逻辑分析仪能看到STM32的RX引脚应当收到的信息,但是UART却一直收不到信息。后来添加了HAL_UART_ErrorCallback的代码,才发现是ORE错误(overrun).)

按照参考手册的信息,overrun错误的原因如下:
  1. An overrun error occurs if a character is received and RXNE has not been reset.
  2. Data can not be transferred from the shift register to the RDR register until the RXNE
  3. bit is cleared. The RXN E flag is set after every byte reception.
  4. An overrun error occurs if RXNE flag is set when the next data is received or the
  5. previous DMA request has not been serviced. When an overrun error occurs:
复制代码
大概意思是处理的速度没有接收到的快。



这种情况应当怎么分析呐?我的分析是:1、我的接收buffer太小?实际我应当接收到8个数据。单不排除因为其它原因导致的数据量增加。 2、我的处理速度不够。我使用的是HAL库的Receive函数,除非这个有bug? 3、因为收发通过1K电阻连在一起。发的数据被收到,长度太长。其实我已经在软件避免了类似情况。
关于第一个猜测,已经排除。因为如果buffer不够大。我的buffer开头起码保存了一部分数据吧。实际上没有数据。
关于第二个,我的波特率才115200,不至于来不及处理吧。波特率降到9600也一样的问题。
所以真的不知道是什么原因。以及怎么解决

大神们,怎么看?
看起来我需要用DMA了?

收藏 评论6 发布时间:2021-6-11 21:48

举报

6个回答
watershade 回答时间:2021-6-13 14:38:44
已经解决。说实话,不知道之前错误出现的原因。只知道现在解决了。
之前的做法是采用定长接收,出现了overrun错误。至于其它一堆因为解决这个问题添加的代码引起其它错误就暂时不追踪了。
现在采用DMA+IDle line的方式解决了问题。因为之前rx和tx的电阻在设计的时候搞反了,需要做一下swap竟然也通过了。之前的定长是8byte,现在发现一次接收的是4+8byte。因为发送的4个字节和返回的8个字节连在了一起发送。
anyway,解决了就好。这个小问题竟然搞了我几天。人一旦傲慢就处处碰壁
xmshao 回答时间:2021-6-15 11:31:11
更倾向怀疑你接收处理方面的问题,即处理接受数据不及时,新的数据来了RXNE还未被清零。你可以尝试将波特率放慢点做验证或考虑使用DMA接收。接收代码你可以尽量做些精简。
watershade 回答时间:2021-6-15 16:40:46
xmshao 发表于 2021-6-15 11:31
更倾向怀疑你接收处理方面的问题,即处理接受数据不及时,新的数据来了RXNE还未被清零。你可以尝试将波特率 ...

确实是这样的。这次通讯对象是TMC2209,这款芯片的UART是单线的。收发切换之间可以设置至多15个byte的间隔,最少3个byte的间隔.(如果没记错的话)
实际测试(用HAL库)发现,即便是发送完成之后(blocking模式),切换到接收(blocking)模式。也来不及。

~~~~~~~~~~~~~~~
上面的说法可能有点笼统。假定那款芯片设置位3个8-bit的间隔。因为是单线模式,自己发送给TMC2209的,其实也被RX监听了。如果是idle-line开启的话,其实会发现自己Tx发送的和TMC2209回应的,被认为是连续的。(这个可以理解,好像是多少位内都可以被认为是连续的。)
~~~~~~~~~~~~~~~
假定芯片设置为15个8-bit间隔(115200下算一下估计不到),大概1ms~2ms的时间间隔。如果用blocking的方式发送,然后立刻切换接收。发现大概率是不能正常接收的,64Mhz的运行速率下。我想1ms怎么也够切换了。uart单线确实有点难搞,其实我也用半双工单线试过。也没成功,只是测试的不够深入。(不能肯定,主要是这个问题耽误一点时间。需要往前赶工,回头再确认一下到底是什么情况。)
~~~~~~~~~~~~~~~
目前采用的是DMA方式+idle line实现的。此时如果将TMC2209的收发间隔搞大一点,stm32发送的和TMC2209回应的就分开了。这时候ISR处理部分要做的足够简洁(不能用printf之类的占用时间的函数),否则也会出问题。
yklstudent 回答时间:2021-6-18 15:21:03
检查自己的代码写的是不是有问题

watershade 回答时间:2021-6-23 14:29:21
yklstudent 发表于 2021-6-18 15:21
检查自己的代码写的是不是有问题

朋友,你说了不是白说

269587732 回答时间:2021-10-29 23:57:49
请问后来是怎么解决的,我一直不定长的dma接收,在overrun错误。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版