STM32F1之RS485通讯协议·MODBUS-RTU超详细解析

目录

1.  简介

2.  Modbus RTU功能码简述

2.1  功能码说明

2.2  寄存器地址分配

2.4  寄存器种类说明

2.5  PLC地址和协议地址区别

2.5.1  寄存器 PLC 地址

2.5.2  寄存器协议地址

3.  Modbus RTU指令说明

3.1  读线圈寄存器01H

3.1.1  描述

3.1.2  查询

3.1.3  响应

3.2  读离散输入寄存器02H

3.2.1  说明

3.2.2  查询

3.2.3  响应

3.3  读保持寄存器03H

3.3.1  说明

3.3.2  查询

3.3.3  响应

3.4  读输入寄存器04H

3.4.1  说明

3.4.2  查询

3.4.3  响应

3.5  写单个线圈寄存器05H

3.5.1  说明

3.5.2  请求

3.5.3  响应

3.6  写单个保持寄存器06H

3.6.1  说明

3.6.2  请求

3.6.2  响应

3.7  写多个线圈寄存器0FH

3.7.1  说明

3.7.2  请求

3.7.3  响应

3.8  写多个保持寄存10H

3.8.1  说明

3.8.2  请求

3.8.3  响应


 

1.  简介

        Modbus 是一种串 行通信协议,是Modicon 于 1979年,为使用可编程逻辑控制器(PLC)而发表的。Modbus是工业领域通信协议的业界标准,并且现在是工业电子设备之间相当常用的连接方式。Modbus 比其他通信协议使用的更广泛的主要原因有:

(1)公开发表并且无版税要求;

(2)相对容易的工业网络部署;

(3)对供应商来说,修改移动原生的位元或字节限制较少。

Modbus网络示意图:

2.  Modbus RTU功能码简述

功能码功能寄存器PLC地址位操作/字操作操作数量
01H读线圈状态00001-09999位操作(1字节)单个或多个
02H读离散输入状态10001-19999位操作(1字节)单个或多个
03H读保持寄存器40001-49999字操作(2字节)单个或多个
04H读输入寄存器30001-39999字操作(2字节)单个或多个
05H写单个线圈00001-09999位操作(1字节)单个
06H写单个保持寄存器40001-49999字操作(2字节)单个
0FH写多个线圈00001-09999位操作(1字节)多个
10H写多个保持寄存器40001-49999字操作(2字节)多个

2.1  功能码说明

        功能码可以分为位操作和字操作两类。位操作的最小单位为BIT,字操作的最小单位为两个字节。

(1)位操作指令

        读线圈状态 01H,读(离散)输入状态 02H,写单个线圈 05H 和写多个线圈OFH.

(2)字操作指令

        读保持寄存器 03H,写单个寄存器 06H,写多个保持寄存器 10H。

2.2  寄存器地址分配

寄存器PLC地址寄存器协议地址功能码位操作/字操作操作数量
00001-099990000H-FFFFH01H、05H、0FH线圈状态可读可写
10001-199990000H-FFFFH02H离散输入状态可读
30001-399990000H-FFFFH04H输入寄存器可读
40001-499990000H-FFFFH03H、06H、10H保持寄存器可读可写

2.4  寄存器种类说明

寄存器种类说明PLC 类比举例说明
线圈状态输出端口。可设定端口的输出状态,也可以读取该位的输出状态DO 数字量输出继电器输出,MOSFET(晶体管)输出等
离散输入状态输入端口。通过外部设定改变输入状态,可读但不可写DI 数字量输入按钮开关,光电开关等
保持寄存器输出参数或保持参数。控制器运行时被设定的某些参数。可读可写AO 模拟量输出

模拟量输出设定值,PID 运行参数,变量阀输出大小,传感器报警上限下限

输入寄存器输入参数。控制器运行时从外部设备获得的参数。可读但不可写AI 模拟量输入模拟量输入

2.5  PLC地址和协议地址区别

        PLC地址可以理解为协议地址的变种,在触摸屏的PLC编程中应用较为广泛。

2.5.1  寄存器 PLC 地址

        寄存器PLC地址指存放于控制器中的地址,这些控制器可以是PLC,也可以是触摸屏,或是文本显示器。PLC地址一般采用10进制描述,共有5位,其中第一位代码寄存器类型。第一位数字和寄存器类型的对应关系如表1 所示。PLC地址例如 40001、30002等。

