Modbus协议是全球最早用于工业现场的总线规约,许多工业设备,包括PLC,DCS,智能仪表等都在使用此协议作为他们之间的通信标准。
Modbus 协议是一个请求/应答协议,发起请求的为Master(client),响应请求的为slave(server)。
此协议定义了一个控制器能认识使用的消息结构,而不管它们是经过何种网络进行通信的。它描述了一个控制器请求访问其它设备的过程,如何回应来自其它设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共格式。
这里大致说明Modbus协议的消息中包含有哪些域(ADU:应用数据单元,PDU:协议数据单元),并且说明各个域的作用。但是需要注意,modbus tcp无地址码和校验码,modbus ascii和modbus rtu也有差别,具体请看下节详述。
地址码:每个从机都必须有唯一的地址码(从1到247,0是广播地址),并且只有符合地址码的从机才能响应回送。当从机回送信息时,相应的地址码表明该信息来自于何处。
功能码:主机发送的功能码告诉从机执行什么任务。ModBus通讯规约定义功能号为1到127。表2-1列出部分常用功能码,以备查询。
数据区:数据区包含需要从机执行什么动作或由从机采集的返送信息。应答包中,数据包括了数据字节长度+数据值,请求包中数据只包含数据值。
校验码:主机或从机可用校验码进行判别接收信息是否出错。
代码 |
中文名称 |
为操作/字节操作 |
操作数量 |
01 | 读线圈状态 |
位操作 |
单个或多个 |
02 | 读离散状态 |
位操作 |
单个或多个 |
03 | 读保持寄存器 |
字节操作 |
单个或多个 |
04 | 读输入寄存器 |
字节操作 |
单个或多个 |
05 | 写单个线圈 |
位操作 |
单个 |
06 | 写单个保持寄存器 |
字节操作 |
单个 |
15 | 写多个线圈 |
位操作 |
多个 |
16 | 写多个保持寄存器 |
字节操作 |
多个 |
各种介质如有线RS-232/422/485/;光纤、无线等,对应的通信模式是MODBUS RTU或MODBUS ASCII。
起始位 |
设备地址 |
功能代码 |
数据 |
LRC校验 |
结束符 |
: | 2个字符 |
2个字符 |
n个字符 |
2个字符 |
2个字符 |
使用ASCII模式,消息以冒号(:)字符(ASCII码 3AH)开始,以回车换行符结束(ASCII码 0DH,0AH)。
其它域可以使用的传输字符是十六进制的0...9,A...F。网络上的设备不断侦测“:”字符,当有一个冒号接收到时,每个设备都解码下个域(地址域)来判断是否发给自己的。消息中字符间发送的时间间隔最长不能超过1秒,否则接收的设备将认为传输错误。
起始位 |
设备地址 |
功能代码 |
数据 |
CRC校验 |
结束符 |
T1-T2-T3-T4 |
8bit |
8bit |
n个8bit |
16bit |
T1-T2-T3-T4 |
使用RTU模式,消息发送至少要以3.5个字符时间的停顿间隔开始(如上图的T1-T2-T3-T4所示)。传输的第一个域是设备地址。可以使用的传输字符是十六进制的0...9,A...F。网络设备不断侦测网络总线,包括停顿间隔时间内。当第一个域(地址域)接收到,每个设备都进行解码以判断是否发往自己的。在最后一个传输字符之后,一个至少3.5个字符时间的停顿标定了消息的结束。一个新的消息可在此停顿后开始。
整个消息帧必须作为一连续的流转输。如果在帧完成之前有超过1.5个字符时间的停顿时间则为非法帧,如果一个新消息在小于3.5个字符时间内接着前个消息开始,接收的设备将认为它是前一消息的延续,这将导致一个错误,因为在最后的CRC域的值不可能是正确的。即帧之间的间隔必须大于3.5T,帧内字符的间隔必须小于1.5T。实际应用中1.5T一般不处理,只处理3.5T(FreeModBus开源代码就是这样)。
在以太网上进行通讯,对应的通讯模式是MODBUS TCP,其帧结构如下图。
与MODBUS RTU相比,少了校验域和地址码,其中地址码被放到MBAP报文头里面了,没有校验域是因为TCP本身就有校验所以省略了。
对应的通信模式是Modbus PLUS。
如果你做的是modbus master,可以使用modbus slave工具模拟从设备来调试,该工具下载地址:http://www.cr173.com/soft/21410.html
如果你做的是modbus slave,可以使用modbus poll工具模拟主设备来调试,该工具下载地址:http://www.cr173.com/soft/21405.html
以上两个工具的使用方法,可以参考此博客:
https://blog.csdn.net/byxdaz/article/details/77979114
STM32L475 + STM32CubeMX + KEIL5
使用STM32L475单片机的uart1作为调试串口,uart2外接RS485芯片作为modbus通讯串口,PC3引脚用来控制RS485芯片的方向。下载本工程后,只需根据你的硬件,改变上述接口,即可正常工作!
本工程实现了MODBUS MASTER RTU的功能,MODBUS SLAVE RTU、MODBUS ASCII和MODBUS TCP均未测试!
https://u20529624.ctfile.com/fs/20529624-383190905
本人使用modbus slave工具进行测试,读取线圈、离散、输入、保持四种寄存器都正常,如下图所示
STM32L071 + STM32Cube + KEIL5
https://u20529624.ctfile.com/fs/20529624-383193713