ESP32 使用RS485模块实现Modbus通信(二)

这篇具有很好参考价值的文章主要介绍了ESP32 使用RS485模块实现Modbus通信(二)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

MODBUS是一种广泛使用的工业通信协议,它允许通过串行线路在不同设备之间进行通信和数据交换。RS485模块是一个在ESP32上实现MODBUS协议的硬件。在本教程中,我们将使用RS485模块在ESP32开发板上创建一个MODBUS主机和从机设备,并实现与MODBUS主机的通信。

实验效果

多个Modbus(Server)从机设备与一个Modbus主机(Client)设备进行通信。

元件说明

ESP32 使用RS485模块实现Modbus通信(二),基于Modbus协议的工业自动化网络规范,modbus

  1. 使用工业级芯片,传输距离可达上千米
  2. 具有高达正负15KV的防静电保护
  3. 芯片内置限摆率控制,大大减少信号干扰
  4. 接收器输入阻抗仅1/4单位,支持多设备连接,可连接128个设备
  5. 工作温度范围广,-40°C到85°C正常工作
  6. 支持热插拔,不会出现信号锁死问题
  7. 使用贴片大容量电解电容进行电源滤波
  8. 双瞬态抑制二极管过压保护
  9. 10欧电流保护电阻,提高信号完整性
  10. RS485和TTL信号单面布线,保证信号质量
  11. 大面积铺铜层,提高抗干扰能力
  12. 提供2.54mm间距洞洞焊接,方便二次开发
  13. 常用M3螺钉固定孔,安装可靠
  14. 120欧端接电阻,支持自动适配
  15. 提供发射/接收指示灯,方便调试
  16. 弯角插针设计,方便测试
  17. 支持3.3V和5V控制,兼容性强

引脚说明

  • RXD —— 接受数据
  • TXD ——传输数据
  • VCC —— 5V供电
  • GND —— 接地
  • A —— 非反相接收器输入和非反相驱动器输出
  • B —— 反相接收器输入和反相驱动器输出

BOM表

  • ESP32 N个
  • RS485模块 N个
  • 跳线
  • 屏蔽信号线

接线图

ESP32 使用RS485模块实现Modbus通信(二),基于Modbus协议的工业自动化网络规范,modbus

ESP32 连接 RS485模块
GND <-> GND
GPIO 17 <-> RXD
GPIO 16 <-> TXD
5V <-> VCC

ESP32 使用RS485模块实现Modbus通信(二),基于Modbus协议的工业自动化网络规范,modbus

把所有RS485的模块的A和B,分别A连接A,B连接B,全部连接起来。

线圈和寄存器

在 Modbus 的内容中多次提到线圈(coil)和寄存器(register)的概念,尤其是 Moddbus功能码中,操作的对象基本上都是线圈和寄存器。

在 Modbus 协议中之所以仍然称为线圈和寄存器,完全是历史原因。在 PLC 应用领域,一个线圈就代表一个 PLC 输出点,也称为输出继电器。通过控制线圈导通与否来改变继电器输出状态,实现弱电控制强电。

ESP32 使用RS485模块实现Modbus通信(二),基于Modbus协议的工业自动化网络规范,modbus

但实际上,在如今的 Modbus 设备中,它们都只是对应一块内存区域而已。其中,线圈代表位操作(bit),表示一个布尔变量;寄存器代表字操作(word),表示一个整型变量(当然也可以通过多个字的组合,表示浮点数以及其他复合数据结构)。在 Modbus 协议中,字(word)的长度是 16 位,即 2 个字节。

寄存器种类说明

在 Modbus 协议中,所有数据均存放于寄存器中。根据存放的数据类型以及各自读写特性,可以将寄存器分为四个部分,这四个部分可以连续也可以不连续,完全由开发者决定。

下表展示了四类寄存器的含义以及与 PLC 的类比。

寄存器种类 含义 PLC 示例
线圈状态 (Coil Status) 输出端口(可读可写) DO(数字量输出) 电磁阀输出、LED 显示
离散输入状态 (Input Status) 输入端口(只读) DI(数字量输入) 拨码开关、微动开关
保持寄存器 (Holding Register) 输出参数(可读可写) AO(模拟量输出) PID 运行参数、阈值上下限
输入寄存器 (Input Register) 输入参数(只读) AI(模拟量输入) 传感器数据输入

寄存器地址分配

Modbus 寄存器地址分配如下表所示,同样参照了 PLC 寄存器地址的分配方法。

