STM32从零到量产开发:四路继电器工业控制模块开发— Modbus RTU 通讯协议设计

STM32从零到量产开发:四路继电器工业控制模块开发--- Modbus RTU 通讯协议设计

文档版本:v1.0.0(对应固件 v1.0.0 / 设备类型码 0x0002)

适用产品:P02_Relay_Controller_4Channels Relay Industrial Control Module

本文档面向主站/网关开发工程师,描述设备的 Modbus RTU 从站协议。所有示例帧的 CRC16 均已用脚本实算(多项式 0x8005,初值 0xFFFF,小端)。


1. 物理层与链路层

项目 说明
物理接口 RS485(A/B 差分),半双工
默认波特率 9600 bps(见 §6 波特率索引表)
数据位 / 停止位 / 校验 8 / 1 / 无(8N1)
从站地址范围 1 ~ 247(0 为广播地址,用于写指令,不回响应)
帧间隔(T3.5) 3.5 个字符时间(9600bps 下约 3.6ms,建议 ≥ 5ms 余量)
字节超时 1.5 个字符时间(约 1.5ms @9600)

接线:RS485_A 接总线 A,RS485_B 接总线 B;总线两端需加 120Ω 终端电阻。设备由外部提供隔离电源。


2. 帧格式(Modbus RTU)

复制代码
[ 从站地址 ][ 功能码 ][ 数据域 ][ CRC 低字节 ][ CRC 高字节 ]
   1 字节      1 字节    N 字节     1 字节        1 字节
  • 字节序 :地址、数据域中的多字节数值(寄存器值、寄存器地址、数量)均为大端(MSB 在前)
  • CRC :Modbus CRC16(多项式 0x8005,初值 0xFFFF,小端,即低字节先发)。
  • 广播:地址=0 时设备执行写操作但不回任何响应;读操作不支持广播。

3. 支持的功能码

功能码 名称 访问对象 说明
0x01 读线圈 继电器 读取 RELAY1~4 状态
0x02 读离散输入 DI 读取 DI1~4 状态
0x03 读保持寄存器 通信参数 读从站地址/波特率/故障安全配置等
0x04 读输入寄存器 诊断/运行信息 运行时间、计数、固件版本、设备类型、SN 等
0x05 写单个线圈 继电器 单个继电器开/断
0x06 写单个保持寄存器 通信参数 改地址/波特率/故障安全
0x0F 写多个线圈 继电器 批量控制 4 路继电器
0x10 写多个保持寄存器 通信参数 批量写配置(本设备常用单寄存器,0x06 即可覆盖)
0x11 上报从站标识(Report Slave ID) 设备信息 返回固件版本、设备类型码、运行状态

4. 异常码

异常码 含义 触发场景
0x01 非法功能码 收到本设备不支持的功能码
0x02 非法数据地址 寄存器地址/范围越界
0x03 非法数据值 数值非法(如从站地址=0、波特率索引越界、故障安全秒=0 且使能=1 等)
0x06 设备忙 正在处理上一条请求(极少触发)

异常响应格式:[地址][功能码 | 0x80][异常码][CRC低][CRC高]


5. 寄存器映射总览

对象 地址范围 读写 内容
线圈 Coils 0x0000 ~ 0x0003 读/写 RELAY1~4(0=断开, 1=吸合)
离散输入 Discrete Inputs 0x0000 ~ 0x0003 只读 DI1~4(0=断开, 1=闭合)
输入寄存器 Input Registers 0x0000 ~ 0x000F 只读 运行秒/复位/帧/CRC/异常/运行小时/寿命/固件/类型/SN/故障安全
保持寄存器 Holding Registers 0x0000 ~ 0x0004 读/写 从站地址/波特率/通信使能/故障安全使能/超时秒

说明:线圈、离散输入、输入寄存器、保持寄存器是 Modbus 的四个独立地址空间,各自从 0x0000 编号,互不相干。


6. 通信参数(保持寄存器 0x0000~0x0004)

地址 名称 读写 范围/取值 说明
0x0000 从站地址 SlaveAddr 读/写 1~247 掉电保存,重启后/下次回复后生效
0x0001 波特率索引 BaudIndex 读/写 0~4 见下表,掉电保存,回复后切换波特率
0x0002 通信使能 LinkEnable 读/写 0 / 1 0=静默模式(不回复任何帧);1=正常回复
0x0003 故障安全使能 FailSafeEn 读/写 0 / 1 1=开启通信故障安全(默认 1)
0x0004 故障安全超时 FailSafeSec 读/写 0~255 秒;0 表示禁用(需配合 FailSafeEn=0)

