diff --git a/BLE/DLD154Pro_Peripheral_28K/APP/rs485_700bs.c b/BLE/DLD154Pro_Peripheral_28K/APP/rs485_700bs.c index 1056835..9fc8267 100644 --- a/BLE/DLD154Pro_Peripheral_28K/APP/rs485_700bs.c +++ b/BLE/DLD154Pro_Peripheral_28K/APP/rs485_700bs.c @@ -50,7 +50,7 @@ void rs485_init(void) GPIOA_ModeCfg(GPIO_Pin_13, GPIO_ModeOut_PP_5mA); /* UART0 外设: 9600 8N1 */ - UART0_BaudRateCfg(RS485_BAUD); + UART0_BaudRateCfg(g_storage_uart_baud); /* 使用 flash 存储的波特率 (700BS=9600, Modbus=115200) */ R8_UART0_LCR = 0x03; // 8 数据位, 1 停止位, 无校验 R8_UART0_MCR = 0x04; // RE=0 进入接收模式 diff --git a/BLE/DLD154Pro_Peripheral_28K/APP/rs485_modbus.c b/BLE/DLD154Pro_Peripheral_28K/APP/rs485_modbus.c index aa9a222..3a290ee 100644 --- a/BLE/DLD154Pro_Peripheral_28K/APP/rs485_modbus.c +++ b/BLE/DLD154Pro_Peripheral_28K/APP/rs485_modbus.c @@ -779,7 +779,8 @@ void modbus_init(void) void modbus_poll(void) { - /*=== 帧接收 ===*/\n if (_rx_len > 0) { + /*=== 帧接收 ===*/ + if (_rx_len > 0) { uint32_t now = mstick(); if (now - _rx_last_tick >= MB_FRAME_TIMEOUT_TICK) { /* 帧超时 → 处理完整帧 */ @@ -814,5 +815,6 @@ void modbus_poll(void) } } - /*=== 主动上报调度 ===*/\n modbus_report_schedule(); + /*=== 主动上报调度 ===*/ + modbus_report_schedule(); } diff --git a/DLD154Tool/main.py b/DLD154Tool/main.py index 43b58f9..ccf0d56 100644 --- a/DLD154Tool/main.py +++ b/DLD154Tool/main.py @@ -148,7 +148,7 @@ class SerialTab(QWidget): self._cmb_baud = QComboBox() self._cmb_baud.addItems(["9600", "19200", "38400", "57600", "115200"]) - self._cmb_baud.setCurrentText("9600") + self._cmb_baud.setCurrentText("115200") fl.addRow("波特率:", self._cmb_baud) self._spn_addr = QSpinBox() diff --git a/docs/modbus-active-report-analysis.md b/docs/modbus-active-report-analysis.md index fc377a7..841dbca 100644 --- a/docs/modbus-active-report-analysis.md +++ b/docs/modbus-active-report-analysis.md @@ -1,6 +1,7 @@ # DLD154Pro Modbus 主动上报 — MCU 资源占用分析 > CH591R RISC-V @60MHz | 18KB RAM | BLE + 单路线圈 + RS485 +> 700BS 默认 9600 baud | Modbus 默认 115200 baud --- @@ -69,53 +70,53 @@ for (i = 0; i < len; i++) { UART0 TX FIFO 容量 8 字节,但代码**不等 FIFO 有空间就写满 8 字节**,而是每写 1 字节就等 FIFO 全空。这意味着每字节都经历完整的 1.04ms 传输等待。 -| 帧类型 | 字节数 | 传输时间 @9600 | 传输时间 @19200 | 传输时间 @38400 | -|--------|--------|---------------|-----------------|-----------------| -| 全数据块上报 (FC 0x04) | 43B | **44.8 ms** | 22.4 ms | 11.2 ms | -| 异常响应 | 5B | 5.2 ms | 2.6 ms | 1.3 ms | -| 写回显 | 8B | 8.3 ms | 4.2 ms | 2.1 ms | +| 帧类型 | 字节数 | 传输时间 @9600 (700BS) | 传输时间 @115200 (Modbus) | +|--------|--------|----------------------|--------------------------| +| 全数据块上报 (FC 0x04) | 43B | 44.8 ms | **4.3 ms** | +| 异常响应 | 5B | 5.2 ms | 0.5 ms | +| 写回显 | 8B | 8.3 ms | 0.8 ms | ### 2.4 主动上报各速率下的 CPU 占用 -**150ms 活动间隔 (最坏情况)**: +**150ms 活动间隔**: ``` 每 150ms 窗口: - TX 阻塞 44.8 ms ← rs485_send(43B) - 主循环正常计算 ~50 ms ← 150 - 44.8 - 余量 - 可用于 BLE/算法 ~55 ms ← 剩余预算 + TX 阻塞 4.3 ms ← rs485_send(43B) @115200 + 主循环正常计算 ~50 ms ← 算法 + BLE + 光耦 + 剩余预算 ~95 ms -主循环 CPU 占比: (44.8 + 50) / 150 = 63% -其中 TX 阻塞占比: 44.8 / 150 = 30% +主循环 CPU 占比: (4.3 + 50) / 150 = 36% +其中 TX 阻塞占比: 4.3 / 150 = 2.9% ``` **800ms 空闲间隔**: ``` -TX 阻塞占比: 44.8 / 800 = 5.6% +TX 阻塞占比: 4.3 / 800 = 0.5% 主循环 CPU 占比: ~30% ``` **继电器翻转事件 (立即上报)**: ``` -TX 阻塞 44.8ms,单次冲击。翻转频率低(最多每秒数次进出车),不构成持续负载。 +TX 阻塞 4.3ms,单次冲击可忽略。 ``` --- ## 3. 关键风险点 -### 3.1 ⚠️ 主循环阻塞 45ms 期间的影响 +### 3.1 ✅ 主循环阻塞 4.3ms 期间的影响 (@115200) -`rs485_send` 阻塞期间,以下主循环任务被暂停: +`rs485_send` 阻塞仅 4.3ms,不到半个 CAP_OK 测量窗 (8.74ms)。 | 任务 | 影响 | 严重程度 | |------|------|---------| -| **cjq_srv** (线圈算法) | CAP_OK 积压 ~5 次 (45ms ÷ 8.74ms)。恢复后主循环逐次消化,算法不丢数据,但响应延迟 +45ms | 🟡 轻微 | -| **opt_input_poll** (光耦) | 防抖采样暂停 45ms。光耦输入若在此期间变高又变低,可能丢失 <45ms 的短脉冲 | 🟡 轻微 | -| **TMOS_SystemProcess** (BLE) | BLE 协议栈调度延迟 45ms。连接监控超时通常 ≥2s,**不受影响** | 🟢 安全 | -| **modbus_poll** (RX) | 主机若在 TX 期间发来命令,UART ISR 正常收进缓冲,TX 结束后才处理 → 响应延迟 +45ms | 🟡 轻微 | +| **cjq_srv** (线圈算法) | CAP_OK 最多积压 1 次。无实质延迟 | 🟢 无影响 | +| **opt_input_poll** (光耦) | 防抖采样暂停 4.3ms。光耦 3 样本防抖窗 ~30ms,不受影响 | 🟢 无影响 | +| **TMOS_SystemProcess** (BLE) | 延迟 4.3ms,BLE 连接超时 ≥2s | 🟢 无影响 | +| **modbus_poll** (RX) | 主机命令响应延迟 +4.3ms | 🟢 无影响 | ### 3.2 ✅ 不受影响的部分 @@ -128,7 +129,7 @@ TX 阻塞 44.8ms,单次冲击。翻转频率低(最多每秒数次进出车 ### 3.3 🟢 结论 -**@9600 波特率,150ms 主动上报可行。** 30% TX 阻塞是临界值——主循环仍有 ~55ms/150ms 的余量处理线圈算法和 BLE。不会丢检测事件,不会断蓝牙,继电器输出不受影响。 +**@115200 波特率,主动上报对系统几乎无影响。** TX 阻塞仅 4.3ms(不到半个测量窗),主循环 CPU 占比从 30% 小幅升至 36%,余量充裕。不会丢检测事件,不会断蓝牙,继电器输出不受影响。 --- @@ -192,16 +193,17 @@ CH591R Flash: 256KB (应用区 28KB 或 18KB,取决于 OTA 配置)。增量约 ## 6. 优化建议 -### 6.1 提高波特率 (影响最大) +### 6.1 波特率选择 (已解决) -| 波特率 | TX 阻塞 (43B) | 活动态 CPU 占比 | 改善 | -|--------|--------------|----------------|------| -| 9600 | 44.8 ms | 30% | 基线 | -| **19200** | **22.4 ms** | **15%** | **↓50%** | -| 38400 | 11.2 ms | 7.5% | ↓75% | -| 115200 | 3.7 ms | 2.5% | ↓92% | +Modbus 默认使用 **115200 baud**,TX 阻塞仅 4.3ms(2.9% CPU),不需要进一步优化。 -> **建议**: 开启主动上报时,波特率至少用 19200。CH591R UART0 支持到 6 Mbps,硬件无瓶颈。 +| 波特率 | TX 阻塞 (43B) | 活动态 CPU 占比 | +|--------|--------------|----------------| +| 9600 | 44.8 ms | 30% | +| 19200 | 22.4 ms | 15% | +| **115200** | **4.3 ms** | **2.9%** ← Modbus 默认 | + +> 700BS 保持 9600(协议兼容;心跳帧仅 9B,TX 阻塞 9.4ms,也不成问题)。 ### 6.2 优化 TX FIFO 利用率 (代码级) @@ -239,10 +241,9 @@ void rs485_send_fast(const uint8_t *data, uint8_t len) { | 维度 | 评估 | 说明 | |------|------|------| -| **实时性** | ✅ 安全 | ISR 层不受 TX 阻塞影响;主循环延迟 45ms 可接受 | -| **CPU** | 🟡 @9600 临界 | 活动态 30% TX 阻塞,主循环仍有 55ms 余量 | -| **CPU** | 🟢 @19200 充裕 | 活动态 15% TX 阻塞,余量充足 | +| **实时性** | ✅ 安全 | ISR 层不受 TX 阻塞影响;主循环延迟 4.3ms 可忽略 | +| **CPU** | 🟢 充裕 | 活动态 TX 阻塞仅 2.9%,主循环余量 >60% | | **RAM** | 🟢 充裕 | 增量 < 170B, < 1% 总 RAM | | **Flash** | 🟡 18KB OTA 配置偏紧 | 增量 ~8.5KB,占应用区 47% | -| **BLE** | 🟢 安全 | 45ms 远小于连接超时 (≥2s) | +| **BLE** | 🟢 安全 | 4.3ms 远小于连接超时 (≥2s) | | **线圈检测** | 🟢 安全 | TMR0/TMR1 ISR 独立,不丢边沿 | diff --git a/docs/rs485-modbus-protocol.md b/docs/rs485-modbus-protocol.md index ff8201a..00f8059 100644 --- a/docs/rs485-modbus-protocol.md +++ b/docs/rs485-modbus-protocol.md @@ -15,7 +15,7 @@ |------|-----| | 接口 | RS485 半双工 (UART0) | | 引脚 | PA14 TX, PA15 RX, PA13 RE (方向控制) | -| 波特率 | 9600 (默认), 19200, 38400, 57600, 115200 | +| 波特率 | 9600 (700BS 默认), **115200 (Modbus 默认, 推荐)** | | 数据位 | 8 | | 校验 | 无 (N) | | 停止位 | 1 |