搜索
bottom↓
回复: 46

血泪教训,关于STM8单片机串口接收中断

  [复制链接]

出0入213汤圆

发表于 2019-10-17 23:39:33 来自手机 | 显示全部楼层 |阅读模式
STM8单片机接工控屏,有接收中断和发送中断,带步进电机,每个脉冲产生一个中断,以及各种外部中断,内部定时器中断。

设计基本完成。在步进电机运转时,遇到一个无规律的重启(看门狗溢出复位)。关闭看门狗,故障为无规律的类似代码跑飞或死机现象。

先检查代码,没发现问题,怪自己还too young,指责客户的供电,安装,电磁干扰等原因造成,让客户仔细排查,又让客户搭一个小型测试模型,已去干扰。

然后,在模型中测试,依然无规律复位重启!
确定不是单片机受干扰引起了。然后回到代码上分析。

预估为反复进入某中断。因为程序的中断太多,不宜设置断点分析,只好定义一个256字节数组,记录最近256次进入了那些中断。每进一个中断,记录一下。
结果定位在串口接收中断,反复进入,阻塞了其它中断和代码运行。
根据串口状态,查出过载错误置位,这个也会进入接收中断。

教训:在接收中断里面,不但要清除接收到数据标志位,还要清除其它引起这个中断的其它标志位!

大家使用STM8和STM32的串口的,引以为鉴。

阿莫论坛20周年了!感谢大家的支持与爱护!!

阿莫论坛才是最爱国的,关心国家的经济、社会的发展、担心国家被别国牵连卷入战争、知道珍惜来之不易的和平发展,知道师夷之长,关注世界的先进文化与技术,也探讨中国文化的博大精深,也懂得警惕民粹主义的祸国殃民等等等等,无不是爱国忧民的表现。(坛友:tianxian)

出0入36汤圆

发表于 2019-10-18 00:04:25 来自手机 | 显示全部楼层
过载错误置位是什么鬼?

出0入213汤圆

 楼主| 发表于 2019-10-18 00:27:40 来自手机 | 显示全部楼层
redworlf007 发表于 2019-10-18 00:04
过载错误置位是什么鬼?

过载错误,也许是上一个数据来不及接收,有来了一个新数据。也有可能是发送数据过程中遇到接收数据,二者冲突。 总之,这个过载错误也是会进串口接收中断的。清除这个标志需按手册的操作顺序来。

可被这个害苦了,大家引以为鉴。

出0入0汤圆

发表于 2019-10-18 06:30:55 来自手机 | 显示全部楼层
经验就是踩过无数坑积累来的

出100入0汤圆

发表于 2019-10-18 07:29:46 | 显示全部楼层
jyrpxj 发表于 2019-10-18 00:27
过载错误,也许是上一个数据来不及接收,有来了一个新数据。也有可能是发送数据过程中遇到接收数据,二者 ...

中断里做的事太多了吧?

出0入0汤圆

发表于 2019-10-18 07:30:47 来自手机 | 显示全部楼层
收藏备用

出0入0汤圆

发表于 2019-10-18 07:54:28 来自手机 | 显示全部楼层
不是读完状态就读数据就清空吗

出10入0汤圆

发表于 2019-10-18 08:14:55 | 显示全部楼层
为何搞那么多中断呢?

出0入0汤圆

发表于 2019-10-18 08:26:21 | 显示全部楼层
中断太多会影响其他任务的执行

出0入0汤圆

发表于 2019-10-18 08:30:59 | 显示全部楼层
昨天也遇到了个too young的bug,恨死了

出0入0汤圆

发表于 2019-10-18 08:31:27 | 显示全部楼层
OVR标志,应该叫溢出。

出0入0汤圆

发表于 2019-10-18 08:43:01 | 显示全部楼层
你的串口数据接收是无规律的?为啥会出现溢出?

出0入4汤圆

发表于 2019-10-18 08:43:43 | 显示全部楼层
遇到过类似的情况,最保险的做法是,在中断里判断对自己有用的中断标志处理,然后清空所有中断标志位

出0入0汤圆