寄存器种类 寄存器PLC地址 寄存器Modbus协议地址 简称
线圈状态 00001~09999 0000H~FFFFH 0x
离散输入状态 10001~19999 0000H~FFFFH 1x
保持寄存器 40001~49999 0000H~FFFFH 4x
输入寄存器 30001~39999 0000H~FFFFH 3x

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

  • 寄存器 PLC 地址指存放于控制器中的地址,这些控制器可以是 PLC,也可以是触摸屏,或者文本显示器。PLC 地址一般采用十进制描述,共有 5 位,其中第一位数字代表寄存器类型。
  • 寄存器 Modbus 协议地址指的是通信时使用的寄存器寻址地址,例如 PLC 地址 40001 对应寻址地址 0x0000,40002 对应寻址地址 0x0001。寄存器寻址地址一般使用十六进制描述。

细心的你会发现,PLC 寄存器地址 40003 对应的协议地址是 0x0002,PLC 寄存器地址 30003 对应的协议地址也是 0x0002,虽然通信时使用两个相同的 Modbus 协议地址,但是因为不同寄存器的功能码是不相同的,因此并不存在访问冲突。

Modbus 功能码

Modbus 功能码是 Modbus 消息帧(报文)的重要组成部分,是 Modbus 协议中通信事务处理的基础。

ESP32 使用RS485模块实现Modbus通信(二),基于Modbus协议的工业自动化网络规范,modbus

Modbus 功能码占用一个字节,取值范围是 1~127(即 0x01~0x7F)。同时,使用功能码 + 0x80 表示异常状态,即 129~255 代表异常码。

在 Modbus 标准协议中,一共规定了三类 Modbus 功能码。

  1. 公共功能码
    • 被明确定义的功能码;
    • 保证唯一性;
    • 由 Modbus 协会确认,并提供公开的文档;
    • 可进行一致性测试;
    • 包括协议定义的功能码和保留将来使用的功能码。
  2. 用户自定义功能码
    • 有两个用户自定义功能码区域,分别是 65~72 和 100~110;
    • 用户自定义,不保证唯一性。
  3. 保留功能码
    • 保留功能码是因为历史遗留原因,某些公司的传统产品上现行使用的功能码不作为公共使用。

本教程主要介绍公共功能码,下表展示了 Modbus 协议中的部分公共功能码。

代码 名称 英文 寄存器 PLC 地址 位/字操作 操作数量
01 读线圈状态 Read Coils 00001~09999 位操作 单个或多个
02 读离散输入状态 Read Discrete Inputs 10001~19999 位操作 单个或多个
03 读保持寄存器 Read Holding Registers 40001~49999 字操作 单个或多个
04 读输入寄存器 Read Input Registers 30001~39999 字操作 单个或多个
05 写单个线圈 Write Single Coil 00001~09999 位操作 单个
06 写单个保持寄存器 Write Single Register 40001~49999 字操作 单个
15 写多个线圈 Write Multiple Coils 00001~09999 位操作 多个
16 写多个保持寄存器 Write Multiple Registers 40001~49999 字操作 多个

功能码的操作可分为两种:

  • 位操作 —— 最小单位为一位(bit),包括读线圈状态功能码 01、读离散输入状态功能码 02、写单个线圈功能码 05 和写多个线圈功能码 15;
  • 字操作 —— 最小单位为两个字节,包括读保持寄存器功能码 03、读输入寄存器功能码 04、写单个保持寄存器功能码 06 和写多个保持寄存器功能码 16。

功能码详解

0x01 读取线圈/离散量输出值
  • 该功能码用于读取从设备的线圈或离散量输出的状态,即各 DO(Discrete Output,离散输出)的 ON/OFF 状态。
  • 消息帧中指定了需读取的线圈起始地址和线圈数目。
  • 起始地址由 2 个字节构成,取值范围为 0x0000 到 0xFFFF。
  • 线圈数量由 2 个字节构成,取值范围为 0x0001 到 0x07D0(即十进制 1~2000)。
  • 需要注意,在 Modbus 协议规定的 PDU 中,规定所有线圈或寄存器地址从 0 开始计算。
0x02 读取离散量输入值
  • 该功能码用于读取从设备的离散输入,即 DI(Discrete Input)的 ON/OFF 状态。
  • 消息帧中指定了需读取的离散输入寄存器起始地址和数目,可读取 1~2000 个连续的离散量输入状态。
  • 如果从设备接受主设备的请求则回复功能码 02,并返回离散量输入各变量的当前状态(如果返回的 DI 数量不是 8 的整数倍,将用 0 填充最后数据字节的剩余位)。
  • 起始地址由 2 个字节构成,取值范围为 0x0000 到 0xFFFF。
  • 离散量数量由 2 个字节构成,取值范围为 0x0001 到 0x07D0(即十进制 1~2000),最多一次可读取 2000 个离散输入状态值。
