SSPC-Tester/Docs/Modbus接口规范/Modbus接口规范.md
2026-06-30 12:10:29 +08:00

252 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Modbus 接口规范
## 1. 文档用途
本文档用于指导主项目接入已完成现场实测的 24 路继电器、电压采集和电流采集设备。
配套文件:
- `device-profile.json`:设备协议与通道映射的唯一权威配置。
- `appsettings.Modbus.example.json`:主项目默认配置字段示例。
- `接入验收清单.md`:开发完成后的测试和验收要求。
主项目实现时必须读取配置,不得在业务代码中硬编码从站地址、线圈、寄存器、量程、公式或通道映射。
## 2. 实测资料与结论
本规范依据以下现场结果整理:
- `结果_Modbus-接口-电流-电压对应表.txt`:逐个物理插位手动测量得到的采集页通道对应关系。
- `结果_modbus-tuner-20260618-131814.json`:调试程序于 2026-06-18 导出的已调通通讯参数。
编号含义必须严格区分:
| 名称 | 含义 |
|---|---|
| `physicalSlot` | 机器上的物理接口位置,也是主项目业务层唯一使用的通道号,范围 124 |
| `relayChannel` | 调试程序继电器控制页按钮号;实测与物理插位一致 |
| `sourceDisplayChannel` | 调试程序采集页面上出现读数的通道号,仅保留作实测追溯 |
| `registerOffset` | 在本次 24 寄存器回包数据区中的零基位置,主项目实际解析使用 |
主项目不得把 `sourceDisplayChannel` 当作物理插位,也不得直接用它计算字节偏移。
## 3. 总线与串口参数
所有模块共用一条 RS485 总线。
| 参数 | 实测值 |
|---|---|
| 协议 | Modbus RTU |
| 波特率 | 9600 |
| 数据位 | 8 |
| 校验 | None |
| 停止位 | 1 |
| 读取超时 | 500 ms |
| 失败重试 | 2 次 |
| CRC | CRC16-Modbus |
| CRC 字节序 | 低字节在前 |
| 地址、数量和寄存器数据 | 高字节在前 |
现场调试使用过 `COM9`,但 COM 号属于计算机本地设置。主项目应允许用户选择和保存,不得把 `COM9` 固定为设备协议的一部分。
同一串口的请求必须串行执行。不得让继电器写入、电压读取和电流读取同时向串口写帧。
## 4. 模块地址
| 模块 | 从站地址 |
|---|---:|
| 继电器板 1负责物理插位 18 | 1 |
| 继电器板 2负责物理插位 916 | 2 |
| 继电器板 3负责物理插位 1724 | 3 |
| 24 路电压采集模块 | 4 |
| 24 路电流采集模块 | 5 |
## 5. 继电器控制
使用功能码 `0x05` 写单个线圈。
- 开:`0xFF00`
- 关:`0x0000`
- 正常响应应回显请求中的从站、功能码、线圈地址和值。
- 响应必须检查长度、从站、功能码、回显内容和 CRC。
主项目业务接口建议:
```text
SetRelayAsync(int physicalSlot, bool isOn)
```
处理流程:
1. 校验 `physicalSlot` 为 124。
2.`device-profile.json``channels` 查找该物理插位。
3. 取得 `relay.slave``relay.coil`
4. 构造并发送 `0x05` 帧。
5. 验证回显后才更新业务状态。
不要在未确认当前硬件是否允许的情况下自动全开 24 路。
## 6. 电压采集
实测配置:
| 参数 | 值 |
|---|---|
| 从站 | 4 |
| 功能码 | `0x03` |
| 起始寄存器 | 0 |
| 寄存器数量 | 24 |
| 量程 | 100 V |
| 解析公式 | B |
| 公式 | `实际电压 = DATA / 100` |
| DATA 类型 | `UInt16` |
| 每通道字节数 | 2 |
| 数据字节序 | Big-Endian |
请求主体:
```text
04 03 00 00 00 18
```
追加 CRC16-Modbus 后发送。正常响应共 53 字节:
```text
[从站1][功能码1][字节数0x30][48字节数据][CRC2]
```
## 7. 电流采集
实测配置:
| 参数 | 值 |
|---|---|
| 从站 | 5 |
| 功能码 | `0x03` |
| 起始寄存器 | 0 |
| 寄存器数量 | 24 |
| 量程 | 60 A |
| 解析公式 | A |
| 公式 | `实际电流 = DATA / 10000 × 60` |
| DATA 类型 | `Int16` |
| 每通道字节数 | 2 |
| 数据字节序 | Big-Endian |
请求主体:
```text
05 03 00 00 00 18
```
这里的“带符号”按现场导出配置解释为:读取寄存器 023并将每个 16 位原始值按二进制补码转换为 `Int16`。主项目不得自行把起始寄存器改成 24也不得在映射地址上额外加 24。如后续更换硬件或重新标定应修改配置版本并重新验收。
## 8. 采集回包解析
电压和电流共用以下流程:
1. 检查响应最小长度。
2. 检查响应从站等于配置从站。
3. 检查功能码。若最高位为 1按 Modbus 异常响应处理。
4. 检查字节数为 `registerCount × registerBytes`,当前应为 48。
5. 验证 CRC16-Modbus。
6. 对每个物理插位读取对应的 `registerOffset`
7. 字节位置为:
```text
position = dataStartOffset + registerOffset × channelBytes
```
当前 `dataStartOffset=3``channelBytes=2`。
8. 按 Big-Endian 合成原始 16 位值。
9. 根据 `signed` 转换为 `UInt16``Int16`
10. 根据 `formula``range` 换算工程值。
公式定义:
```text
A: value = DATA / 10000.0 × range
B: value = DATA / range
```
## 9. 统一业务接口
主项目业务层只允许使用物理插位 124建议公开以下抽象
```text
ConnectAsync()
DisconnectAsync()
SetRelayAsync(int physicalSlot, bool isOn)
ReadAllVoltagesAsync()
ReadAllCurrentsAsync()
ReadMeasurementsAsync()
```
一次测量结果建议包含:
```text
PhysicalSlot
Voltage
Current
VoltageRaw
CurrentRaw
Timestamp
VoltageQuality
CurrentQuality
```
`ReadMeasurementsAsync()` 应分别完成一次电压整帧读取和一次电流整帧读取,再按 `physicalSlot` 合并。不要为每个物理插位单独读取一次寄存器;每种采集模块一次读取 24 个寄存器即可。
## 10. 配置加载与校验
程序启动时必须校验:
- `schemaVersion` 是程序支持的版本。
- 物理插位恰好覆盖 124不重复、不缺失。
- 继电器从站和线圈组合不重复。
- 电压、电流的 `registerOffset` 均在 `0registerCount-1`
- 每类采集映射不得出现重复的 `registerOffset`
- 从站地址范围为 1247。
- `registerBytes=2`、`channelBytes=2`。
- 公式只能是 `A``B`
- 字节序和 CRC 类型为程序支持值。
配置错误时应阻止通讯并给出具体字段,不要静默使用代码默认值。
## 11. 超时、重试和线程规则
- 一次请求从发送到收到完整响应视为一个事务。
- 失败后最多重试配置中的次数;当前为 2 次,即最多发送 3 次。
- CRC 错误、响应超时、从站错误、功能码错误和响应长度错误都应记录原始 HEX。
- 重试前应清理串口输入缓冲区,避免残帧与下一帧拼接。
- 串口操作使用互斥锁或单消费者队列串行化。
- 断开和应用退出时安全关闭串口。
## 12. 主项目配置建议
建议将机器本地参数放在主项目配置,将设备协议和映射放在独立配置:
```text
主项目配置
└─ Modbus
├─ Enabled
├─ PortName
├─ DeviceProfilePath
└─ PollIntervalMs
device-profile.json
├─ 串口通讯默认参数
├─ Modbus 帧规则
├─ 模块协议
└─ 24 路权威映射
```
`device-profile.json` 应随主程序发布并复制到输出目录。主项目可以提供配置界面修改 COM 口,但协议和通道映射只应由经过授权的维护流程更新。
## 13. AI 编程强制要求
将本目录交给主项目 AI 时,应附加以下要求:
> 严格按《Modbus接口规范.md》和 `device-profile.json` 实现。业务层统一使用 `physicalSlot` 124。所有从站、线圈、寄存器、量程、公式及映射从配置读取不得硬编码。`sourceDisplayChannel` 仅用于追溯现场实测不参与解析寻址。实现配置启动校验、串口事务串行化、CRC及响应完整校验并按《接入验收清单.md》完成测试。