波特率索引表(P02 专用):

索引 波特率
0 9600(出厂默认)
1 19200
2 38400
3 57600
4 115200

⚠️ 系列差异提醒:同系列 P03 模块的波特率索引表不同(额外支持 4800,且 9600 在索引 1)。若网关需同时接入 P02/P03,请按本表各自区分(详见 §13)。

出厂默认值:SlaveAddr=1,BaudIndex=0(9600),LinkEnable=1,FailSafeEn=1,FailSafeSec=10。


7. 线圈 --- 继电器(0x0000~0x0003)

线圈地址 名称 写值含义
0x0000 bit0 RELAY1 0xFF00=吸合,0x0000=断开
0x0001 bit1 RELAY2 同上
0x0002 bit2 RELAY3 同上
0x0003 bit3 RELAY4 同上
  • 继电器为低电平有效驱动,线圈写 1(吸合)= 输出闭合。
  • 写保持寄存器 FailSafeSec 触发故障安全时,所有继电器强制断开(安全态)。

8. 离散输入 --- DI(0x0000~0x0003,只读)

离散地址 名称 含义
0x0000 bit0 DI1 外部接点闭合=1,断开=0
0x0001 bit1 DI2 同上
0x0002 bit2 DI3 同上
0x0003 bit3 DI4 同上

读响应中首字节的低 4 位为 DI1~DI4 状态。


9. 输入寄存器(0x0000~0x000F,只读)

地址 名称 位宽 含义
0x0000 运行秒数 Uptime 16 累计运行秒(16 位回绕)
0x0001 复位次数 ResetCount 16 累计上电复位次数
0x0002 有效帧计数 FrameCount 16 收到合法 Modbus 帧数
0x0003 CRC 错误计数 CrcErrCount 16 CRC 校验失败计数
0x0004 异常响应计数 ExcepCount 16 回复异常帧累计次数(通信质量评估)
0x0005 运行小时 RunHours 16 累计运行小时
0x0006 继电器1 动作次数 16 寿命计数(翻转时 +1)
0x0007 继电器2 动作次数 16 同上
0x0008 继电器3 动作次数 16 同上
0x0009 继电器4 动作次数 16 同上
0x000A 寿命告警位图 LifeAlarm 16 bit0~3 对应 RELAY1~4 寿命越限(默认阈值 100000 次)
0x000B 固件版本 FwVer 16 0xMMmm,如 0x0100 = v1.0
0x000C 设备类型码 DevType 16 0x0002(P02 标识)
0x000D 序列号低16位 SN_Low 16 取自芯片 UID(全球唯一)
0x000E 序列号高16位 SN_High 16 取自芯片 UID
0x000F 故障安全态 FailSafe 16 bit0=使能,bit8=当前是否触发(1=已切安全态)