2.5.2  寄存器协议地址

        寄存器协议地址指指通信时使用的寄存器地址,例如PLC地址40001对应寻址地址0000H, 40002对应寻址地址 0001H,寄存器寻址地址一般使用 16进制描述。再如,PLC寄存器地址 40003 对应协议地址 0002,PLC 寄存器地址 30003 对应协议地址 0002,虽然两个PLC 寄存器寄存器通信时使用相同的地址,但是需要使用不同的命令访问,所以访问时不存在冲突。

3.  Modbus RTU指令说明

3.1  读线圈寄存器01H

3.1.1  描述

        读线圈寄存器当前状态。

3.1.2  查询

假设一个例子:

        例如从机地址位01H,线圈寄存器的起始地址位0013H,结束地址位0037H,该次查询总共访问37个线圈寄存器。

线圈寄存器01H-主机发送:

字节序号功能16进制数据
1从机地址01
2功能码01
3寄存器起始地址高字节00
4寄存器起始地址低字节13
5寄存器数量高字节00
6寄存器数量低字节25
7CRC校验低字节0C
8CRC校验高字节14

3.1.3  响应

        响应负载中的各线圈状态与数据内容每位相对应,1代表ON,0代表OFF。若返回的线圈数部位8的倍数,则在最后数据字节末尾使用0代替。

读线圈寄存器01H-模块返回:

字节序号功能16进制数据
1从机地址01
2功能码01
3返回字节数05
4数据1(线圈0013H-线圈001AH)CD
5数据2(线圈001BH-线圈0022H)6B
6数据3(线圈0023H-线圈002AH)B2
7数据4(线圈0032H-线圈002BH)0E
8数据5(线圈0037H-线圈0033H)1B
9CRC校验低字节44
10CRC校验高字节EA

        线圈 0013H 到线圈 001AH的状态为CDH,二进制值为 11001101,该字节的最高位为线圈 001AH,最低位 为线圈 0013H。线 圈 001AH 到线 圈 0013H 的状态 分 别 为ON-ON-OFF-OFF-ON-ON-OFF-ON。

线圈0013H到001AH状态:

001AH0019H0018H0017H0016H0015H0014H0013H
11001101

        最后一个数据字节中,线圈0033H到线圈0037的状态为1BH (二进制00011011),线圈0037H是左数第4位,线圈0033H为该字节的最低位,线圈0037H至线圈0033H的状态分别为 ON-ON-OFF-ON-ON,剩余 3 位使用 0 填充。

线圈0033H到0037H状态:

003AH0039H0038H0037H0036H0035H0034H0033H
00011111

3.2  读离散输入寄存器02H

3.2.1  说明

        读离散输入寄存器状态。

3.2.2  查询

假设一个例子:

        从机地址为01H,离散输入寄存器的起始地址为00C4H,结束寄存器地址为00D9H。

总共访问22个离散输入寄存器。

读离散输入寄存器02H-主机发送:

字节序号功能16进制数据
1从机地址01
2功能码02
3寄存器起始地址高字节00
4寄存器起始地址低字节C4
5寄存器数量高字节00
6寄存器数量低字节16
7CRC校验低字节B8
8CRC校验高字节39

3.2.3  响应

        响应各离散输入寄存器状态,分别对应数据区中的每位值, 1代表ON: 0代表OFF。器第一个数据字节的LSB (最低位)为查询的寻址地址寄存器值,其他输入口按顺序在该字节中由低位向高位节排列,直到填充满8位。下一个字节中的8个输入位也是从低字节到高字节排列。若返回的输入位数不是8的倍数,则在最后的数据字节中的剩余位至该字节的最高位使用 0填充。

读离散输入寄存器02H-模块返回:

字节序号功能16进制数据
1从机地址01
2功能码02
3返回字节数03
4数据1(00C4H-00CBH)AC
5数据2(00CCH-00D3H)DB
6数据3(00D4H-00D9H)35
7CRC校验低字节22
8CRC校验高字节88

        离散输入寄存器 00D4H 到0OD9H 的状态为35H(二进制00110101)。输入寄存器 00D9H为左数第3位,输入寄存器00D4为最低位,输入寄存器00D9H到00D4H的状态分别为ON-ON-OFF-ON-OFF-ON。00DBH寄存器和00DAH寄存器被0填充。

离散输入寄存器00C4H到00DBH状态:

00CBH00CAH00C9H00C8H00C7H00C6H00C5H00C4H
00110101
00D3H00D2H00D1H00D0H00CFH00CEH00CDH00CCH
11101011
00DBH00DAH00D9H00D8H00D7H00D6H00D5H00D4H
00110101

3.3  读保持寄存器03H

3.3.1  说明

        读保持寄存器。可读取单个或者多个保持寄存器。

