加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

串口跑着跑着又死掉了,是怎么回事?

09/15 11:00
923
阅读需 4 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

串口是MCU最经常使用的外设之一,我遇到过多起串口在使用过程中出现死掉的实际案例。

这种问题在测试阶段如果发现了还好,一旦批量出去在现场发生就更加麻烦了。今天说的死掉,其实真实现象是MCU一直在不停的进串口中断,导致其他代码无法正常执行。

遇到该问题的罪魁祸首是串口Overrun,即溢出所致。Overrun其实很好理解,串口在接收数据的时候,每一字节数据经移位寄存器数据寄存器,所谓溢出就是指,上一个字节的数据在数据寄存器还没有被读取走,新的1字节数据又已经被移入到移位寄存器的现象。以STM32F030为例,其他家的MCU也类似,Overrun错误标志位位于USART_ISR寄存器中。

Overrun现象我们可以这么产生:在串口中断服务函数刚开始处加一个断点,debug全速运行,通过串口调试助手一下发送2个字节的数据,这时就会出现Overrun,原因就是进入到断点处还没有去读数据,但是新的数据又来了。

手册中描述当此标志位置位时,RDR寄存器中的数据没有丢失,我们可以看到RDR内容就是第一个字节0x31。

默认情况下,Overrun检测功能时开启的,USART_CR3寄存器的OVRDIS位可以把该功能关掉。

当把溢出检测功能给关掉,要注意的是新来的数据会覆盖USART_RDR寄存器中的数据。

我们在代码串口初始化中把溢出功能关闭,同样做之前的实验,这时可以看到RDR的值就不是之前的0x31,而是0x32了,ISR里ORE标志位也不会置位了。

出现死掉的问题是因为来了ORE中断,但是中断服务函数没有去处理所致,所以就会一直进中断。

其实解决该问题的方法也非常简单,就是在中断服务函数里加入该标志位的清除操作即可。或者干脆就把溢出功能关闭不使用也行。

MCU里Overrun这个标志本来目的是为了提醒数据传输过程中出错了,接收端需要通知发送端重传。但是实际应用中大家一般也不这么用,为了保证串口数据通信的正确性,一般都会在应用层上加上数据帧的校验,有了校验其实用不用溢出功能也无所谓了。

最后强调一下:如果MCU开启了Overrun功能,一定要在中断服务函数里加入清溢出标志的操作。不加Overrun标志位处理大部分情况下也许不会出问题,但是一旦溢出可就麻烦大了。

相关推荐

电子产业图谱

TopSemic,让芯片使用更简单。 专注分享:嵌入式,单片机,STM32,ARM,RTOS,Linux, 软硬件,半导体,电子技术等相关内容。