MODBUS-寄存器与功能码学习
1.Modbus-RTU 是数据在串口RS485等链路上传输的,数据包格式=PDU(Process Data Unit)+CRC
2.Modbus-TCP是在以太网TCP层传输的,使用502端口,客户端和服务器模式,数据包格式=前导字节+PDU,没有CRC了,多了前导字节。
3.Modbus over TCP/IP,准确说是Modbus-RTU over TCP/IP
,使用TCP层传输Modbus-RTU的报文,端口不一定是502了,TCP层报文格式就是Modbus-RTU的标准格式=PDU(Process
Data Unit)+CRC
注意:下面说的modbus是在异步串行上的传输。
Modbus+:是Modbus的扩展版本,是Modicon莫迪康专有的,和Modbus不同。它需要一个专门的协处理器来处理类似HDLC(高级数据链路控制,在同步网上传输数据、面向比特的数据链路层协议,它是由国际标准化组织(ISO)根据IBM公司的SDLC(SynchronousData Link Control)协议扩展开发而成的)的高速令牌旋转,MODBUSPLUS比MODBUS的性能更好,通讯速率快,从协议开发上来说区别较大,参考
分类 |
简称 |
起始地址 |
结束地址 |
能够使用的功能码 |
输出逻辑线圈/(可读写位)/(DI/O)(如继电器开关控制) |
0x |
00000 |
09999 |
0x01读一组逻辑线圈 0x05写单个线圈 0x0f写多个线圈 |
离散量触点/开关量输入/只读位(DI)如按键是否按下 |
1x |
10000 |
19999 |
0x02读一组开关输入
|
输入寄存器(AI)实时数据如AD采集数据。 |
3x |
30000 |
39999 |
0x04读一个或多个输入寄存器
|
保持寄存器(AI/O) 如设置的各种参数 |
4x |
40000 |
49999 |
0x03读一个或多个保持寄存器的值
0X06写单个保持寄存器 0X10写多个保持寄存器 |
RTU协议中的指令由地址码(一个字节,范围1~247,0地址用于广播,其它保留),功能码(一个字节),起始地址(两个字节),数据(N个字节),校验码(两个字节)五个部分组成,总帧长最大256字节。
0x01: 读一组逻辑线圈,如读8个继电器输出状态。
0x0F: 写一组逻辑线圈。如同时控制8个继电器
0x05: 写单个逻辑线圈,如设定单个继电器
0x02: 读一组开关量的输入,如读显示板是否有按键按下、水流开关的状态。
0x03: 读一个或多个保持寄存器,如读一个或多个设置参数
0x010: 写一个或多个保持寄存器,如写设置参数
0x06: 写单个保持寄存器,如写单个设置参数
0x04: 读一个或多个输入寄存器,如读具体的按键值,AD采集的信息等
Pasted from <http://blog.csdn.net/educast/article/details/8159510
错误码:功能码的最高位置1.
0x17:发送的字节数指的是要写的字节数,相应的字节数是指读的字节数,注意是先写后读。
《Modbus软件开发实践指南》参考手册
1单片机开发与PLC开发的异同:
MODBUS协议是专门针对485总线设备(例PLC)开发,寄存器的定义要严格按照其地址范围;功能码的功能定义及定义的寄存器地址与功能码的使用要要严格符合。如上图。
而当单片机开发用串口点对点,可能不会完全遵守MODBUS协议具体体现在2方面:
首先是定义的寄存器地址范围,应结合不同单片机RAM的大小和项目得实际需求定义起始范围和大小。方法如在RAM区的不同区域定义不同功能的数组:
IOX[N]:输出线圈,用来进行继电器的操作
IX[M]:开关输入 ,用于识别按键是否按下的查询。
其它:功能码的使用也不会严格限定在指定的PLC地址范围。
2modbus寄存器的地址说明:
有两套规则,一套称为PLC地址,为5位十进制数,例如40001,PLC地址40001意味着该参数类型为保持寄存器。另一套是协议地址,协议地址为0x0000,这里面有对应关系,去掉PLC地址的最高位,然后剩下的减1即可。这会存在一个问题,PLC地址30002和PLC地址40002的协议地址同为0x0001,此时访问时是不是会冲突呢。亲们,当然不会了,30001为输入寄存器,需要使用04指令访问,而40001为保持寄存器,可以使用03、06和16指令访问。注意定义的寄存器地址像数组一样都是从0开始的,即通讯中的地址比实际地址小“1”
http://blog.sina.com.cn/s/blog_6ab9638f0100vqol.html
3线圈寄存器:就是可以单独进行位控制的BITS寄存器,类似C51的位带结构体
Typedef struct
{
Bit:0
Bit:1
..
Bit:14
Bit:15
}COIL_REG
http://blog.sina.com.cn/s/blog_598b27cd0101rphm.html
4modbus帧结构:
ADU:应用数据单元
PUD:协议数据单元
freemodbus中如何判断帧结束
modbus协议中没有明显的开始符和结束符,而是通过帧与帧之间的间隔时间T3.5来判断的。超过T3.5就认为收到了新的帧。接下来就可
以处理数据了,首当其冲的就是判断帧的合法性。Modbus通过时间来判断帧是否接受完成,自然需要单片机中的定时器配合。
使用串口发送完成中断:避免丢失最后一个字节内容
Pasted from <http://www.360doc.com/content/14/0313/22/7991404_360395398.shtml>
Modbus TCP协议:
Modbus TCP协议则是在RTU协议上加一个MBAP报文头,由于TCP是基于可靠连接的服务,RTU协议中的CRC校验码就不再需要,所以在Modbus TCP协议中是没有CRC校验码,用一句比较通俗的话说就是:Modbus TCP协议就是Modbus RTU协议在前面加上五个0以及一个6,然后去掉两个CRC校验码字节就OK.虽然这句话说得不是特别准确,但是也基本上把RTU与TCP之间的区别说得比较清楚了
http://www.cnblogs.com/woxihuadabai/p/8043188.html
modbusTCP下从设备(每一个从设备一个ip地址)最多247个( ip地址1~247,248-255保留,0地址在请求的报文中请求的地址为0则为广播模式)。
NnmberMaxofClientTransaction :此参数取值为 1~16 (在下列各章中给出更完整的描述。
MODBUS 服务器可以接收并同时为多个 MODBUS 请求提供服务。服务器可以同时接收 MODBUS 请求
的最大数量是 MODBUS 服务器的主要特性之一。这个数量取决于服务器的设计以及它的处理和存储能
力。将这个实现参数称为“NumberMaxOfServerTransaction”,必须作为 MODBUS 服务器的一个特性
描述这个实现参数。根据设备的能力,它的取值范围为:1~16,。
“NumberMaxOfServerTransaction”参数对 MODBUS 服务器的操作和性能有非常显著的影响。尤
其重要的是,所管理的并发 MODBUS 事务处理的数量可能影响服务器对 MODBUS 请求的响应时间。
)
从地址:RTU(1~247,0,作为广播地址);TCP(不需要,必须使用0xff),0 也可以用作与 MODBUS/TCP 设备直接通信
TCP连接:默认2小时,超过这个时间每隔75s进行询问一次,连续8次。