3.3.2  查询

假设一个例子:

        从机地址为01H,保持寄存器的起始地址为006BH,结束寄存器地址为006DH。

总共访问3个保持寄存器。

读保持寄存器03-主机发送:

字节序号功能16进制数据
1从机地址01
2功能码03
3寄存器起始地址高字节00
4寄存器起始地址低字节6B
5寄存器数量高字节00
6寄存器数量低字节03
7CRC校验低字节74
8CRC校验高字节17

3.3.3  响应

        保持寄存器的长度为2个字节。对于单个保持寄存器而言,寄存器高字节数据先被传输,低字节数据后被传输。保持寄存器之间,低地址寄存器先被传输,高地址寄存器后被传输。

读保持寄存器03H-模块返回:

字节序号功能16进制数据
1从机地址01
2功能码03
3返回字节数06
4数据1高字节(006BH)00
5数据1低字节(006BH)6B
6数据2高字节(006CH)00
7数据2低字节(006CH)13
8数据3高字节(006DH)00
9数据3低字节(006DH)00
10CRC校验低字节F5
11CRC校验高字节79

保持寄存器006BH到006DH结果:

006BH高字节006BH低字节006CH高字节006CH低字节006DH高字节006DH低字节
006B00130000

3.4  读输入寄存器04H

3.4.1  说明

        读输入寄存器命令。该命令支持单个寄存器访问也支持多个寄存器访问。

3.4.2  查询

        从机地址为01H。输入寄存器的起始地址为0008H,寄存器的结束地址为0009H。本次访问2个输入寄存器。

读输入寄存器04H-主机发送:

字节序号功能16进制数据
1从机地址01
2功能码04
3寄存器起始地址高字节00
4寄存器起始地址低字节08
5寄存器数量高字节00
6寄存器数量低字节02
7CRC校验低字节F0
8CRC校验高字节09

3.4.3  响应

        输入寄存器长度为2个字节。对于单个输入寄存器而言,寄存器高字节数据先被传输,低字节数据后被传输。输入寄存器之间,低地址寄存器先被传输,高地址寄存器后被传输。

字节序号功能16进制数据
1从机地址01
2功能码04
3返回字节数04
4数据1高字节(006BH)00
5数据1低字节(006BH)0A
6数据2高字节(006CH)00
7数据2低字节(006CH)0B
8CRC校验低字节9A
9CRC校验高字节41

输入寄存器0008H到0009H的结果:

006BH高字节006BH低字节006CH高字节006CH低字节
000A000B

3.5  写单个线圈寄存器05H

3.5.1  说明

        写单个线圈寄存器。FFOOH 值请求线圈处于 ON 状态,0000H 值请求线圈处于 OFF 状态。05H指令设置单个线圈的状态, 15H指令可以设置多个线圈的状态,两个指令虽然都设定线圈的 ON/OFF 状态,但是 ON/OFF 的表达方式却不同。

3.5.2  请求

        从机地址为01H,线圈寄存器的地址为00ACH。使00ACH线圈处于ON状态,即数据内容为FFOOH。

写单个线圈寄存器05H-主机发送:

字节序号功能16进制数据
1从机地址01
2功能码05
3寄存器地址高字节00
4寄存器地址低字节AC
5数据 1 高字节FF
6数据 1 低字节00
7CRC校验低字节4C
8CRC校验高字节1B

3.5.3  响应

写单个线圈响应:

字节序号功能16进制数据
1从机地址01
2功能码05
3寄存器地址高字节00
4寄存器地址低字节AC
5数据 1 高字节FF
6数据 1 低字节00
7CRC校验低字节4C
8CRC校验高字节1B

3.6  写单个保持寄存器06H

3.6.1  说明

        写保持寄存器。注意06H指令只能操作单个保持寄存器, 10H指令可以设置单个或多个保持寄存器。

3.6.2  请求

        从机地址为01H.保持寄存器地址为0000H.寄存器内容为0001H。

写单个保持寄存器 06H-主机发送:

字节序号功能16进制数据
1从机地址01
2功能码06
3寄存器地址高字节00
4寄存器地址低字节00
5数据高字节00
6数据低字节01
7CRC校验低字节48
8CRC校验高字节0A

3.6.2  响应

写单个保持寄存器06H-模块返回:

字节序号功能16进制数据
1从机地址01
2功能码06
3寄存器地址高字节00
4寄存器地址低字节00
5寄存器数据高字节00
6寄存器数据低字节01
7CRC校验低字节48
8CRC校验高字节0A

