modbus协议教程
1、modbus协议简介
modbus是工业现场总线通信协议中应用较为成熟稳定的协议。理解起来也比较简单。modbus数据传输采用大端模式
1.1功能码简要说明
modbus定义了不同的功能码来操作不同类型的数据。具体如下:
序号 | 功能码 | 名称 | 读写 | 寄存器数据类型 | 说明 |
---|---|---|---|---|---|
1 | 0x01 | 读线圈寄存器 | R | bit | 读输出开关量,每个bit代表一个信号。类比mcu的通用输出口 |
2 | 0x02 | 读离散输入寄存器 | R | bit | 读输入开关量,每个bit代表一个信号。类比mcu的通用输入口 |
3 | 0x03 | 读保持寄存器 | R | uint16 | 读数据,每个数据是16位 |
4 | 0x04 | 读输入寄存器 | R | uint16 | 读输入数据,每个数据是16位,类比模拟量输入信号 |
5 | 0x05 | 写单个线圈寄存器 | W | bit | 写输出开关量,每个bit代表一个信号。类比mcu的通用输出口 |
6 | 0x06 | 写单个保持寄存器 | W | uint16 | 写数据,每个数据是16位 |
7 | 0x0f | 写多个线圈寄存器 | W | bit | 写输出开关量,每个bit代表一个信号。类比mcu的通用输出口 |
8 | 0x10 | 写多个保持寄存器 | W | uint16 | 写数据,每个数据是16位 |
1.2线圈寄存器读写操作(读输出口状态,设置输出口状态)
1.2.1 读单个线圈寄存器(功能码0x01)
字节 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
说明 | 通信地址 | 功能码 | 数据高地址 | 数据低地址 | 数据长度高字节 | 数据长度低字节 | CRC低字节 | CRC高字节 |
示例 | 0x01 | 0x01 | 0x00 | 0x00 | 0x00 | 0x01 | 0xFD | 0xCA |
数据地址:开始读取的首地址
数据长度:读取的长度,注意由于线圈寄存器的最小单位是bit,所以改长度对应的读取的bit数量,上面的例子中读取的是地址第一个线圈寄存器的值
如果线圈寄存器的值为1,则返回如下数据:
字节 | 1 | 2 | 3 | 4 | 5 | 5 |
---|---|---|---|---|---|---|
说明 | 通信地址 | 功能码 | 字节数 | 数据0 | CRC低字节 | CRC高字节 |
示例 | 0x01 | 0x01 | 0x01 | 0x01 | 0x90 | 0x48 |
1.2.2写单个线圈寄存器(功能码0x05)
将单个线圈寄存器写1,注意写1要发送0xff 0x00
字节 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
说明 | 通信地址 | 功能码 | 数据高地址 | 数据低地址 | 数据长度高字节 | 数据长度低字节 | CRC低字节 | CRC高字节 |
寄存器置1 | 0x01 | 0x05 | 0x00 | 0x00 | 0xFF | 0x00 | 0x8C | 0x3A |
返回数据为发送的数据:
01 05 00 00 FF 00 8C 3A
将单个线圈寄存器写0,注意写0要发送0x00 0x00
字节 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
说明 | 通信地址 | 功能码 | 数据高地址 | 数据低地址 | 数据长度高字节 | 数据长度低字节 | CRC低字节 | CRC高字节 |
寄存器置0 | 0x01 | 0x05 | 0x00 | 0x00 | 0x00 | 0x00 | 0xCD | 0xCA |
返回的数据为发送的数据:
01 05 00 00 00 00 CD CA
1.2.3读多个线圈寄存器(功能码0x01)
读取两个线圈寄存器,假如线圈寄存器1值为1,线圈寄存器2值为1则,
读
01 01 00 00 00 02 BD CB
数据返回
01 01 01 03 11 89
返回的值为3,3的2进制表述为11b
1.2.4写多个线圈寄存器(功能码0x0F)
字节 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
说明 | 通信地址 | 功能码 | 数据高地址 | 数据低地址 | 线圈数量高字节 | 线圈数量低字节 | 字节数量 | 数据 | CRC低字节 | CRC高字节 |
示例 | 0x01 | 0x0F | 0x00 | 0x00 | 0x00 | 0x02 | 0x01 | 0x03 | 0x9E | 0x96 |
上面的例子是将第一和第二个线圈写入1。0x03的二进制为11b。
返回的数据格式如下:
字节 | 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 |
---|---|---|---|---|---|---|---|---|
说明 | 通信地址 | 功能码 | 数据高地址 | 数据低地址 | 线圈数量高字节 | 线圈数量低字节 | CRC低字节 | CRC高字节 |
示例 | 0x01 | 0x0F | 0x00 | 0x00 | 0x00 | 0x02 | 0xD4 | 0x0A |
注意,当写入的线圈数量不大于8则字节数量为1,数据为1个字节。如果长度超过8,则字节数量为2,字节8对应1-8线圈的值,字节9对应线圈9-16的值,字节10和11为crc
1.3读输入离散输入寄存器(功能码0x02)
字节 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
说明 | 通信地址 | 功能码 | 数据高地址 | 数据低地址 | 读取数量高字节 | 读取数量低字节 | CRC低字节 | CRC高字节 |
示例 | 0x01 | 0x02 | 0x00 | 0x00 | 0x00 | 0x04 | 0xFD | 0xCA |
上面读取了4个离散输入寄存器的值,假如4个寄存器的值为0101b,则返回数据如下:
字节 | 1 | 2 | 3 | 4 | 7 | 8 |
---|---|---|---|---|---|---|
说明 | 通信地址 | 功能码 | 字节数量 | 数据 | CRC低字节 | CRC高字节 |
示例 | 0x01 | 0x02 | 0x01 | 0x05 | 0x61 | 0x8b |
其中的每个bit代表io口的输入值。
1.4读取输入寄存器(功能码0x04)
输入寄存器读取的是类似模拟量的数据,每个数据占16bit。而离散输入寄存器每个bit占1个bit,这是这两者的区别。
字节 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
说明 | 通信地址 | 功能码 | 数据高地址 | 数据低地址 | 读取数量高字节 | 读取数量低字节 | CRC低字节 | CRC高字节 |
示例 | 0x01 | 0x04 | 0x00 | 0x00 | 0x00 | 0x01 | 0x90 | 0x0a |
上面读取了1个输入寄存器值,假如寄存器的值为0x1000,从机的返回如下:
字节 | 1 | 2 | 3 | 4 | 7 | 8 | |
---|---|---|---|---|---|---|---|
说明 | 通信地址 | 功能码 | 字节数量 | 寄存器数据高字节 | 寄存器数据低字节 | CRC低字节 | CRC高字节 |
示例 | 0x01 | 0x04 | 0x02 | 0x10 | 0x00 | 0xb4 | 0xf0 |
读取4个输入寄存器如下:
01 04 00 00 00 04 F1 C9
返回数据
01 04 08 10 00 10 01 10 02 10 03 F2 90
返回的数据长度:8字节
第一个寄存器值:0x1000
第二个寄存器值:0x1001
第三个寄存器值:0x1002
第四个寄存器值:0x1003
1.5 保持寄存器读写操作
1.5.1读保持寄存器(功能码0x03)
字节 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
说明 | 通信地址 | 功能码 | 寄存器高地址 | 寄存器低地址 | 读取数量高字节 | 读取数量低字节 | CRC低字节 | CRC高字节 |
示例 | 0x01 | 0x03 | 0x00 | 0x00 | 0x00 | 0x02 | 0xc4 | 0x0b |
上面读取了两个寄存器的值,假如第一个寄存器值0x147b,第二个寄存器值0x3f8e,则从机的返回数据如下:
字节 | 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 |
---|---|---|---|---|---|---|---|---|---|
说明 | 通信地址 | 功能码 | 字节数量 | 第一个寄存器数据高字节 | 第一个寄存器数据低字节 | 第二个寄存器数据高字节 | 第二个寄存器数据低字节 | CRC低字节 | CRC高字节 |
示例 | 0x01 | 0x03 | 0x04 | 0x14 | 0x7b | 0x3F | 0x8E | 0x1E | 0x4E |
1.5.2写单个保持寄存器(功能码0x06)
字节 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
说明 | 通信地址 | 功能码 | 寄存器高地址 | 寄存器低地址 | 写入值高字节 | 写入值低字节 | CRC低字节 | CRC高字节 |
示例 | 0x01 | 0x06 | 0x00 | 0x00 | 0x00 | 0x02 | 0x08 | 0x0b |
如果写入成功:则返回发送下去的值
01 06 00 00 00 02 08 0B
这样就成功将第一个寄存器的值写为0x0002
1.5.3写多个保持寄存器(功能码0x10)
字节 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
说明 | 通信地址 | 功能码 | 寄存器高地址 | 寄存器低地址 | 寄存器数量高字节 | 寄存器数量低字节 | 写入字节数 | 第一个寄存器值高字节 | 第一个寄存器值低字节 | 第二个寄存器值高字节 | 第二个寄存器值低字节 | CRC低字节 | CRC高字节 |
示例 | 0x01 | 0x10 | 0x00 | 0x00 | 0x00 | 0x02 | 0x04 | 0x00 | 0x01 | 0x00 | 0x02 | 0x23 | 0xae |
如果写入正常则从机的返回值如下:
字节 | 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 |
---|---|---|---|---|---|---|---|---|
说明 | 通信地址 | 功能码 | 数据高地址 | 数据低地址 | 线圈数量高字节 | 线圈数量低字节 | CRC低字节 | CRC高字节 |
示例 | 0x01 | 0x10 | 0x00 | 0x00 | 0x00 | 0x02 | 0x41 | 0xc8 |
这样就正常将第一个寄存器写入0x0001,第二个寄存器写入0x0002
1.6 错误反馈
如果发送的命令有问题,则会返回错误帧,如果是crc错误,从机是不会返回任何数据。从机返回错误的格式如下:
字节 | 1 | 2 | 3 | 9 | 10 |
---|---|---|---|---|---|
说明 | 地址码 | 功能码 | 错误码 | CRC低字节 | CRC高字节 |
示例 | 0x01 | 0x80+功能码 | 0x00 |
常见错误码
错误码 | 名称 | 说明 |
---|---|---|
0x01 | 非法功能码 | 不支持该功能码操作寄存器 |
0x02 | 非法的寄存器地址 | 设备没有该地址 |
0x03 | 非法的数据 | 数据格式不对 |
0x04 | 从机故障 | 从机工作不正常 |
发送:01 06 00 00 01 02 04 00 01 00 02
返回:01 86 03 02 61
错误码为3,说明数据格式错误。上面的数据应该是写多个寄存器0x10,但功能码是写单个寄存器0x06,所有导致错误。
发送:01 16 00 00 01 02 04 00 01 00 02 D3 71
返回:01 96 01 8E 60
错误码为1,说明功能码不对,没有0x16功能码
modbus协议教程相关推荐
- Modbus教程| Modbus协议,ASCII和RTU帧,Modbus工作
转载自:https://www.rfwireless-world.com/Tutorials/Modbus-Protocol-tutorial.html 这个Modbus教程涵盖了modbus协议基础 ...
- Modbus协议简易入门教程
关注+星标公众号,不错过精彩内容 转自 | 小麦大叔 之前有不少读者在问关于Modbus协议相关的问题,今天给大家分享一篇由小麦大叔整理的Modbus协议教程. 背景 介绍modbus rtu之前,我 ...
- 【Modbus 】Modbus 协议
Modbus 协议简介 Modbus协议是一项应用层报文传输协议,包括ASCII.RTU.TCP三种报文类型. 标准的Modbus协议物理层接口有RS232.RS422.RS485和以太网接口,采用m ...
- RS485与Modbus通信协议教程!
原文:RS485与Modbus通信协议教程!_接口_信号_传输 1979年施耐德电气制定了一个用于工业现场的总线协议Modbus协议,现在工业中使用RS485通信场合很多都采用Modbus协议,所以今 ...
- modbus协议与nodejs modbus-serial实现
nodejs可通过modbus-serial库来实现modbus协议 npm install modbus-srial 安装完后在examples目录下有例子说明如何使用,本文主要讲述作为客户端的使用 ...
- Modbus协议在串行链路上的实现
目录 1.串行链路通信简介 2.串行链路通信协议原理 3.串行链路通信帧描述 4.RTU.ASCII串行传输模式 4.1.RTU传输模式 4.2.ASCII传输模式 1.串行链路通信简介 Modbus ...
- 一文看懂Modbus协议
目录 1.协议简介 2.协议格式 3.数据模型 1.协议简介 自从 1979 年出现工业串行链路的事实标准以来,Modbus使成千上万的自动化设备能够通信.Modbus 是OSI模型第 7 层上的应用 ...
- java modbus协议
概念 Modbus是一种串行通信协议,Modbus协议目前存在用于串口.以太网以及其他支持互联网协议的网络的版本. 大多数Modbus设备通信通过串口EIA-485物理层进行. 通讯格式 地址域 功能 ...
- 遵循Modbus协议通过Usb(Ch375)通信的上位机传输问题
遵循Modbus协议通过Usb(Ch375)通信的上位机传输问题 Delphi / Windows SDK/API http://www.delphi2007.net/DelphiNetwork/ht ...
最新文章
- adminlte+layui框架搭建3 - layui弹出层
- OO_Unit2_多线程电梯
- 前端学习(1896)vue之电商管理系统电商系统之修改用户状态
- 【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--参数自动映射篇(6/8)...
- SharePoint Enterprise Search基础知识点拾遗系列之二
- Python花式编程案例锦集(2)
- 从职业方向,谈程序员如何突破成长瓶疾,我们该怎么去学习?
- 7820X+RTX2080Ti(Ubuntu 18.04)新机配置记录
- 【单机实现系列】SharePoint2010与Exchange Server2010 结合
- 瑞昱rtl8168网卡支持Linux吗,瑞昱 RTL8168F PCI-E专用网卡驱动,亲测可用
- 《经济学人》15个栏目版块介绍,快速了解杂志!
- ADB投屏_手机无需安装客户端的【安卓投屏】
- 高刷新率电视机有必要吗?
- MATLAB求解矩阵特征值的六种方法
- Linux平台串口读取GPS每次只能收到8个字节 以及 使用LiveGBS 调试 GB28181设备 包括视频 GPS信息等等
- Vue单文件组件TypeScript写法
- html中如何放音乐 和视频播放器,HTML5培训之HTML5音乐播放器和视频播放器分享
- TO B是什么?TO C呢?
- 特征锦囊:如何根据变量相关性画出热力图?
- 机器学习常见英语单词解释