docs: devlog — Modbus RTU V1.6 编码实现条目

This commit is contained in:
wangfq
2026-07-30 13:55:09 +08:00
parent e32f3892fe
commit c7176b93f2
+79
View File
@@ -4,6 +4,85 @@
---
## 2026-07-30 — Modbus RTU V1.6 私有协议编码实现
### 背景
根据 `docs/rs485-modbus-protocol.md` V1.6 规范,实现完整 Modbus RTU 从机协议(含主动上报私有扩展)。
与 700BS 协议共享 UART0 物理层,通过 `g_fm_700bs_disable` 互斥切换。
### 新增文件
| 文件 | 行数 | 说明 |
|------|------|------|
| `APP/include/rs485_modbus.h` | 52 | API + 协议常量宏 (MB_IR_FULL_BLOCK_START/COUNT, MB_HR_AUTO_RPT_ENABLE/ACTIVE_THRESHOLD, 上报间隔) |
| `APP/rs485_modbus.c` | 815 | 完整 Modbus 实现: CRC16 查表 + 6 个 FC 处理函数 + 全数据块组装 + 主动上报调度 + 车间距/通过时间测量 |
### 实现的功能码
| FC | 功能 | 关键细节 |
|----|------|---------|
| 0x02 | 读离散输入 | 9-bit 位图, GPIOB_ReadPortPin 直读光耦 |
| 0x03 | 读保持寄存器 | 含 HR 0x0010(主动上报使能) 和 0x0011(活动阈值) |
| 0x04 | 读输入寄存器 | 基础 IR 0x00000x000C + 全数据块 0x01000x0112 (19 reg = 38B) |
| 0x06 | 写单寄存器 | 值域校验 + 只读拦截 + 连锁写入: Fusion Mode→direction_mode, Hold Time→g_hold_time, Freq Level→loopFreq_Level |
| 0x10 | 批量写寄存器 | 逐寄存器同 FC 0x06 逻辑 |
| 0x11 | Report Slave ID | "DLD154Pro\0" + loop1_LOOP_OK 状态 |
### 全数据块 (0x01000x0112)
```
灵敏度 | 频率档 | 融合模式 | car_state | 线圈状态(bit0=断开/bit1=稳定) | 光耦状态
频率Hz(32b) | CAPVD(32b) | Variation(32b signed)
断开累计(32b) | 继电器吸合累计(32b)
Time Type(0=间隙/1=通过/0xFFFF=无效) | 时间值10ms(32b)
```
- Variation = `loop1_CAPVD loop1_Origin`,实时计算
- 频率 = `FREQ_SYS * LPCNT / CAPVD + 360`,与 700BS 一致
- 光耦 = `GPIOB_ReadPortPin(Pin_10) == 0`,直读硬件
### 主动上报 3 级速率调度
| 状态 | 条件 | 间隔 | 迟滞 |
|------|------|------|------|
| 事件 | 继电器翻转 (relay1_state 边沿) | 立即 | — |
| 活动 | \|Variation\| ≥ 阈值 (HR 0x0011, 默认 10) | 150ms (30 tick) | — |
| 空闲 | \|Variation\| < 阈值 | 800ms (160 tick) | 连续 2 次低于阈值才降速 |
- 帧格式复用 FC 0x04 响应,与轮询完全一致
- 上报前先调 `update_misc_time()` 更新 gap/pass time
### 车间距 / 通过时间
- 单位: 10ms (`mstick()/2`)
- 继电器 0→1 吸合沿 → `_misc_time_value = now _last_relay_off_10ms`, `_misc_time_type = 0`
- 继电器 1→0 释放沿 → `_misc_time_value = now _last_relay_on_10ms`, `_misc_time_type = 1`
- `_relay_engage_cnt` 在每次吸合沿递增 (全数据块 0x010E0x010F)
### 改造现有文件
| 文件 | 变更 |
|------|------|
| `rs485_700bs.h` | +`rs485_send()` 声明; +`extern _rx_buf/_rx_len/_rx_last_tick` |
| `rs485_700bs.c` | `_rx_buf`/`_rx_len`/`_rx_last_tick``static`; `rs485_send``static` |
| `peripheral_main.c` | +`#include "rs485_modbus.h"`; `gpio_uart_init``modbus_init()`; `Main_Circulation``g_fm_700bs_disable` 分派 700BS/Modbus |
### 关键设计决策
- **与 700BS 共享 ISR**: 不创建第二个 UART0_IRQHandlerModbus 从共享 `_rx_buf` 读取
- **帧超时判定**: `mstick() _rx_last_tick ≥ 2` (10ms), 对齐 9600 的 t3.5≈4ms
- **写穿透**: Holding Register 写入后立即同步到 RAM 全局变量,不等待 flash 持久化 (flash 写入由调用方处理)
- **CRC 错误静默**: 符合 Modbus 标准——CRC 不匹配时不回应
### 影响
- RS485 物理层零改动,Modbus/700BS 通过 BLE 小程序切换
- 主动上报默认关闭 (`_auto_rpt_enable = 0`),需通过 HR 0x0010 使能
- Holding Register 写操作不写 flash,若需持久化需额外调用 `write_cfg_to_store`
---
## 2026-07-30 — 输出融合模式枚举再次重排:地感且光耦后移
### 变更