You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
Lizongdi 9107d07c73 现在支持通过协议获取版本信息 1 week ago
..
include 现在支持通过协议获取版本信息 1 week ago
CMakeLists.txt 项目维度的模块加了一层文件夹 2 months ago
README.md spoolend 【修改文档】差异点梳理 1 week ago
Spoolend.c spoolend 【编译通过】初版代码移植,未调试 2 weeks ago
dmk.c spoolend 【编译通过】初版代码移植,未调试 2 weeks ago
flash_operation.c spoolend 【编译通过】初版代码移植,未调试 2 weeks ago
modbus.c 现在支持通过协议获取版本信息 1 week ago

README.md

Spoolold → Spoolend 移植计划

一、Spoolold 功能汇总

Spoolold 是一个 线缆卷筒末端控制器(STM32G431),核心功能如下:

功能模块 说明
Modbus RTU 从机 UART1, 地址 0x34, 支持 FC03/FC06/FC10, 12 个保持寄存器
Modbus RTU 主机 UART2, 向 DMK 电机驱动器发送速度/方向指令
4 路继电器输出 K1-K4 独立开关控制,由 Modbus 寄存器 [0]-[3] 驱动
电源管理 K5 继电器,支持手动/自动(超时)模式,含极性反转配置
通信超时保护 无通信活动时自动停止电机、关闭电源
DMK 电机控制 3 相状态机(模式→速度→方向),100ms/相,通过 Modbus FC06 发送
Flash 参数持久化 12 个 int16_t 参数存储在 Flash 最后一页,写入 55 触发保存
IWDG 看门狗 主循环喂狗,死机自动复位

核心数据结构:holdingRegisters[12]

索引 默认值 功能
[0]-[3] 50 K1-K4 继电器控制(0=关, 非0=开)
[4] 0 电源极性(0=正逻辑, 非0=反转)
[5] 0 电源模式(0=自动超时, 非0=手动)
[6] 0 手动电源开关(0=关, 非0=开)
[7] 0 通信超时阈值(ms)
[8] 2000 电机速度
[9] 0 电机状态(0=停, 1=正转, 2=反转)
[10] 0 Flash 保存触发(55=保存)
[11] 0 保留

二、新旧架构对比

维度 Spoolold (旧) Spoolend (新)
UART 驱动 直接调 HAL,逐字节中断接收 bsp_uart.h + TComCtrl 抽象层,环形缓冲区
Modbus 协议 自带 modbus.c(从机+主机) 无,需移植
电机控制 自带 dmk.c(3 相状态机) 无,需移植
Flash 操作 自带 flash_operation.c(直接操作 Flash) 可用 bspMCU/stmflash.h
GPIO 控制 直接 HAL_GPIO_WritePin 同样方式,无需改变
发送方式 DMA 发送 TComCtrlrd_ComSendProc + 自定义 send 回调

三、移植方案

3.1 文件结构规划

robot/project/Spoolend/ 下新增:

Spoolend/
├── CMakeLists.txt          (已有,需更新源文件列表)
├── Spoolend.c              (已有,需重写)
├── include/
│   ├── Spoolend.h          (新建 - 公共接口)
│   ├── modbus.h            (从 Spoolold 移植,适配 TComCtrl)
│   ├── dmk.h               (从 Spoolold 移植)
│   └── flash_operation.h   (从 Spoolold 移植,适配 stmflash)
├── modbus.c                (从 Spoolold 移植,重写收发层)
├── dmk.c                   (从 Spoolold 移植,适配新 Modbus 接口)
└── flash_operation.c       (从 Spoolold 移植,适配 stmflash API)

3.2 各模块移植要点

A. Modbus 协议栈 (modbus.c/h)

保留:

  • CRC-16 计算逻辑
  • FC03/FC06/FC10 帧解析与响应构造
  • 异常响应机制
  • 寄存器读写逻辑 + 可写性检查

重写:

  • 接收层:不再逐字节中断接收,改为通过 TComCtrlcheck/decode 回调机制
    • check_RS485_1() → 做 Modbus 帧完整性校验(CRC + 长度),返回帧长或 0
    • decode_RS485_1() → 调用 Modbus_Process() 解析帧内容
  • 发送层Modbus_SendResponse() 改为调用 rd_ComWrite(g_ptRS485_1, ...)
  • 主机发送Modbus_Master_Send() 改为调用 rd_ComWrite(g_ptRS485_2, ...)
  • 超时检测:不再依赖 Rx_Pre_time,改用 TComCtrlm_uiLastRecvTime

关键适配:

// 旧:HAL_UART_Transmit_DMA(&huart1, data, len)
// 新:rd_ComWrite(g_ptRS485_1, (char*)data, len)

