目 录
Modbus通信协议
Modbus由Modicon公司(也是现在的施耐德电气)于1979年开发,是一种工业现场总线协议标准。最初是为使用PLC(可编程逻辑控制器)通信而发表,即该协议最先是在PLC通信上使用的。
因以下特点而广泛使用:
1、免费 —— 使用在任何产品上
2、简单 —— 协议格式简单易用
3、接口丰富 —— 可以在串口、以太网、蓝牙等介质上传输,适用的物理接口有RS485、RS232、RS422
Modbus通信协议就像是一种特殊的语言规则,让不同的设备能够相互理解和交流。
比方说,有多个设备(控制器、温度传感器等)连接在系统网络中,它们原本可能各说各的话,谁也听不懂谁。但有了Modbus协议,就好像大家都学会了一种通用语言。通过这个语言,控制器可以询问温度传感器 “现在的温度是多少呀?”,控制器也可以告诉阀门驱动器 “把这个阀门打开”。
再比方说,五十六个民族各有各的方言,为了相互之间能够沟通和交流,普通话普及后解决了语言差异问题。
这个通信协议规定了信息怎么传递,用了什么样的格式,以及包含哪些具体内容等,让不同设备能够协同工作,实现数据交换和命令传达。
提示:要想熟悉Modbus通信协议,建议下载这两个小工具进行学习和实践,在Help > Help Topics和use manual中查看说明,很快你就掌握了。
Modbus主机设备角色:Modbus Poll
Modbus从机设备角色:Modbus Slave
上述的工具详细使用可以参考链接:
Modbus调试软件–ModbusPoll、ModbusSlave使用详解
提醒:对于不熟悉modbus两个工具的使用者,需要注意两个工具都可以同时运行多个mbp或mbs文件,从而实现多条指令发送和响应。如果把其中一个mbp或mbs文件最大化了,容易忘记除了最大化的文件在运行,还有其它也在运行。
出现一个情况,明明mbs设置没错,可是mbp就是读到0值,后来发现还有一个全0的mbs文件在运行。
一、说明
1.1 描述
Modbus协议是一种消息传递结构,广泛用于智能设备之间建立主从通信。
从主机(Host)发送到从机(Slave)的Modbus消息包含:
从机的地址 + 命令 + 数据 + 校验 (LRC或CRC)
1、命令类型:读寄存器(可理解为查询)或写寄存器(可理解为设置)
2、校验和方式:LRC或CRC,用于确保消息的完整性和正确性。
由于Modbus协议只是一个消息传递结构,它独立于底层物理层。传统上使用了RS232, RS422或RS485实现。
在标准Modbus网络上可以使用两种传输模式之一进行串口通信:
1、ASCII (美国信息交换标准代码)
2、RTU (远程终端单元)
还有另外一种用于网络通信:
3、TCP
Modbus 协议的帧结构使得主设备(通常是计算机或控制器)可以向从设备发送请求,并接收从设备的响应。通过解析帧结构中的各个字段,可以实现不同设备之间的数据交换和控制操作。
Modbus通信方式是:
1、主机广播或者单播发送指令,从机分析请求,并且给主机应答(如果出错就返回异常功能码)。
2、从机只能响应主机,不能主动发送数据。
- ASCII 模式
消息结构中是ASCII字符
当控制器设置在Modbus网络上使用ASCII模式进行通信时,消息中的每个8位字节作为两个ASCII字符(高4位,低4位)发送。这种模式的主要优点是,它允许字符之间出现最多一秒的时间间隔,而不会导致错误。
在ASCII模式下,消息以冒号(:)字符(0x3A)开始,以回车换行(CR LF)对结束(0x0D和0x0A)。
错误校验:纵向冗余校验(LRC)
所有其他字段允许传输的字符是十六进制0…9、a…F、网设备连续监视网络总线的冒号字符。当接收到一个时,每个设备解码下一个字段(地址字段),以确定它是否是被寻址的设备。
从机地址范围:0-255
消息中字符之间的间隔可以长达一秒。如果出现较大的间隔,则接收设备假定发生了错误。一个典型的消息框架(其中字符是指ASCII字符)如下所示:
开始 | 地址 | 功能码 | 数据 | LRC | 结束 |
---|---|---|---|---|---|
: | 2个字符 | 2个字符 | 多个字符 | 2个字符 | \r\n |
举例,读取温度数据
1、主机(控制器)发送请求消息
:01030000000174\r\n
01是从机地址,03是功能码,0000是访问的寄存器起始地址,0001是访问的寄存器数量,74是校验值
2、从机(温度传感器)收到请求后,处理并响应
:0103020019C4\r\n
01是从机地址,03是功能码,02是返回的数据字节数,0019是温度值对应的十六进制,C4是校验值
当字符帧使用ASCII模式时,错误检查字段包含两个ASCII字符。错误检查字符是对消息内容执行LRC(纵向冗余检查)计算的结果,不包括开始冒号和结束CRLF字符。LRC字符作为CRLF字符前面的最后一个字段附加到消息中。
//LRC 例子
BYTE LRC (BYTE *nData, WORD wlength)
{
BYTE nLRC