前段时间,做了一个小项目,十路继电器的控制方面,要用一台电脑通过串口控制两块单片机板子,每块板子有10路继电器。我是用的STC12C5A32S2芯片。用的RS485通信。
这个是一个多机通信,用的串口通信方式三(串口通信方式一不能用于多机通信,因为涉及到通信通道被哪个模块抢占的问题)。
其实这个有个问题,串口通信方式三,数据位为9位,而如何用串口调试助手与单片机通信呢,串口调试助手发送的数据位只有8位。这个问题不容忽视。否则会出问题的。
在网上找了一些类似的例子,并不满意,虽然后来发现这些例子并没有错。
下面来说一下,网上的例子局限性吧。
串口通信方式三中有个SM2位和RB8位,SM2可以决定要不要侦听串口发送来的信息。RB8位决定串口发送来的信息是数据字节,还是地址字节。
其一, 网上的某些例子,写的较复杂。它把地址和数据分开发送和接收。第一次发送或接收地址,第二次发送或接收数据信息。这样既要处理SM2,又要处理RB8,这样势必造成使用的不方便性。我们习惯了将地址信息字节写在一条协议的开头,后面紧跟多个字节的数据,还有校验什么的。
其二,这些例子当中,也没有提到RB8位该怎么处理,说白了就是并未说明,串口调试助手如何处理RB8位。
我多次调试发现,如果串口调试助手不做修改,沿用串口通信一的方式发送数据。对单个字节发送不成问题。但对于多个字节的发送(一次发送多个字节)就会有问题。下位机收到的数据会是乱码。
后来,我又在发送一条协议时,在发送字节之间加个1ms的延时,问题得到一定解决,但不完美。
再后来我把注意力集中在RB8上,问题才得以解决。
方法就是,把串口调试助手的停止位设置成2(思想就是,将其中一个停止位当做第九位)。
这样串口就相当于发送9个数据和一个停止位...
单片机要发送数据给上位机,将TB8位设置成1,串口调试助手就能收到正确信息。
接下来说一下其一中提到的问题.
相信大家对PC机的串口与单个单片机通信不陌生。
下位机(也就是单片机),程序写起来挺简单。无非是先来个串口初始化,再加个串口中断。使用的是串口通信方式一。
其实可以将串口通信方式三做的和通信方式一一样简单。只要初始化时将SM2设为0(表示对接收来的数据进行侦听),SM0和SM1都设为1(表示用的是串口通信方式三)。
然后串口中断中服务程序,不需要再操作SM2了,也不用操作RB8,一切和串口通信方式一一样了。
只是单片机在向上位机发送数据时,TB8设为1。这样就不用把地址和数据分得那么清楚了。对于每一个下位机来说相当于,一直在接收数据,对接收来的数据进行分析,判断地址相符,就做动作和回应。否则接收数据但不动作和回应。
最后说一下RS485通信问题
程序和RS232通信程序差不多,无非是,多个方向控制管教。发送时方向管脚拉高。接收时方向管脚拉低。