10. 故障安全机制(#1 量产增强)

  • 设备默认开启通信故障安全(FailSafeEn=1,超时 10s)。
  • 主站连续 FailSafeSec 秒未发来任何有效 Modbus 帧 → 设备自动把所有继电器切到安全态(断开),防止主站死机导致失控。
  • 任意一帧合法 Modbus 帧到达 → 立即清除故障安全态,恢复由主站控制。
  • 由主站重新下发控制指令即可恢复继电器状态;无需人工复位。

设计原则:心跳/保活必须用只读帧(如 FC01 读线圈、FC03 读保持、FC04 读输入),绝不能拿控制帧(如 FC0F 全开)当心跳------控制帧只改变状态,不能做保活。


11. 心跳 / 保活 SOP(双视角)

主站视角: 以小于 FailSafeSec(默认 10s)的周期,周期性发送只读轮询帧(推荐 FC04 读输入寄存器,或 FC01 读线圈)维持链路活跃。例如每 5s 读一次 0x0000 运行秒数。

设备视角: 收到任意合法帧即清零故障安全计时器;若计时超过阈值则进入安全态并置位 0x000F 的 bit8。


12. 设备识别(FC17 Report Slave ID)

主站发送 01 11 即可获取设备标识。P02 响应含固件版本与设备类型码 0x0002。

示例(见 §14)可验证设备类型码,主站据此加载对应的寄存器字典。


13. 系列关系说明

P02 与 P03 属于同一产品系列 :同芯片(STM32F103RCT6)、同 Modbus 协议框架(9 功能码、异常码 01/02/03/06、大端数据+小端 CRC、故障安全默认开)。两者通信参数保持寄存器 0x0000~0x0004 含义完全对齐,主站"设地址/设波特率/开关故障安全"的帧格式一致。

差异(主站须注意):

项目 P02(本文档) P03(模拟量模块)
设备类型码 0x0002 0x0003
波特率索引表 0=9600...4=115200 0=4800,1=9600...5=115200
业务寄存器 继电器/DI 相关 ADC/DAC/校准/报警相关
LinkEnable 可写(0=静默) 只读(恒为 1,无静默模式)

接入网关时,建议先用 FC17 读取设备类型码,再按产品加载寄存器字典。


14. 通信示例(CRC 已实算)

以下主站地址均为 1(0x01)。CRC 以「低字节 高字节」给出。

14.1 读线圈(FC01)--- 读 4 路继电器状态

复制代码
请求: 01 01 00 00 00 04  3D C9
响应: 01 01 01 00         51 88     (00 = 4 路全断)

14.2 写单线圈(FC05)--- 继电器1 吸合

复制代码
请求: 01 05 00 00 FF 00  8C 3A
响应: 01 05 00 00 FF 00  8C 3A     (原样回显)

14.3 写多线圈(FC0F)--- 4 路全开

复制代码
请求: 01 0F 00 00 00 04 01 0F  7E 92
响应: 01 0F 00 00 00 04            (原样回显起始/数量)

14.4 读保持寄存器(FC03)--- 读从站地址

复制代码
请求: 01 03 00 00 00 01  84 0A
响应: 01 03 02 00 01     79 84     (00 01 = 地址 1)

14.5 写保持寄存器(FC06)--- 改波特率为 115200(索引 4)

复制代码
请求: 01 06 00 01 00 04  D9 C9
响应: 01 06 00 01 00 04  D9 C9     (原样回显,之后设备切换 115200)

14.6 读离散输入(FC02)--- 读 4 路 DI

复制代码
请求: 01 02 00 00 00 04  79 C9
响应: 01 02 01 00         A1 88     (00 = 无 DI 闭合)

14.7 读输入寄存器(FC04)--- 读运行小时

复制代码
请求: 01 04 00 05 00 01  21 CB
响应: 01 04 02 00 05     79 33     (00 05 = 5 小时)

14.8 上报从站标识(FC17)

复制代码
请求: 01 11             C0 2C
响应: 含设备类型码 0x0002 + 运行状态(详见固件实现;可用 FC04 单独读 0x000B/0x000C 获取版本与类型)

14.9 异常响应示例(FC01 非法功能码)

复制代码
请求: 01 08 ...                  (假设主站发了一个不支持的功能码 0x08)
响应: 01 81 01         81 90     (功能码|0x80=0x81, 异常码 0x01=非法功能)

15. 出厂默认参数速查

参数
从站地址 1
波特率 9600(索引 0)
通信使能 1(正常回复)
故障安全 开启,超时 10s
继电器上电态 全断(安全态)
设备类型码 0x0002
固件版本 v1.0.0(0x0100)

本文档依据 P02 工程源码(modbus_rtu.c / flash_param.c / bsp_rs485.c)核对编写,示例帧 CRC 经脚本验证。

相关推荐
Zyed1 小时前
[FreeRTOS]Day8-Part1队列+红外遥控器玩游戏+旋转编码器玩游戏
stm32·单片机·玩游戏
GeekArch16 小时前
第28讲:避坑——AI堆栈分配错误、栈溢出BUG
c语言·人工智能·stm32·mcu·学习·bug
wuyk55519 小时前
59.嵌入式C语言高级宏定义实战:多行宏、字符串化与符号拼接
c语言·开发语言·stm32·单片机·嵌入式硬件·物联网·51单片机
piaoyiren19 小时前
STM32 综合温控风扇控制系统
stm32·单片机·嵌入式硬件·oled·lcd1602·hc-05蓝牙
亿道电子Emdoor1 天前
【Arm】解决Keil MDK无法查看外设寄存器的问题
stm32·单片机·嵌入式硬件
BW.SU1 天前
瑞佑RUI--工业UI,拖拽即成
stm32·单片机·51单片机·gui·人机界面·单片机可视化设计
十月的皮皮1 天前
STM32从零到量产开发:四路继电器工业控制模块开发原理小灶 · 合集
stm32·单片机·嵌入式硬件·stm32cubemx·hal库
小羊先生car1 天前
F429-SysTick(2026/7/22)
stm32·单片机·嵌入式硬件
WWJA王文举1 天前
单片机参数如何掉电保存:Flash、EEPROM和配置存储完整设计
数据库·stm32·mongodb·c#