// 旧:逐字节 HAL_UART_Receive_IT + HAL_UART_RxCpltCallback
// 新:check 回调做帧校验,decode 回调做帧处理

B. DMK 电机控制 (dmk.c/h)

保留:

  • 3 相状态机逻辑(模式→速度→方向,100ms/相)
  • 电机方向映射(0=停, 1=正转→0x01, 2=反转→0x14)

重写:

  • MB_WriteHoldingReg() 调用改为新的 Modbus 主机接口
  • 超时检测逻辑适配 TComCtrl 时间戳

C. Flash 参数存储 (flash_operation.c/h)

方案选择: 使用 bspMCU/stmflash.h 提供的 API

适配:

// 旧:直接 HAL_FLASH_Unlock / HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, ...)
// 新:STMFLASH_Write(WriteAddr, pBuffer, NumToWrite)
//     STMFLASH_Read(ReadAddr, pBuffer, NumToRead)
//     STMFLASH_EraseByAddress(Address)

注意:stmflash.h#ifdef USE_ONCHIP_FLASH 保护,需确保 CMake 中启用该宏。

D. 主逻辑 (Spoolend.c)

SpoolendInit():

  1. 初始化 RS485_1(已有)→ 绑定 Modbus 从机 check/decode
  2. 初始化 RS485_2(已有)→ 绑定 Modbus 主机 send
  3. 初始化 FDCAN1(保留,可选)
  4. 调用 Flash_ReadParameters() 恢复参数
  5. 设置 holdingRegisters[8] = 2000(默认速度)
  6. IWDG 初始化(如 CubeMX 未配置)

SpoolendTask():

  1. HAL_IWDG_Refresh() 喂狗
  2. rd_ComRead + Modbus_Process() 处理 Modbus 帧
  3. K1-K4 GPIO 控制(holdingRegisters[0..3])
  4. 通信超时判断 + 电机停止
  5. handle_dmk_motor() 电机控制
  6. handle_power_on_off() 电源管理
  7. Flash 保存检查(holdingRegisters[10]==55)
  8. rd_ComSendProc() 发送处理

3.3 CMakeLists.txt 更新

set(SRC_LIST
    Spoolend.c
    modbus.c
    dmk.c
    flash_operation.c
)

依赖关系保持不变:target_link_libraries(${TARGET_NAME} PUBLIC bspMCU)


四、移植顺序

  1. flash_operation.c/h → 最独立,先移植并验证 Flash 读写
  2. modbus.c/h → 核心协议,移植从机部分先(FC03/06/10),再移植主机部分
  3. dmk.c/h → 依赖 Modbus 主机接口
  4. Spoolend.c → 整合所有模块,替换 demo 逻辑为正式控制逻辑

五、验证方案

  1. Flash 验证:写入参数 → 重启 → 读取比对
  2. Modbus 从机验证:用 Modbus Poll 等工具连接 RS485_1,读写 12 个寄存器
  3. Modbus 主机验证:连接 DMK 驱动器,发送速度/方向命令,观察响应
  4. GPIO 验证:通过 Modbus 写 K1-K4 寄存器,用万用表测引脚电平
  5. 电源管理验证:设置超时阈值,断开通信,观察 K5 自动关闭
  6. 看门狗验证:故意死循环,观察系统自动复位

六、关键文件路径

文件 路径
Spoolold 主逻辑 robot/project_old/Spoolold/Spoolold.c
Modbus 旧实现 robot/project_old/Spoolold/modbus.c
DMK 旧实现 robot/project_old/Spoolold/dmk.c
Flash 旧实现 robot/project_old/Spoolold/flash_operation.c
Spoolend 当前代码 robot/project/Spoolend/Spoolend.c
TComCtrl 通信抽象 robot/peripheral/include/com.h
BSP UART 驱动 robot/bspMCU/include/bsp_uart.h
BSP Flash 驱动 robot/bspMCU/include/stmflash.h
根 CMakeLists robot/CMakeLists.txt

Spoolend 线轴端控制板 — 测试用例文档

一、测试环境

项目 说明
硬件 STM32G431 控制板 + DMK 电机驱动器 + 5路继电器模块
上位机工具 Modbus Poll / Modbus Slave / 自定义串口工具
连接 RS485_1 (USART1) → 上位机主机, RS485_2 (USART3) → DMK 驱动器
波特率 115200, 8N1
Modbus 从机地址 0x34 (52)

二、Modbus 从机通信测试

TC-MODBUS-01: FC03 读保持寄存器 — 正常读取全部寄存器

