From c7176b93f244befa1acbf18f53d56007814cb812 Mon Sep 17 00:00:00 2001 From: wangfq Date: Thu, 30 Jul 2026 13:55:09 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20devlog=20=E2=80=94=20Modbus=20RTU=20V1.?= =?UTF-8?q?6=20=E7=BC=96=E7=A0=81=E5=AE=9E=E7=8E=B0=E6=9D=A1=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/devlog.md | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/docs/devlog.md b/docs/devlog.md index 2954e86..e9504f8 100644 --- a/docs/devlog.md +++ b/docs/devlog.md @@ -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 0x0000–0x000C + 全数据块 0x0100–0x0112 (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 状态 | + +### 全数据块 (0x0100–0x0112) + +``` +灵敏度 | 频率档 | 融合模式 | 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` 在每次吸合沿递增 (全数据块 0x010E–0x010F) + +### 改造现有文件 + +| 文件 | 变更 | +|------|------| +| `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_IRQHandler,Modbus 从共享 `_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 — 输出融合模式枚举再次重排:地感且光耦后移 ### 变更