先说结论
使用51单片机,用interrupt定义中断服务函数时,没有注意到之前有定义过相同的中断服务函数,但是编译通过,导致每次进入另一个中断,将RI(接收完成标志位)清除
问题描述
使用串口让MS51和PY32两板进行通信,MS51向PY32发送数据可以正常接收,但是PY32向MS51发送数据却不能正常接收
原因分析:
首先排除串口配置问题,因为单边通信是可以的,所以就将问题定位到了MS51的串口接收,
通过观察MS51的SBUF(发送接收数据寄存器)和RB8(接收数据第九位)发现可以正常收到数据。
随后查看数据手册发现有一个多主机通信模式,可能会导致RI不被置位,下图是RI被置位的必要条件
后续查看寄存器,SM2 = 0,所以不影响,然后查看串口信号,发现起始位,数据位,停止位都是正常的。
这里就十分奇怪了,串口配置没有问题,接收数据也正常,就是不置位RI。一度怀疑是硬件问题。后来无意中想起编译器报的警告。
意思就是0x000078这块地址有变量重叠。后面才知道是两个中断服务函数使用的同一中断入口,就是0x000078(串口0中断服务函数入口)定义了两个中断服务函数。至于为什么RI看起来没有被置位,其实就是置位后就立即进入另一个中断服务函数,然后将RI清零,造成了没有被置位的假象。
解决方案:
知道问题就好解决了,找到了工程中一个其他地方定义的中断服务函数。然后删掉。
这里建议把一个工程中的所有中断服务函数写到同一个.c文件中,需要在其他文件中实现的功能使用回调函数。不要到处拉屎!