0x03 读取保持寄存器值
  • 该功能码用于读取从设备保持寄存器的内容,不支持广播模式。
  • 消息帧中指定了需读取的保持寄存器的起始地址和数目,而保持寄存器中各地址的具体内容和意义则由设备开发者自行规定。
  • 起始地址由 2 个字节构成,取值范围为 0x0000 到 0xFFFF。
  • 寄存器数量由 2 个字节构成,取值范围为 0x0001 到 0x007D(即十进制 1~125),最多一次可连续读取 125 个寄存器值。
  • 需要注意,Modbus 的保持寄存器和输入寄存器是以字(Word)为基本单位的(1Word 等于 2Bytes)。因此,在读取时需要注意字节序(大小端)问题。
0x04 读取输入寄存器值
  • 该功能码用于读取从设备输入寄存器的内容,不支持广播模式。(与 03 功能码类似)
  • 消息帧中指定了需读取的输入寄存器的起始地址和数目,而输入寄存器中各地址的具体内容和意义则由设备开发者自行规定。
  • 起始地址由 2 个字节构成,取值范围为 0x0000 到 0xFFFF。
  • 寄存器数量由 2 个字节构成,取值范围为 0x0001 到 0x007D(即十进制 1~125),最多一次可连续读取 125 个寄存器值。
  • 同样需要注意字节序问题。
0x05 写单个线圈/单个离散输出
  • 该功能码用于将单个线圈寄存器(或离散输出)设置为 ON 或 OFF,支持广播模式。
  • 在广播模式下,所有从站设备的同一地址的值将被统一修改。
  • 消息帧中指定了需要变更的线圈地址和设定的状态值。
  • 起始地址由 2 个字节构成,取值范围为 0x0000 到 0xFFFF。
  • 目标数据(即查询报文中的 ON/OFF 状态)由报文数据字段的常数指定,0xFF00 表示 ON 状态,0x0000 表示 OFF 状态,其余所有值均是非法的。
  • 需要注意,在 Modbus 协议规定的 PDU 中,规定所有线圈或寄存器地址从 0 开始计算。
0x06 写单个保持寄存器
  • 该功能码用于更新从设备的单个保持寄存器的值,支持广播模式。
  • 在广播模式下,所有从站设备的同一地址的值将被统一修改。
  • 消息帧中需要指定从设备地址以及需要变更的保持寄存器地址和设定值。
  • 起始地址由 2 个字节构成,取值范围为 0x0000 到 0xFFFF。
  • 变更目标数据由 2 个字节构成,取值范围为 0x0000 到 0xFFFF。
  • 保持寄存器以字(Word)为基本单位,写入时需要注意目标数据的字节序问题。
0x08 诊断功能
  • 该功能码仅用于串行链路,主要用于检测主设备和从设备之间的通信故障,或检测从设备的各种内部故障,该功能不支持广播。
  • 查询报文中需要指定从设备地址、功能码(Modbus Command)以及子功能码(Diagnostic Sub-function)。其中,子功能码字段为 2 个字节,用于区别各诊断类型。
  • 在正常的响应报文中,从设备将原样回复功能码和子功能码。

常用的 Modbus 诊断子功能码定义如下:

功能码 子功能码 描述 说明
08 00(0x00) Return Data Query (Loop-back) 原样返回查询报文
08 01(0x01) Restart Communications 用于初始化并重新启动从站设备 其中,报文字段 0x00, 0x00 表示保持事件记录 0xFF, 0x00 表示清除事件记录
08 02(0x02) Return Diagnostic Register 返回诊断寄存器内容
08 03(0x03) Change ASCII Input Delimiter
08 04(0x04) Force Listen Only Mode 强制被寻址的从站设备进入只听模式 使其与网络中的其他设备断开,不返回响应
08 10(0x0A) Clear Counters and Diagnostic Registers 清除计数器和诊断寄存器
08 11(0x0B) Return Bus Message Count 返回总线报文计数值
08 12(0x0C) Return Bus Communication Error Count 返回总线通信 CRC 出错计数
08 13(0x0D) Return Bus Exception Error Count 返回总线异常计数
08 14(0x0E) Return Slave Message Count 返回从站设备接收的报文数量
08 15(0x0F) Return Slave No Response Count 返回从站设备没有返回响应的报文数量
08 16(0x10) Return Slave NAK Count
08 17(0x11) Return Slave Busy Count 返回从站设备响应忙的报文数量
08 18(0x12) Return Bus Character Overrun Count 返回总线字符超限的报文数量
08 19(0x13) Return IOP Overrun Count (884)
08 20(0x14) Clear Overrun Counter and Flag (884)
0x0B 获取通信事件计数器
  • 该功能码主要用于获取从设备通信计数器中的状态字和事件计数的值,不支持广播模式。
  • 可以通过在通信报文之前和之后读取通信事件计数值,来确定从设备是否正常处理报文。
  • 对于正常完成报文处理和传输的场合,事件计数器增加 1;而对于异常响应、轮询命令或读事件计数器(即 0x0B 功能码)的场合,则计数器不变。
  • 通过 0x08 诊断功能中的 0x01 子功能和 0x0A 子功能,可以复位事件寄存器。
0x0C 获取通信事件记录
  • 该功能码主要用于从从设备获取状态字、事件计数、报文计数以及事件字节字段。
  • 其中状态字和事件计数与功能码 0x0B 获取的值一致。
  • 报文计数器包含了加电重启、清除计数器之后的报文数量,报文计数与通过 0x08 诊断功能中的 0x0B 子功能码获取的值一致。
  • 事件字节字段包含 0~64 个字节,定义各种事件。
  • 正常情况下响应报文包括一个 2 Bytes 状态字字段、一个 2 Bytes 事件计数字段、一个 2 Bytes 消息计数字段以及 0~64 个字节的事件字段。
  • 由于事件字段是变长的,因此增加了一个 1 Byte 的数据长度字段,以方便读取响应数据。
0x0F 写多个线圈
  • 该功能码用于将连续的多个线圈(或离散输出)设置为 ON 或 OFF,支持广播模式。
  • 在广播模式下,所有从站设备的同一地址的值将被统一修改。
  • 消息帧中指定了需要变更的线圈起始地址和线圈数目。
  • 起始地址由 2 个字节构成,取值范围为 0x0000 到 0xFFFF。
  • 寄存器数量字段由 2 个字节构成,取值范围为 0x0001 到 0x07B0。
  • 数据字段中为逻辑 1 的位对应 ON,逻辑 0 的位对应 OFF。
0x10 写多个保持寄存器
  • 该功能码用于设置或写入从设备保持寄存器的多个连续的地址块(1~123个寄存器),支持广播模式。
  • 在广播模式下,所有从站设备的同一地址的值将被统一修改。
  • 消息帧中需要指定从设备地址以及需要变更的保持寄存器地址和数量。
  • 起始地址由 2 个字节构成,取值范围为 0x0000 到 0xFFFF。
  • 寄存器数量字段由 2 个字节构成,取值范围为 0x0001 到 0x007B(即十进制 1~123)。
  • 在实际开发中,该功能码常用于方便用户写入多字节类型的数据,例如浮点数值。因此,需要注意字节序问题。
0x11 报告从站 ID
  • 该功能码仅适用于串行链路,用于读取从站设备的 ID、类型描述、当前状态以及其他信息,不支持广播模式。
  • 查询报文中没有数据字段。
  • 响应消息的构成由从站设备决定。

总结

常用 Modbus 公共功能码下表所示。

ESP32 使用RS485模块实现Modbus通信(二),基于Modbus协议的工业自动化网络规范,modbus

其中,支持广播模式的功能码有:

  • 0x05 写单个线圈
  • 0x06 写单个保持寄存器
  • 0x0F 写多个线圈
  • 0x10 写多个保持寄存器

除了广播模式的报文以外,其他所有查询报文都希望能够获取一个正常的响应报文。如果一切正常,则从站设备将返回一个正常响应报文,该响应报文的功能码与请求报文的功能码一致。

另外,对于字操作的功能码,存在多字节存储的大小端问题,因此主站设备和从站设备必须保持一致的规则处理,约定 Modbus 传输中的数据字段的字节序。文章来源地址https://www.toymoban.com/news/detail-807869.html

