485通信乱码/延时问题
好久没写单片机相关的内容了,这两天由于之前项目的关系,重新温习了一遍485通信。
首先是基础概念,485通信采用差分信号控制,比232通信强在距离远,抗干扰能力强,可带设备更多。大多数情况下都是用普通串口接一个MAX485或者3485芯片进行不同协议的切换。芯片除了发送和接受数据引脚还有一根控制脚。控制脚为0时为接收状态,反之发送。对于STC8芯片来说,引脚默认的双向口模式即可正常工作。
我们的项目目前是采用一拖六的485通信。一块主板控制六块控制板。主板发送信息,控制板接收到后,定时回复心跳包。方式都是485通信。
遇到的问题是:485线路上常常会产生乱码,发送FF,FE,F3等字节。
开始阶段,老师觉得可能是485线路上有干扰的问题。将对称电阻焊上去之后没有改善。后来我想是不是串口中断里面读写EEPROM的时间太长,导致中断没有快进快出造成错误。在改写程序后发现还是没效果。
最后在网上找了很久,发现有人提出过485通信的发送和接收状态切换时要加延时。我觉得是在理,程序判断数据是否发送完是靠芯片uart的TI位,但是TI发送完不代表485芯片转发数据也完成了。此时可能正在发送数据的停止位。如果此时马上将控制引脚拉低,可能会导致数据传输不完整。产生乱码。
于是改变程序,在状态切换的位置加入了1ms的延时。片段如下:
void Uart2SendData(unsigned char dat)
{
P33=1;
EA=0;
Delay1ms();
S2BUF =dat; //发送完8位数据,停止位发送时不能拉低P33,否则数据不完整
while((S2CON & 0X02)==0);
S2CON &= ~0X02;
Delay1ms();
EA=1;
P33=0;
}
具体多少ms根据发送数据位数判断。本文发送1个字节,延时1ms是够的。延时程序根据芯片主频编写。
问题得到了解决,485可以正常通信了,假设是对的。
其实,在问题刚出现的阶段,还考虑过是不是几块控制板同时发送心跳包导致485通信链路上发生了数据碰撞,或者是在发送数据时,有数据到来导致没有接收到等等情况。但实测并没有这些情况的出现。后来查阅资料发现485电平模式配套的上层协议有modbus,可以完成更严谨的485通信。有时间也可以去了解一下。