发表于 2019-10-18 09:30:08 | 显示全部楼层
串口中断清除所有是必须,不过你这个应该是中断阻塞,导致串口下一个字节没有读取而被覆盖,如果是9600波特率,也就是相当于随机有大于1.04ms的阻塞,,,
需要优化调整代码结构,不然也会出现命令丢失的情况,一般这种中情况debug打断点时经常出现

出0入0汤圆

发表于 2019-10-18 09:36:56 | 显示全部楼层
越是底层的坑,越坑人

出0入0汤圆

发表于 2019-10-18 09:48:16 | 显示全部楼层
是的。允许中断的标志位,都要处理。

出0入0汤圆

发表于 2019-10-18 09:51:52 | 显示全部楼层
way2888 发表于 2019-10-18 07:54
不是读完状态就读数据就清空吗

+10086

出0入0汤圆

发表于 2019-10-18 11:11:27 | 显示全部楼层
也可能通讯逻辑没有处理好,

出0入34汤圆

发表于 2019-10-18 11:38:10 | 显示全部楼层
血泪教训?我还以为发生 Bug 因而出人命了都!呵呵~

出0入4汤圆

发表于 2019-10-18 11:40:02 | 显示全部楼层
很多年前从51转到PIC时就遇到过类似问题,只要故意短路PIC的串口RX,或者用金属故障碰触RX引脚模拟脉冲干扰,程序就会跑飞了一样,死机了。最后查出来是帧格式错误标志位置位了,应该是人为故意短路,造成没有合法的停止位,产生了错误标志,而接收中断里没有处理这种标志,造成不停的中断。后来不管用什么平台的单片机,接收中断里都会加上对这些错误标志位的处理。所以有些坑还是要踩完才能成长。

出0入0汤圆

发表于 2019-10-18 12:46:44 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2019-10-18 13:06:31 | 显示全部楼层
stm32这坑我也踩过,开启接收中断时溢出中断就被开启了,而且你并不能关掉溢出中断,它是和接收中断绑定到一起的。数据溢出时进中断如果只清除了发送和接收中断,就会在中断里面出不来。

出0入4汤圆

发表于 2019-10-18 13:52:00 | 显示全部楼层
这个仿真时应该很容易发现吧

出0入0汤圆

发表于 2019-10-18 15:45:16 | 显示全部楼层
吓得我赶紧把这段给加上了!虽然目前没爆出问题!

出1325入193汤圆

发表于 2019-10-18 15:46:12 | 显示全部楼层
xymxym 发表于 2019-10-18 11:40
很多年前从51转到PIC时就遇到过类似问题,只要故意短路PIC的串口RX,或者用金属故障碰触RX引脚模拟脉冲干扰 ...

这个坑 估计需要三五天才能爬出来 话说 一个大牛电工的青葱岁月大都是在坑里度过的呢

出0入0汤圆

发表于 2019-10-18 15:47:39 | 显示全部楼层
过载 噪声 什么的BIT在进入HAL处理前都要清

出0入0汤圆

发表于 2019-10-18 16:16:16 | 显示全部楼层
lingdianhao 发表于 2019-10-18 13:06
stm32这坑我也踩过,开启接收中断时溢出中断就被开启了,而且你并不能关掉溢出中断,它是和接收中断绑定到 ...

哈哈哈哈哈 我还以为就只有我遇到过呢

出0入0汤圆

发表于 2019-10-18 16:29:58 | 显示全部楼层
还是喜欢51的串口,简单可靠,不容易出BUG

出0入4汤圆

发表于 2019-10-18 16:30:26 | 显示全部楼层
lb0857 发表于 2019-10-18 15:46
这个坑 估计需要三五天才能爬出来 话说 一个大牛电工的青葱岁月大都是在坑里度过的呢 ...

是啊,关键对老电工来说,往往是一坑还比一坑深

出0入76汤圆

发表于 2019-10-18 21:05:19 | 显示全部楼层
呵呵, 比如串口这类的中断,我的做法是“ 直接使用寄存器操作 ” (又快又方便), 先把中断状态寄存器SR全部标志读取后, 然后直接把所有中断标志清掉, 然后再来判断发生了哪些中断,做相应处理。