3.7  写多个线圈寄存器0FH

3.7.1  说明

        写多个线圈寄存器。若数据区的某位值为“1”表示被请求的相应线圈状态为 ON,若某位值为“0”,则为状态为0FF。

3.7.2  请求

        从机地址为 01H,线圈寄存器的起始地址为 0013H,线圈寄存器的结束地址为 001CH。总共访问 10 个寄存器。寄存器内容如下表所示。

线圈寄存器 0013H 到 001CH:

001AH0019H0018H0017H0016H0015H0014H0013H
11001101
0022H0021H0020H001FH001EH001DH001CH001BH
00000001

        传输的第一个字节CDH对应线圈为0013H到001AH,LSB(最低位)对应线圈0013H,传输第二个字节为01H,对应的线圈为001BH到001CH,LSB (最低位)对应线圈001BH,其余未使用位使用0填充。

写多个线圈寄存器0FH-主机发送:

字节序号功能16进制数据
1从机地址01
2功能码0F
3寄存器起始地址高字节00
4寄存器起始地址低字节13
5寄存器数据高字节00
6寄存器数据低字节0A
7字节数02
8数据1(0013H-001AH)CD
9数据1(001BH-001CH)01
10CRC校验低字节72
11CRC校验高字节CB

3.7.3  响应

写多个线圈寄存器0FH-模块返回:

字节序号功能16进制数据
1从机地址01
2功能码0F
3寄存器起始地址高字节00
4寄存器起始地址低字节13
5寄存器数据高字节00
6寄存器数据低字节0A
7CRC校验低字节24
8CRC校验高字节09

3.8  写多个保持寄存10H

3.8.1  说明

        写多个保持寄存器。

3.8.2  请求

        从机地址为 01H。保持 寄存器的起始地址为 0001H,寄存器的结束地址为 0002H.总共访问2个寄存器。保持寄存器0001H的内容为000AH,保持寄存器0002H的内容为0102H.

写多个保持寄存器 10H-主机发送:

字节序号功能16进制数据
1从机地址01
2功能码10
3寄存器起始地址高字节00
4寄存器起始地址低字节01
5寄存器数据高字节00
6寄存器数据低字节02
7字节数04
8数据 1 高字节00
9数据 1 低字节0A
10数据 2 高字节01
11数据 2 低字节02
12CRC校验低字节92
13CRC校验高字节30

保持寄存器0001H到0002H的内容:

0001H0001H0002H0002H
高字节低字节高字节低字节
000A0112

3.8.3  响应

字节序号功能16进制数据
1从机地址01
2功能码10
3寄存器起始地址高字节00
4寄存器起始地址低字节01
5寄存器数据高字节00
6寄存器数据低字节02
7CRC校验低字节10
8CRC校验高字节08

  • 43
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
STM32中使用RS485Modbus-RTU通信时,接线方式如下:将STM32的发送引脚连接到RS485芯片的发送引脚,将RS485芯片的输出引脚连接到RS485总线的A线,将RS485芯片的使能引脚连接到STM32的一个GPIO引脚。此外,还需要将RS485总线的B线连接到地线。这样,STM32通过控制RS485芯片的使能引脚,可以实现在发送和接收模式之间的切换。具体的代码实现可以参考以下示例: RS485_TX_ENABLE; //使能485控制端(启动发送) for(j=0;j<i;j++) { Modbus_Send_Byte(modbus.sendbuf[j]); } RS485_RX_ENABLE; //失能485控制端(改为接收) 这段代码中,RS485_TX_ENABLE用于启动发送模式,RS485_RX_ENABLE用于启动接收模式。 需要注意的是,在RS485总线上,设备之间的连接方式是A接A,B接B。这样才能正确传输数据。另外,RS485通信是半双工的,即同一时刻只能进行发送或接收。这是因为RS485只有一个数据传输通道。 总结起来,STM32与RS485的接线方式包括将发送引脚连接到RS485芯片的发送引脚,将RS485芯片的输出引脚连接到RS485总线的A线,将RS485芯片的使能引脚连接到STM32的GPIO引脚,并将RS485总线的B线连接到地线。通过控制RS485芯片的使能引脚,可以实现发送和接收模式的切换。请注意按照A接A、B接B的方式连接设备。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [STM32作为从机通过RS485实现Modbus RTU通讯](https://blog.csdn.net/DBLLLLLLLL/article/details/88390677)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [STM32+RS485+Modbus-RTU(主机模式+从机模式)-标准库/HAL库开发](https://blog.csdn.net/qq_37281984/article/details/122739968)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时光の尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值