3、Modbus地址模型:线圈、离散输入、保持寄存器、输入寄存器的区别与用途
好,咱们今天聊点实在的。Modbus 协议里最绕人的,就是这四种地址类型。我刚入行那会儿,也经常搞混。说白了,它们就是四种不同的“数据箱子”,每个箱子装的东西不一样,用法也不一样。
你想想看,楼宇自控系统里,有开关、有传感器、有阀门、有变频器。这些设备的数据,有的只读,有的可读可写;有的只有 0 和 1,有的是一串数字。Modbus 就用这四种箱子,把数据分门别类装好。
3.1 四种地址类型速览
先给个总览,心里有个谱。
| 地址类型 | 数据宽度 | 读写属性 | 典型用途 | PLC 地址前缀 |
|---|---|---|---|---|
| 线圈 (Coil) | 1 位 (Bit) | 可读可写 | 开关控制、继电器输出 | 0x |
| 离散输入 (Discrete Input) | 1 位 (Bit) | 只读 | 按钮状态、限位开关 | 1x |
| 保持寄存器 (Holding Register) | 16 位 (Word) | 可读可写 | 设定值、PID 参数、运行频率 | 4x |
| 输入寄存器 (Input Register) | 16 位 (Word) | 只读 | 温度、压力、流量等测量值 | 3x |
这张表,我建议你存下来。项目上遇到不确定的,拿出来对照一下,基本不会错。
3.2 线圈 (Coil) —— 控制命令的“开关”
线圈,就是 0 和 1 的世界。它代表一个开关量输出。你可以读它,也可以写它。
用途:
- 控制风机启停
- 控制照明回路通断
- 控制阀门开/关
- 控制电加热器启停
实战经验:
我在一个大型商业项目中,遇到过一个问题。空调机组的启停控制,用的是线圈。但调试时发现,上位机下发“启动”指令后,设备没反应。查了半天,发现是 Modbus 地址写错了。PLC 里线圈地址是 00001,我写成了 00002。嗯,这里要注意,线圈地址通常从 0 或 1 开始,不同厂家定义不一样,一定要看设备手册。
重要提示: 线圈的读写操作,对应 Modbus 功能码是 01(读线圈)和 05(写单个线圈)、15(写多个线圈)。
3.3 离散输入 (Discrete Input) —— 状态的“眼睛”
离散输入,也是 0 和 1。但它只能读,不能写。它代表一个开关量输入。
用途:
- 读取手自动转换开关状态
- 读取风机运行/停止反馈
- 读取水流开关状态
- 读取门禁的开门/关门信号
避坑指南:
我曾经犯过一个低级错误。把离散输入当成线圈去写,结果设备一直报错。后来才明白,离散输入是设备“告诉”你它的状态,你不能去改它。就像你问一个人“你吃饭了吗?”,你不能替他回答“吃了”。
警告: 离散输入是只读的!如果你尝试用写功能码去操作它,Modbus 从站会返回异常码。别问我怎么知道的。
3.4 保持寄存器 (Holding Register) —— 参数的“调节旋钮”
保持寄存器,是 16 位的数据。你可以读它,也可以写它。它是 Modbus 里最灵活、最常用的地址类型。
用途:
- 设定温度值(如 25.5℃)
- 设定风机频率(如 35.0 Hz)
- 设定 PID 比例带、积分时间
- 读取设备运行累计时间
- 读取设备故障代码
实战经验:
我建议,凡是需要“设定”和“读取”的参数,优先用保持寄存器。比如变频器,你既要设定它的运行频率,又要读取它的当前频率。这两个都可以放在保持寄存器里。但要注意,有些设备会把“设定值”和“实际值”放在不同的寄存器里,一定要仔细看手册。
小技巧: 保持寄存器可以存储浮点数。通常用两个连续的寄存器(32 位)来存储一个浮点数。比如地址 40001 和 40002 组合成一个 32 位浮点数。但要注意字节顺序(Big-Endian 还是 Little-Endian),不同设备可能不一样。
3.5 输入寄存器 (Input Register) —— 测量值的“仪表盘”
输入寄存器,也是 16 位数据。但它只能读,不能写。它代表一个模拟量输入。
用途:
- 读取温度传感器测量值
- 读取压力传感器测量值
- 读取流量计瞬时流量
- 读取湿度传感器测量值
避坑指南:
我记得有一次,一个同事把温度传感器的值放在输入寄存器里,但上位机程序却用保持寄存器的功能码去读。结果读回来的数据全是 0。折腾了半天,才发现是功能码用错了。输入寄存器对应的是功能码 04(读输入寄存器),而保持寄存器对应的是功能码 03(读保持寄存器)。
重要提示: 输入寄存器和保持寄存器,虽然都是 16 位,但本质区别在于读写属性。输入寄存器是“只读”的,保持寄存器是“可读可写”的。这个区别,决定了它们在系统中的角色。
3.6 四种地址类型的对比总结
为了让你更直观地理解,我画个对比图(用文字描述)。
- 线圈:像家里的灯开关。你可以打开它,也可以关闭它,还能看到它当前是开还是关。
- 离散输入:像门上的门磁开关。你只能知道门是开着的还是关着的,但你没法通过它去关门。
- 保持寄存器:像空调的遥控器。你可以设定温度,也能看到当前设定值是多少。
- 输入寄存器:像室内的温度计。你只能看到当前温度是多少,但你没法通过它去改变温度。
这样一比喻,是不是清楚多了?
3.7 实战中的地址规划建议
在楼宇自控项目中,我习惯这样规划地址:
- 先看设备手册:确定设备支持哪些地址类型,以及每个地址的具体含义。
- 分类管理:把控制命令放在线圈,把状态反馈放在离散输入,把设定参数放在保持寄存器,把测量值放在输入寄存器。
- 预留地址:在规划地址表时,每个类型都预留一些空地址,方便后期扩展。
- 做好文档:把地址分配表整理清楚,标注每个地址的用途、数据类型、单位、量程等信息。这个文档,后期调试和维护时能救命。
警告: 不要随意修改设备手册中定义的只读地址!我曾经见过有人试图通过写保持寄存器来修改输入寄存器的值,结果导致设备死机。记住,输入寄存器是只读的,你只能“看”,不能“动”。
好了,关于 Modbus 的四种地址类型,就聊这么多。你只要记住它们的读写属性和典型用途,项目上基本不会出大问题。下一节,我们聊聊 Modbus 的功能码,看看怎么用这些地址去读写数据。