项目 内容
前置条件 系统正常启动
操作 发送: 34 03 0000 000C CRC
预期响应 34 03 18 [24字节寄存器数据] CRC
验证点 返回 12 个寄存器值,与 holdingRegisters[0..11] 一致

TC-MODBUS-02: FC03 读保持寄存器 — 读取单个寄存器

项目 内容
操作 发送: 34 03 0000 0001 CRC (读 K1 状态)
预期响应 34 03 02 [K1值高] [K1值低] CRC

TC-MODBUS-03: FC03 读保持寄存器 — 地址越界

项目 内容
操作 发送: 34 03 000B 0002 CRC (从地址11开始读2个)
预期响应 34 80 02 CRC (异常码 0x02: 非法数据地址)

TC-MODBUS-04: FC06 写单个寄存器 — 写 K1 控制

项目 内容
操作 发送: 34 06 0000 0000 CRC (K1 设为 0)
预期响应 34 06 0000 0000 CRC (原帧回显)
验证点 K1 引脚变为低电平;再发 34 06 0000 0001 CRC,K1 恢复高电平

TC-MODBUS-05: FC06 写单个寄存器 — 地址越界

项目 内容
操作 发送: 34 06 000C 0000 CRC (地址 12 超出范围)
预期响应 34 80 02 CRC (异常码 0x02)

TC-MODBUS-06: FC10 写多个寄存器 — 批量写入 K1-K4

项目 内容
操作 发送: 34 10 0000 0004 08 0001 0000 0001 0000 CRC
预期响应 34 10 0000 0004 CRC
验证点 K1=1, K2=0, K3=1, K4=0;GPIO 引脚电平对应变化

TC-MODBUS-07: FC10 写多个寄存器 — 数据长度错误

项目 内容
操作 发送: 34 10 0000 0004 04 0001 0000 CRC (byteCount=4 但 registerCount=4 需要 8 字节)
预期响应 34 80 03 CRC (异常码 0x03)

TC-MODBUS-08: FC10 写多个寄存器 — 只读寄存器保护

项目 内容
前置条件 registerWritable[i] = 0 的寄存器
操作 尝试写入只读寄存器
预期响应 正常响应,但只读寄存器值不变

TC-MODBUS-09: CRC 校验 — 错误 CRC

项目 内容
操作 发送: 34 03 0000 0001 0000 (CRC 错误)
预期响应 无响应(静默丢弃)

TC-MODBUS-10: 不支持的功能码

项目 内容
操作 发送: 34 01 0000 0001 CRC (FC01 不支持)
预期响应 无响应(静默丢弃)

三、GPIO 继电器控制测试

TC-GPIO-01: K1-K4 独立控制

项目 内容
操作 通过 FC06 依次写 holdingRegisters[0..3] 为非零值
预期 K1→K4 引脚依次变为高电平 (GPIO_PIN_SET)
操作 写为 0
预期 K1→K4 引脚依次变为低电平 (GPIO_PIN_RESET)

TC-GPIO-02: K1-K4 默认状态

项目 内容
操作 系统上电,不发送任何 Modbus 命令
预期 holdingRegisters[0..3] 默认值为 50 (0x32),K1-K4 均为高电平

TC-GPIO-03: LED1 指示灯

项目 内容
操作 发送任意 Modbus 命令到本机地址 (0x34)
预期 LED1 翻转一次

四、电源管理测试 (K5)

TC-PWR-01: 自动模式 — 通信正常时电源开启

项目 内容
前置条件 holdingRegisters[5]=0 (自动), [4]=0 (正极性), [7]=0x1388 (5秒超时)
操作 持续发送 Modbus 命令(间隔 < 5秒)
预期 K5 引脚保持低电平(电源开启,正极性时 RESET=开)

TC-PWR-02: 自动模式 — 通信超时关闭电源

项目 内容
前置条件 同上
操作 停止发送 Modbus 命令,等待超过 5 秒
预期 K5 引脚变为高电平(电源关闭)

TC-PWR-03: 自动模式 — 通信恢复重新开启

项目 内容
操作 超时后重新发送 Modbus 命令
预期 K5 引脚恢复低电平(电源重新开启)

TC-PWR-04: 手动模式 — 开启电源

项目 内容
操作 FC06 写 holdingRegisters[5]=1 (手动), [6]=1 (开)
预期 K5 引脚变为低电平(电源开启)

TC-PWR-05: 手动模式 — 关闭电源

项目 内容
操作 FC06 写 holdingRegisters[6]=0 (关)
预期 K5 引脚变为高电平(电源关闭)

TC-PWR-06: 极性反转

项目 内容
操作 FC06 写 holdingRegisters[4]=1 (反极性)
预期 K5 引脚电平逻辑反转(SET=关, RESET=开)