广播操作(只能针对写指令):
RTU主站使用广播地址(0x0/0xff)发送一条命令报文,全部的从站收到报文后执行,但不发送回应报文。此功能在很多情况下(用广播方式给所有设备发送设置值,如变频器速率)很实用。
modbus poll 工具的几个时间;
- connect timeout:建立连接的时间,超时重连间隔
- response timeout:表示读取超时(放弃)时间,从站在超时时间内没有返回数据,则认为通讯失败,默认1000ms
- delay between polls:每次扫描的最小间隔时间,根据模式,slave数量,PC机特点不同(单个RTU或者TCP可以小于等于20ms,多slave时必须大于20ms,因为windows任务调度周期大概10~20ms,所以该值小于20ms不能保证T3.5。)
- scan rate( 0 ~ 3600000ms):读数据的时间间隔,一定要比整个来回通讯的时间要长
RTU通讯超时的计算:主站读取从站的寄存器为例,主站发出请求需要8个字节,从站返回响应为5 2*n个字节。其中n为寄存器个数。
在9600的波特率下,每秒可以传输出的桢数为:9600 / (1 + 8 + 1) = 960桢/秒,即960字节/秒。
每传输1个字节数据需要的时间为:1秒 / 960 = 1.041ms
(8 +1 +1)/9600=1.04ms/Byte
因此,主站发出响应到从站返回数据的时间周期为:
(8+ 5+ 2*n)*1.04+ T1 +T2,其中n为寄存器个数,T1为从站的响应时间(如果是PLC,则为PLC的扫描时间),T2为通讯余量,一般为20~50ms。
如果读取10个字的数据,从站响应时间为50ms,则整个周期为:
(8+ 5+ 2*10)*1.04+ 50+ 50=134.32ms。
因此,超时时间必须大于134.32ms,可以设置为150ms以上;
而ModBus协议中超时时间定为:3.5个桢长度为超时时间;
超时时间 = 3.5 * 1 / BaudRate / 10 秒
= 3.5 * 10 / BaudRate 秒
= 3.5 * 10 * 2 / BaudRate *2 秒
= 70 / BaudRate *2 秒
波特率大于19200使用定值:1750us
波特率小于19200使用定值:usTimerT35_50us = ( 7UL * 220000UL ) / ( 2UL * ulBaudRate )=770000/BaudRate; 这usTimerT35_50us 一个单位为50uS,将这个计算结果写到定时器。每中断一次为50us * usTimerT35_50us 微秒
————————————————
版权声明:本文为CSDN博主「sunxboy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sunxboy/article/details/84499791
单次触发操作:setup-read/write disable 或快捷键shift+F6,然后用F6或者图标来操作
使用手册:
网页scada:万物物联
协议栈的实现:
安富莱的《设计一款属于自己的Modbus RTU主从协议栈》
关于字节序问题:modbus一般采用大端顺序,比如设计50002~50005共4个u16来表示厂商id,但只用了一个u16,那只能是reg[50002]=0x1234,则读这个厂商码时的通讯帧为以下,可见从机在组织回复时的字节填充顺序为:50005H,50005L,50004H,50004L,50003H,50003L,50002H,50002L.同样的加入读的是一个f32的浮点数,回复的顺序也是
COM1-发送:01 03 c3 52 00 04 d9 9c
COM1-接收:01 03 08 00 00 00 00 00 00 1d 07 dd 45
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?