工作:MODBUS通讯协议知识
一、Modbus三种通讯分类
-
Modbus TCP/IP
使用网口通讯,更多是用于快速网络设备,如机器人,上位机视觉。
-
Modbus RTU
使用RS232或者RS485/RS422接口,通讯方式是串口通讯,是直接传输二进制数值的通讯,工业领域用得最多。
-
Modbus ASCII
使用RS232或者RS485/RS422接口,通讯方式是串口通讯,Modbus ASCII比前两者少用,支持Modbus ASCII协议的设备一定也会支持Modbus RTU协议。
三种类型区别:
硬件接口以及传输数据方式不一样
如果设备之间需要Modbus协议通讯的时候,这两个设备必须都支持Modbus协议。由于是基于串口通讯,串口通讯的格式双方也要一致。 如96 8 1 偶(UART通讯格式)。
二、Modbus协议格式
1. Modbus报文解析
2. 报文里的设备地址(从站地址)
3. 报文中的校验码
发送时,串口通讯软件将带对数据校验后带校验码报文发出去(勾上数据校验即可),对方收到后,对发过来的带校验码的报文进行校验后,其校验码一定是00 00
注意,串口通讯里的奇偶校验位是不在Modbus报文的,奇偶校验位是在串口通讯UART发送一个字节后对该字节进行奇偶校验,只对此字节负责,不对Modbus报文内容负责。
3.常用功能码
Modbus中常用的功能码有 8个,可以分为位操作和字操作两类,如下表
3.1 读线圈功能码H01/H02
这里读取的线圈数量不可以超过2000Bits(250字节X8bits),下面有介绍原因
如下为FX3U PLC输入与输出线圈,设备规格书一般会提示是哪些只读,哪些是可读可写。
上图中H02功能码是可以读出X0-X377,但不可以使用参数为读写的H01功能码去读取x0-x377,因为X点只支持读取。
例子:
(1)读取PLC的M点(读取什么类型只要参照上面Modbus参数即可,发送时记得勾选数据校验)
01【从站地址】 01【功能码】 00【起始地址(高字节)】 00【起始地址(低字节)】 00【读取数量(高字节)】 10【读取数量(低字节)】
即从M0开始读取,读取10个Bit位
返回值:
01【从站地址】 01【功能码】 02【返回数据字节数】 FF【返回字节1(低字节)】 00【返回字节2(高字节)】 F8【CRC校验码】 0C【CRC校验码】
因为读10Bit位,所以会返回2个字节,00FF即M0-M7全ON,M8-M15全OFF,注意返回的数据里,低字节在前,高字节在后。
(2)读取PLC的X点(读取什么类型只要参照上面Modbus参数即可,发送时记得勾选数据校验)
01【从站地址】 02【功能码】 34【起始地址(高字节)】 00【起始地址(低字节)】 00【读取数量(高字节)】 06【读取数量(低字节)】
即从X0开始读取,读取6个Bit位
返回值:
01【从站地址】 02【功能码】 01【返回数据字节数】 03【返回字节1(低字节)】 _【返回字节2(高字节)】 E1【CRC校验码】 89【CRC校验码】
因为读6Bit位,所以只会返回1个字节,03即X0-X1全ON,X2-X7全OFF,注意返回的数据里,低字节在前,高字节在后。
这里如果用H01(此功能码参数为可读可写的数据)会报错的,返回如01 81 02 C1 91的数据,81就是读取出错,因为X点为只读参数,不可对其使用H01
3.2 读寄存器功能码H03和H04
如下为FX3U PLC寄存器,通常设备规格书一般会提示是哪些只读,哪些是可读可写。
例子:
(1)读取PLC的数据寄存器D(读取什么类型只要参照上面Modbus参数即可,发送时记得勾选数据校验)
01【从站地址】 03【功能码】 00【起始地址(高字节)】 00【起始地址(低字节)】 00【读取字数量(高字节)】 02【读取字数量(低字节)】
即从D0开始读取,读取2个字节。
返回值:
01【从站地址】 03【功能码】 04【返回数据字节数】 1A【返回字节1(寄存器1高字节)】 1B【返回字节2(寄存器1低字节)】 1C【返回字节3(寄存器2高字节)】 1D【返回字节4(寄存器2低字节)】 F8【CRC校验码】 0C【CRC校验码】
因为读2个字,所以会返回4个字节,值分别为1A 1B 1C 1D,注意返回的数据里,高字节在前,低字节在后。
3.3 写单线圈和多线圈功能码H05和H0F
上面打错字,”十字进“是十进制
如下为FX3U PLC线圈,通常设备规格书一般会提示是哪些只读,哪些是可读可写。
例子:
(1)置位/复位单个PLC的中间继电器M(读取什么类型只要参照上面Modbus参数,发送时记得勾选数据校验)
01【从站地址】 05【功能码】 00【起始地址(高字节)】 00【起始地址(低字节)】 FF【置位FF/复位00】 00【固定值】
即置位M0。
返回值:
01【从站地址】 05【功能码】 00【起始地址(高字节)】 00【起始地址(低字节)】 FF【置位FF/复位00】 00【固定值】 8C【CRC校验码】 3A【CRC校验码】
(2)置位/复位多个PLC的中间继电器M(读取什么类型只要参照上面Modbus参数,发送时记得勾选数据校验)
01【从站地址】 0F【功能码】 00【起始地址(高字节)】 00【起始地址(低字节)】 00【写线圈数量(高字节)】 09【写线圈数量(低字节)】 02【字节数】 FF【线圈形成的十六进制值(低字节)】 01【线圈形成的十六进制值(高字节)】
即以十六进制值FF置位或复位低字节那8个线圈,以十六进制值01置位或复位高字节那1个线圈(M0-M7全ON,M8=on),
注意是先低字节再到高字节。
返回值:
01【从站地址】 0F【功能码】 00【起始地址(高字节)】 00【起始地址(低字节)】 00【写线圈数量(高字节)】 09【写线圈数量(低字节)】 95【CRC校验码】 CD【CRC校验码】
3.4 写单寄存器和多寄存器功能码H06和H10
注意H10的H是十六进制
如下为FX3U PLC寄存器,通常设备规格书一般会提示是哪些只读,哪些是可读可写。
例子:
(1)读单个寄存器(读取什么类型只要参照上面Modbus参数,发送时记得勾选数据校验)
01【从站地址】 06【功能码】 00【寄存器地址(高字节)】 02【寄存器地址(低字节)】 FF【写入值(高字节)】 FF【写入值(低字节)】
返回值:
01【从站地址】 06【功能码】 00【寄存器地址(高字节)】 02【寄存器地址(低字节)】 FF【写入值(高字节)】 FF【写入值(低字节)】 29【CRC校验码】 BA【CRC校验码】
(2)读多个寄存器(读取什么类型只要参照上面Modbus参数,发送时记得勾选数据校验)
01【从站地址】 10【功能码】 00【寄存器地址(高字节)】 00【寄存器地址(低字节)】 00【写寄存器数量(高字节)】 03【写寄存器数量(低字节)】 03【写入总字节数】 0A【写入字节1(寄存器1高字节)】 0B【写入字节2(寄存器1低字节)】 1A【写入字节3(寄存器2高字节)】 1B【写入字节4(寄存器2低字节)】 2A【写入字节5(寄存器3高字节)】 2B【写入字节6(寄存器3低字节)】
返回值:
01【从站地址】 10【功能码】 00【寄存器地址(高字节)】 00【寄存器地址(低字节)】 00【写寄存器数量(高字节)】 03【写寄存器数量(低字节)】 80【CRC校验码高字节】 08【CRC校验码低字节】
3.5 Modbus消息结构-摘自作者Pou光明
Pou光明写得也很好,简略易懂。
以功能码01(0x01)与03(0X03)为例进行说明。
(1)功能码01H读取Modbus从站中线圈寄存器的状态,可以是单个寄存器,或者是多个连续的寄存器。(看懂前面3.1可以跳过)
发送:
假设从站地址为01H,读取线圈寄存器的起始地址为0017H,读取38(十进制)个寄存器,指令结构如下表:
这里发送了01 01 00 17 00 26 OD D4 这8个字节。设备B接收到了这8个字节,那么设备B就根据Modbus协议约定功能执行相应的动作,这8个字节称为报文,也叫一个信息帧,当然因为命令差异,报文可以不止8个字节。
响应:
各线圈的状态与数据内容的每个bit对应,1代表ON,0代表OFF.若查询线圈的数量不是8的倍数,则在最后一个字节的高位补0.
读线圈结果:
第一个字节CDH对应线圈0017H到001E的状态,转为二进制是11001101,其中bit0对应0017H,bit7对应001E
(2) 功能码03H读取Modbus从站中读取保存寄存器的状态,可以是单个寄存器,或者是多个连续的寄存器。(看懂前面3.2可以跳过)
三、 Modbus协议的绝对地址
1 对应区的值范围与功能。
四、学习Modbus通讯,举例设置PLC主从站
本节为摘选第二集: MODBUS RTU模式下通信设置和线路连接(三菱PLC)的部分内容。
以FX3U的 Modbus RTU进行设置,实际项目要根据实际项目硬件规格书进行设置。
1. 硬件
Modbus RTU使用串口通讯,可以使用RS485接线
- 实际接线举例…
以FX3U-32MT+485BD板+485ADP-MB为例
FX3U只能扩展出2个通道。这里特别说明下,如果没有485BD板,那么此时的485ADP-MB就
变成了通道1。
2. 软件
由于要验证功能码报文,所以拿串口调试助手当主站,plc当从站。而且由于485BD板不能当从站,因此要通过485ADP-MB来进行测试。
TIPS:PLC是一个最好的从站设备,它有MODBUS所有的存储区特性.
(a) 由于要拿通道2的485ADP-MB来进行测试,所以要用到以下特殊寄存器
D8420: 通信格式:我们按照如下通信格式进行设置: 数据位=8,奇偶校验=偶校验,停止位=1,波特率=9600,RS485连接。那么按照通信格式设置表格它的二进制为0001 0000 10000111,转换为16进制值是H1087,所以 “MOV H1087 D8420”
( b ) D8421: 协议: 我们按照如下协议设置: MODBUS协议,MODBUS从站,RTU模式。那么它的16进制值为H11,要"MOV H11 D8421"
( c ) D8434:从站本站号: 设置为1。那么它的16进制值为H1,要“MOV H1 D8434"
将上面三个的特殊寄存器设置完后,我们要用M8411特殊辅助寄存器来触发将它们写入到PLC中。它是在用到MODBUS通信时,用来写入通信设定的。如果是RS/RS2指令,就可以用M8002来写入,没有特殊要求。
到此,FX3U的485ADP-MB从站就设置完毕了.
五、FX3U Modbus指令ADPRW
可以使用SSCOM作从站,PLC作主站,然后PLC往SSCOM发内容进行通讯,成功通讯后可以显示出来PLC发出的报文,方便进行练习。
- SSCOM接到的信息
但是由于SSCOM不是真正设备,无法返回M0/M1数据,所以PLC M100/M101会还是OFF
六、Modbus调试助手
本节内容摘自-Pou光明
TCP协议下有Server和Client,两个都需要设置,不然只有一个也无法通信~
实验材料:Windows系统的电脑、Modbus Poll(Client)、ModSim32(Server)
1. ModSim32(Server)的相关设置
(1) ModSim32 初始界面
(2)修改Address和Length,MODBUS Point Type使用默认类型,Devide Id使用默认值是1,方便使用
(3)点击上方菜单栏【Connection】–>【Connect】–>【Modbus/TCP Svr】。确定服务器端口,点击【OK】按钮。成功启动后不再有“NOT CONNECTED!”显示
本次我们使用的是第三种保持寄存器类型。
本教程主要侧重Server与Client的通信搭建,其他更多的功能熟练之后容易探索。
2. Modbus Pol(Client)的相关设置
(1)Modbus Poll初始化界面
Tx代表接收数据,Err表示错误,F代表功能码类型,SR是扫描(发送)周期
(2)读写定义的设置
点击上方菜单栏的【Setup】->【Read/Write Definition…】或者F8快捷键直接打开
Slave ID保持一致为1,Function使用默认参数,注意这里地址设置为0,与Server端地址相差1,Quantity是设置的寄存器数量,下次给大家分享pymodbus库时会有很好的对应说明,这里面了解下即可。Scan Rate使用默认的即可。下方的View Rows 是对可以看见的区域设置,随便点点,没什么大问题的。之后点击【Apply】->【OK】按钮使设置成功。
- (a)TCP IP的通讯设置
- (b)串口通讯的设置(Modbus RTU/Mobus ASCII才用)
(3)连接服务器的设置
点击上方菜单栏的【Connection】->【Connect…】或F3快捷键直接打开
Connection 默认选择的是Modbus TCP/IP,下方是远程Modbus Server的设置,像网络调试助手一样连接服务器一样,需要设置服务器的Ip和Port.其余参数使用默认传参数即可。之后点击【OK】按钮即可。
- (a)Modbus TCP 连接服器
(4)连接成功与更改数值
连接成功如下:
更改数据操作:
鼠标左键双击蓝色单元格,会出现弹窗图中的弹窗,修改Value部分单元格数值为【666】,之后点击【Send】按钮完成修改。
修改成功后效果:
(5)Modbus客户端这边设置相对多一些,熟悉后就像使用网络调试助手一样。从设置上来看,Client与Server双方在访问的地址上必须一致,否则Client连接时会报出【无效地址】的错误。如下: