深入理解Modbus
基于串口的Modbus软件开发
----------------------八股--------------------
一、开发背景:
2、GAT垃圾项目的DCS要通过Modbus与PLC进行通讯,我们的DCS仅进行过简单的测试。要连鬼子的炉排PLC,还需进行更正式的测试,秦SUN为了体现ABB的软件水平,特决定自己写一个ABoBo公司的MB测试软件。
1、已经有好多个测试软件了,但是没有开源。如modbusscan 7.),Modbus Poll version, 4.3.1, ,ModLink,ModbusSimulator
2、协议比较老了,但是很管用。
----------------------八股--------------------
----------------------N步走--------------------
----------------------八股--------------------
一、开发背景:
2、GAT垃圾项目的DCS要通过Modbus与PLC进行通讯,我们的DCS仅进行过简单的测试。要连鬼子的炉排PLC,还需进行更正式的测试,秦SUN为了体现ABB的软件水平,特决定自己写一个ABoBo公司的MB测试软件。
1、已经有好多个测试软件了,但是没有开源。如modbusscan 7.),Modbus Poll version, 4.3.1, ,ModLink,ModbusSimulator
2、协议比较老了,但是很管用。
----------------------八股--------------------
----------------------N步走--------------------
第一步:图书馆借N本VC串口编程的书
第二步:上网下N个源代码
第三步:上网下个虚拟串口的程序。(www.sudt/cn/sn/download.htm)
第四步:学习Modbus协议
第二步:上网下N个源代码
第三步:上网下个虚拟串口的程序。(www.sudt/cn/sn/download.htm)
第四步:学习Modbus协议
主从方式,主站初始化传输。从站根据主设备查询提供的数据作出反应。
主站查询格式:站(或广播)地址、功能代码、要发送的数据、错误检测域。
从站回应格式:确认要行动的域、返回的数据、错误检测域。如果在消息接收过程中发生错误,或从站不能执行其命令,从站将建立错误消息并把它作为回应发送出去。
从站地址是0...247,0为广播地址
LRC(纵向冗长检测)
使用ASCII模式,消息以冒号(:)字符(ASCII码 3AH)开始,以回车换行符结束(ASCII码 0DH,0AH)。
其它域可以使用的传输字符是十六进制的0...F。网络上的设备不断侦测“:”字符,当有一个冒号接收到时,每个设备都解码下个域(地址域)来判断是否发给自己的。
消息中字符间发送的时间间隔最长不能超过1秒,否则接收的设备将认为传输错误。
RTU模式
地址 | 功能代码 | 数据数量 | 数据1 | ... | 数据n | CRC低字节 | CRC高字节 | ||
代码系统:
8位二进制,十六进制数0...9,A...F
消息中的每个8位域都是一个两个十六进制字符组成
每个字节的位:
1个起始位
8个数据位,最小的有效位先发送
1个奇偶校验位,无校验则无
1个停止位(有校验时),2个Bit(无校验时)
错误检测域
CRC(循环冗长检测)
深入理解ModBus功能码
Modbus主要功能码
功能码 | 名称 | 注释 | |
01 | Read Coil Status | (线圈状态0x)(读PLC的开出状态) | bit 读位 ,与5对应, 可读可写DO |
02 | Read Input Status | (输入状态1x) (读PLC的开入状态) | bit 读位,只读DI |
03 | Read Holding Register | (保持寄存器4x HR) (读模出状态) | 读整形、状态字、浮点型、字符型,与16对应 |
04 | Read Input Register | (输入寄存器3x AR) (读PLC模入状态) | 读整形、状态字、浮点型 只读AI |
05 | Write Single Coil | (强制单路开出,给PLC写数据) | 写单个位 可读可写DO |
06 | Write Single Register | (强制单路模出,给PLC写数据) | 写单个整形、状态字、浮点型、字符型,写HR4x的地址区 |
15和16可能是用于一次写一串数据的,不允许单个写。如时间的世纪、年、月、日、时、分、秒要一次写下去
设备和Modbus 地址范围对应表 | ||||
设备地址 | Modbus地址 | 描述 | 功能 | R/W |
1...10000* | address - 1 | Coils (outputs) | 0 | Read/Write |
10001...20000* | address - 10001 | Discrete Inputs | 01 | Read |
40001...50000* | address - 40001 | Holding Registers | 03 | Read/Write |
40000* | address - 30001 | Input Registers | 04 | Read |
最大值与设备相关
注:设备地址是从1开始的,所以Modbus写入地址要在设备地址上减1。
协议格式
功能码:04 (输入寄存器3x AR) (读模入状态)
例:从1站读0…1(寄存器 30001…30002),共2个数据
从站地址 | 功能码 | H 地址 | L 地址 | H 数据 | L 数据 | CRC | |
01 | 04 | 00 | 00 | 00 | 02 | 71 | CB |
主站
从站地址 | 功能码 | 字节数 | H数据 | L数据 | H数据 | L数据 | CRC | |
01 | 单reactor和主从reactor04 | 04 | 00 | 06 | 00 | 05 | DB | 86 |
从站
注:变量写的从站反馈没有数据
注:变量写的从站反馈没有数据
秦批:Modbus的从站反馈数据没有数据帧的编号(不像TCP协议那样),所以不会显示这个反馈数据是主站的哪次请求的。若主站一次发送N个数据,从站而没有及时反馈,这样就乱了,主站就不知道从站发过来的数据是哪次命令的。
单变量与多变量:读可以读单读多,命令不分读几个。但是写要区分写一个还是写多个,所以写命令有写单线圈和写多线圈
Modbus所有功能码
功能码 | 名称 | 作用 |
01 | 读取线圈状态 | 取得一组逻辑线圈的当前状态(ON/OFF) |
02 | 读取输入状态 | 取得一组开关输入的当前状态(ON/OFF) |
03 | 读取保持寄存器 | 在一个或多个保持寄存器中取得当前的二进制值 |
04 | 读取输入寄存器 | 在一个或多个输入寄存器中取得当前的二进制值 |
ModBus功能码与数据类型对应表
代码 | 功能 | 数据类型 |
03 | 读 | 整型、字符型、状态字、浮点型 |
04 | 读 | 整型、状态字、浮点型 |
05 | 写 | 位 |
Modbus变量地址
映射地址 | 功能 | 地址类型 | 存取方式 | 描述 |
0xxxx | 01,05,15 | Coil | 读写 | |
1xxxx | 02 | 离散输入 | 只读 | |
2xxxx | 03,04,06,16 | 浮点寄存器 | 读写 | 两个连续16位寄存器表示一个浮点数(ieee754格式32位) |
3xxxx | 04 | 输入寄存器 | 只读 | 每个寄存器表示一个16位无符号整数(0~65535)同上 |
4xxxx | 03,06,16 | 保持寄存器 | 读写 | |
5xxxx | 03,04,06,16 | ascii字符 | 读写 | 每个寄存器表示两个ascii字符 |
FAQ0:ABB组态软件有功能块读线圈-1,读线圈-8,读寄存器-1,读寄存器-8的原因是什么?
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论