五、DMK 电机控制测试

TC-DMK-01: 电机正转

项目 内容
操作 FC06 写 holdingRegisters[9]=1 (正转), [8]=2000 (速度)
预期 RS485_2 周期性 (300ms) 向 DMK 发送: 模式→速度→方向(0x01)
验证点 用串口监听 RS485_2,确认 3 相 Modbus FC06 帧正确

TC-DMK-02: 电机反转

项目 内容
操作 FC06 写 holdingRegisters[9]=2
预期 方向寄存器 0x033 写入值 0x14

TC-DMK-03: 电机停止

项目 内容
操作 FC06 写 holdingRegisters[9]=0
预期 方向寄存器 0x033 写入值 0x00

TC-DMK-04: 速度设置

项目 内容
操作 FC06 写 holdingRegisters[8]=3000
预期 速度寄存器 0x06A 写入值 3000

TC-DMK-05: 3 相时序验证

项目 内容
操作 电机运行中,监听 RS485_2 输出
预期 每 300ms 周期: 相0(0-100ms)写模式=0, 相1(100-200ms)写速度, 相2(200-300ms)写方向

TC-DMK-06: 默认速度

项目 内容
操作 系统上电
预期 holdingRegisters[8] 硬编码为 2000(即使 Flash 中存储了其他值)

六、通信超时保护测试

TC-TIMEOUT-01: 超时停止电机

项目 内容
前置条件 holdingRegisters[7]=5000, 电机正在运行
操作 停止 Modbus 通信超过 5 秒
预期 RS485_2 发送停止命令 MB_WriteHoldingReg(1, 0x33, 0x0)

TC-TIMEOUT-02: 超时阈值为 0 时禁用超时

项目 内容
操作 FC06 写 holdingRegisters[7]=0
预期 通信超时不会触发停止(阈值为 0 时立即超时,但需验证行为)

七、Flash 参数持久化测试

TC-FLASH-01: 参数保存

项目 内容
操作 修改 K1-K4 为自定义值,FC06 写 holdingRegisters[10]=0x37
预期 参数写入 Flash 最后一页;holdingRegisters[10] 自动变为 1
验证 发送 FC03 读取确认 [10]=1

TC-FLASH-02: 参数恢复

项目 内容
前置条件 TC-FLASH-01 已执行
操作 系统复位/重新上电
预期 从 Flash 读取参数,K1-K4 恢复为保存时的值

TC-FLASH-03: 保存后速度覆盖

项目 内容
操作 保存时 holdingRegisters[8]=3000,重启
预期 Flash 读取后 [8]=3000,但 SpoolendInit 硬编码覆盖为 2000

TC-FLASH-04: 默认参数

项目 内容
操作 全新芯片首次启动(Flash 为空白 0xFF)
预期 holdingRegisters[0..3] 读取为 0xFFFF (非零=开),K1-K4 默认开启

八、看门狗测试

TC-WDG-01: 正常运行不复位

项目 内容
操作 系统正常运行
预期 SpoolendTask 每次循环喂狗,系统持续运行不复位

TC-WDG-02: 死机自动复位

项目 内容
操作 在 SpoolendTask 中插入 while(1); 死循环
预期 IWDG 超时后系统自动复位

九、FDCAN 测试

TC-CAN-01: CAN 数据透传

项目 内容
操作 向 FDCAN1 发送任意 CAN 帧
预期 数据通过 rd_ComIDWrite 回传(echo)

TC-CAN-02: CAN 错误恢复

项目 内容
操作 制造 CAN 总线错误
预期 HAL_FDCAN_ErrorStatusCallback 触发 MX_FDCAN1_Init 重新初始化

十、边界条件与异常测试

TC-EDGE-01: Modbus 帧不完整

项目 内容
操作 发送不完整的 Modbus 帧(如只有地址字节 34
预期 等待后续数据或超时丢弃,不崩溃

TC-EDGE-02: 非本机地址帧

项目 内容
操作 发送地址非 0x34 的 Modbus 帧
预期 静默忽略,不响应

TC-EDGE-03: 高频 Modbus 请求

项目 内容
操作 以最大频率连续发送 FC03 读取请求
预期 每帧正确响应,不丢帧不乱序

TC-EDGE-04: 同时读写寄存器

项目 内容
操作 一边用 FC03 读取,一边用 FC06 写入
预期 读取返回写入前或写入后的值(无中间态撕裂)

十一、测试用例统计

类别 用例数
Modbus 从机通信 10
GPIO 继电器控制 3
电源管理 6
DMK 电机控制 6
通信超时保护 2
Flash 参数持久化 4
看门狗 2
FDCAN 2
边界与异常 4
合计 39