到了这里,关于ESP32 使用RS485模块实现Modbus通信(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • # 项目一:‍‍‍STM32+串口DMA+RS485+MODBUS+传感器实现SO2的测试

    通过STM32控制传感器实现气体浓度的测量:RS485+MODBUS+串口DMA+定时器。 其中,USART2负责控制数据的发送和接受,USART3负责将询问帧、应答帧以及处理后数据打印出来,TIM1负责每隔1秒发送一次询问帧。 持续更新手中的项目(导师给的活)经验。。。 打工人加油🐱‍🚀🐱‍🚀

    2024年02月11日
    浏览(39)
  • 树莓派4B与智能插排通过RS485(modbus RTU协议)通信

    目标:使用树莓派4B与CANHAT扩展板读取智能插排测量的各项数据(RS485+modbus RTU),获取的数据上传到Hyperledger Fabric框架。 之前学习过了modbus RTU协议,在智能涡轮流量计的实验中应用过一次,这次用这个带485模块的智能插座再复习一次~ 实验材料: 树莓派4B/8G:  CANHAT扩展板:

    2024年02月01日
    浏览(79)
  • STM32:使用RS485和多摩川编码器通信

    本文主要讲使用STM32F767和绝对式多摩川TS5700N8501编码器通信的流程和注意事项。 TS5700N8501编码器推荐收发电路如下:  首先使用STM32CubeMX生成RS485驱动部分功能代码,注意该款编码器的波特率是2.5Mbps。   注意使能的GPIO可以使用其他管脚,我们的主控板使用的是PA8。前期可以这

    2024年02月11日
    浏览(79)
  • STM32CUBUMX配置RS485 modbus STM32(从机)亲测可用

    ———————————————————————————————————— ⏩ 大家好哇!我是小光,嵌入式爱好者,一个想要成为系统架构师的大三学生。 ⏩最近在开发一个STM32H723ZGT6的板子,使用STM32CUBEMX做了很多驱动,包括ADC、UART、RS485、EEPROM(IIC)、FLASH(SPI)、mod

    2024年02月14日
    浏览(195)
  • 02 | 基于RS485总线通信实现智能家居监测系统

    Proteus 75SP3 Setup.exe LXK Proteus 7.5 SP3 v2.1.2.exe(破解) 2.1.1 准备设备 PC机一台(作为上位机) 网关一个 RS-485通信节点三个(一个作为主机、两个作为从机) 空气质量一个(安装在从机1上) 可燃气体传感器一个(安装在从机2上) USB转485调试器一个 2.1.2 网络图 2.1.3 硬件连接方法

    2024年02月12日
    浏览(51)
  • STM32之485通信(RS485串口编程)

    目录 1.编程思路 2.代码    USART串口的库函数:    USART_:       AIRCR中断分组设置表:            通过485通信来实现MCU之间的通信,把接收到的数据通过串口助手显示在pc端。第一是对usart1,usart2进行初始化,Usart1负责与串口助手通信,Usart2,485负责进行MCU通信。第二是

    2024年01月18日
    浏览(54)
  • STM32RS485通信

    本章所要实现的功能是:通过操作 KEY_UP 键,STM32F1 的串口 2 将 PC 机发 送过来的数据原封不动的返回给 PC 机串口,同时 DS0 指示灯不断闪烁,提示系 统正常运行。程序框架如下: (1)初始化串口 2,并使能串口接收中断等 (2)编写串口 2 中断函数(将接收到的数据返回出去

    2024年02月14日
    浏览(50)
  • 在STM32上实现RS485通信

    RS485是一种常用的串行通信协议,通常用于远距离数据传输和多点通信。在STM32单片机上实现RS485通信,通常需要配置相关硬件和软件,包括串口外设、GPIO和通信协议。 本文将介绍如何在STM32上实现RS485通信,包括硬件连接、串口配置和通信协议,并给出相应的代码示例。 一、

    2024年01月16日
    浏览(45)
  • STM32 RS485通信的一种办法

    一、RS485        485通信,通信接口的远程重数据采集方法,在要求通信距离为几十米到上千米时,广泛采用RS-485串行总线标准。RS-485采用平衡发送和差分接受,因此具有抑制共模干扰的能力。 它的电气特性是逻辑“1”以两线间电压差+(2-6)V表示;逻辑“0”以两线间电压差

    2024年02月11日
    浏览(46)
  • STM32CubeIDE开发(二十二), stm32的RS485/232串口通信开发要点

    目录 一、stm32串口通信         1.1 硬件流控          1.2 软件流控         1.3 串口通信参数 二、新建RS485通信工程         2.1 项目实现背景信息         2.2 项目配置         2.3 代码实现    三、RS485驱动调用及测试         3.1 接口调用        3.2 编

    2024年01月20日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包