当上位机和下位机进行通讯或多个微控制器进行通讯时需要进行通讯,很常用的一种就是通过串口收发命令,在简单的系统中可以自己定义一些简单的协议,收发双方按照协议来就可以了,如果要保证传输的稳定和同其他系统的兼容,最好采用通用的通讯协议。
我们可以Modbus协议进行修改,使之能使用在自己的系统中。Modbus协议包括ASCII、RTU、TCP等,并没有规定物理层。此协议定义了控制器能够认识和使用的消息结构,而不管它们是经过何种网络进行
通信的。标准的Modicon控制器使用RS232C实现串行的Modbus。Modbus的ASCII和RTU协议比较如下:
通过比较可以看到,ASCII协议和RTU协议相比拥有开始和结束标记,因此在进行程序处理时能更加方便,而且由于传输的都是可见的ASCII字符,所以进行调试时就更加的直观,另外它的LRC校验也比较容易。但是因为它传输的都是可见的ASCII字符,RTU传输的数据每一个字节ASCII都要用两个字节来传输,比如RTU传输一个十六进制数0xF9,ASCII就需要传输’F’’9’的ASCII码0x39和0x46两个字节,这样它的传输的效率就比较低。所以一般来说,如果所需要传输的数据量较小可以考虑使用ASCII协议,如果所需传输的数据量比较大,最好能使用RTU协议。
MODBUS通信之ASCII通信方式的每个字符的数据格式规定如下
·1个起始位
·8个数据位
·无校验
·1个停止位
在MODBUS之ASCII通信方式中,其数据格式中每个字节(8bit)都是一个十六位进制字符组成。发送时每个字节(8bit)都作为两个ASCII码字符发送。
ASCII通信方式数据格式
MODBUS的ASCII方式的数据格式如下所示:
各部份内容说明如下:
起始码:数据格式的帧头,以“ :”号表示(4位),ASCII码为(3AH)。
地址码:从站的地址(8位),01H-FFH。
功能码:主站发送,告诉从站执行功能(8位),01H-FFH
数据区:具体数据内容(n× 8位,)
校验码:LRC校验码(8位),校验码的范围为由地址码开始到数据区结束,不包含起始码。
停止码:数据格式的帧尾,用 “CR”(0DH),“LF”(0AH)表示(8位)
控制器在MODBUS网络上以ASCII码模式通信,在数据格式中每8个bit(1个字节)都转换成ASCII码发送,也就是每个16进制字符(0~9),(A~F)都转换成ASCII码发送。这种方式的主要优点是字符发送的时间间隔可达1秒,而不产生错误。
数据格式的“:”为帧头,在发送时,网络上的设备不断侦测“:”字符,当有一个冒号被收到时,每个设备都会解码下个字符(地址码)来判断是否发给自己。
数据格式中的每个字符发送的时间间隔不能超过1秒,否则,接受设备将认为是传送错误。
功能码是主站告诉从站要执行的功能。例如运行命令,读取监控状态,修改参数,读取参数等。MODBUS协议制定了相关的功能代码,数据区为功能码的内容,执行什么运行命令,正转,反转,停止,修改那个参数等等。MODBUS协议对数据区的具体格式与内容没有作统一的规定,而留给设备生产商去制定。凡是采用MODBUS协议作为设备通信协议的生产商,都会在在这方面作具体说明。
对于Modbus协议的一些猜测:
1.Modus协议既然是将数据字节按ASCII码发送,为什么不以高4字节+低4字节的方式呢?我猜测的因为停止位是0x0D和0X0A,如果采用高4字节+低4字节传输,0x0D和0X0A有可能出现在数据位中。所以,如果数据采用高4字节+低4字节的传输方式,可以将停止位换成0X20(空格)等高4字节有值的数,这样一来就不会跟前面的数据位相冲突。(我自己定的协议就是这么做的)。
2.Modbus采用了2个字节的停止位,有可能是为了防止如果采用1个字节的停止位会出现校验位或命令位与停止位相同的情况(Modbus协议是不定长的,如果自己采用定长的协议,应该可以将停止位变成一个字节)。
原作者:Mr老李 EE漫谈