不过你说的是 “过载错误置位”问题, 估计应该你的中断程序处理时间太长了吧(当然不光是指串口的中断处理程序, 还有其它比它优先级高的中断程序)

出0入4汤圆

发表于 2019-10-18 21:18:58 | 显示全部楼层
本帖最后由 xiepan2010 于 2019-10-18 21:24 编辑

这个问题我也遇到过  不过调试的时候就发现了  也就顺手解决了  
是串口的溢出中断  默认是开启这个的   也没找到怎么用库函数关闭溢出中断   直接用寄存器关掉的



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2019-10-18 21:42:08 | 显示全部楼层
我比较幸运,使用过8和32的串口接收还没有遇到过类似的问题

出5入8汤圆

发表于 2019-10-19 10:45:50 | 显示全部楼层
谢谢 楼主分享经验

出0入0汤圆

发表于 2019-10-19 12:11:47 | 显示全部楼层
遇到过 我的debug过程是吧寄存器值打印出来  然后关键分支点打印

出0入0汤圆

发表于 2019-10-19 13:38:07 | 显示全部楼层
还是没找到好的stm的串口demo,这个问题用多了自然会碰到

出1325入193汤圆

发表于 2019-10-20 22:13:55 | 显示全部楼层
122402902 发表于 2019-10-19 12:11
遇到过 我的debug过程是吧寄存器值打印出来  然后关键分支点打印

这个方法很好  值得学习

出0入0汤圆

发表于 2019-10-22 14:00:33 | 显示全部楼层
谢谢楼上各位分享的宝贵经验,以后仔细检查各种中断的设置,不需要的坚决关闭,出问题时要记录中断标志寄存器

出0入0汤圆

发表于 2019-10-23 11:25:25 | 显示全部楼层
中断处理东西太多,时间过长?

出0入0汤圆

发表于 2019-10-25 19:53:06 | 显示全部楼层
从未有楼主的现象发生过
在接收中断添加如下:
u8 sr= UART3->SR;
u8 dr= UART3->DR;

出0入12汤圆

发表于 2019-10-25 20:46:43 来自手机 | 显示全部楼层
似乎楼主的问题我也遇到过,比如,在stm8开机之前,外部串口一直发送数据。我也是进入串口接收后把所有中断标志都清掉。

出0入0汤圆

发表于 2019-10-26 08:03:15 | 显示全部楼层
遇到过,需要小心处理

出0入0汤圆

发表于 2019-10-26 08:55:53 | 显示全部楼层
出现过载证明有打断时间长的操作。估计本质还是中断函数里写太长了,遇到一堆人都这么干

出0入0汤圆

发表于 2019-11-11 22:35:52 来自手机 | 显示全部楼层
bolizhicheng204 发表于 2019-10-18 08:43
遇到过类似的情况,最保险的做法是,在中断里判断对自己有用的中断标志处理,然后清空所有中断标志位 ...

点赞,也是总结出来的血泪教训,真的可以避过好多坑。

出0入0汤圆

发表于 2019-11-12 08:09:15 | 显示全部楼层
技术员啊享受不了便利,ST设计STM8和STM32UART的时候,只要读取了Data,数据接收完成中断就会被自动清除,可仅仅清除了该中断标志,别的可不会自动清除。

最好的做法
if(Rx_Flg)
{
  Rx_Flg = 0;
  do something...
}
else if(TxC_Flg)
{
  TxC_Flg = 0;
  do something...
}
else
{
  SR_Reg = 0;
}

出0入0汤圆

发表于 2019-11-12 08:14:51 来自手机 | 显示全部楼层
读的太慢了吧

出0入0汤圆

发表于 2019-11-12 09:13:53 | 显示全部楼层
串口过载  我也遇到过这个问题   当时怎么弄都搞不定   找了群里一个高手看了  给我远程搞定了   处理方法 就是 定义一个变量  再读一次串口接收寄存器  但这个变量从来不在别的地方去使用
如下
if (UART2_GetITStatus(UART2_IT_OR))//over run
        {
            ayumi = UART2_ReceiveData8();
        }  

出0入0汤圆

发表于 2019-11-18 22:27:09 | 显示全部楼层
收藏 防备着
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-9-19 16:45

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表