面向全国大学生电子设计竞赛、校赛、省赛、智能车/小车类题目、控制类题目和常见嵌入式快速开发场景的 单片机工程 Skill。
它的目标不是简单生成一段驱动代码,而是让 Codex 像一个可靠的电赛嵌入式队友一样工作:先问清板子、芯片、开发环境和外设;再分析需求并生成决策树;做好状态机、FreeRTOS、裸机调度或混合架构的整体规划;再读取已有工程;必要时访问原厂官网学习资料;然后完成引脚分配、外设配置、比赛级代码结构、单模块测试、调参路径、多环 PID、步进运动规划、传感器补偿、通信协议和整机联调文档。
| 目标 | 说明 |
|---|---|
| 适配所有板子 | 不默认用户使用 STM32,MSPM0,ESP32;先询问,再查证,再落地 |
| 先理解硬件 | 板卡、芯片、开发环境、外设、电压、下载方式和现有项目必须先确认 |
| 先读取项目 | 如果用户已有工程,先读 .ioc、.syscfg、Keil、CCS、PlatformIO、Arduino 等配置 |
| 优先官方资料 | 不凭论坛印象决定引脚、定时器、DMA、ADC、电平等关键事实 |
| 比赛级代码 | 参数前置、模块分层、状态机、限幅、死区、补偿、遥测、安全保护 |
| 调参可执行 | 不只写 TUNING.md,还要明确用户是模块带调、单测带调,还是混合模式 |
| 先规划再实现 | 非简单任务必须先生成需求决策树和总体架构计划,再进入代码实现 |
| 状态机优先 | 比赛模式、模块启动、通信解析、步进运动、故障处理必须显式状态化 |
| FreeRTOS 有边界 | 需要并发服务时使用任务、队列、通知;简单硬实时项目优先裸机状态机 |
| 能教会用户 | 对 PID、死区、滤波、补偿、步进规划、状态机、FreeRTOS 和通信调参给出耐心步骤 |
| 原则 | 要求 |
|---|---|
| 先问清,再写代码 | 板子、芯片、IDE、外设和调参路径不清楚时,先询问关键问题 |
| 先读项目,再改项目 | 已有工程优先读取配置文件,不直接重写 main.c 或覆盖生成文件 |
| 先查官方,再给结论 | 引脚复用、电气限制、定时器通道、ADC、DMA、SDK API 不确定时必须查原厂资料 |
| 先单测,再闭环 | 关键硬件先用独立测试代码验证,再合入主工程做多环联调 |
| 参数必须前置 | 比赛中可能调的参数集中放到 tuning_params.h/.c,禁止魔法数散落 |
| 应用与板卡解耦 | 应用逻辑依赖驱动,驱动依赖 BSP,BSP 依赖具体 HAL/DriverLib/SDK |
| 安全永远在线 | 电机、步进、继电器、电源、电流采样等必须有输出限幅、超时和急停方案 |
| 决策树先行 | 先判断裸机、状态机调度、FreeRTOS 或混合架构,再决定代码组织 |
| FreeRTOS 不滥用 | 只有多任务服务、通信、UI、日志、网络、存储等确有必要时才引入 RTOS |
Skill 在开始写代码前,应先询问缺失但会改变交付物的问题。
| 问题 | 示例选项 | 影响 |
|---|---|---|
| 你用的是什么板子/芯片? | STM32F103/F407/G0/H7、TI MSPM0/MSP430/C2000、ESP32、GD32、CH32、STC、RP2040、Arduino、其他 | 决定 SDK、引脚复用、定时器、ADC、DMA、下载方式 |
| 你用什么开发环境? | CubeMX + Keil、CubeIDE、CCS/SysConfig、PlatformIO、Arduino IDE、ESP-IDF、Make/CMake | 决定配置文档和工程文件修改方式 |
| 项目文件是否已经存在? | 有,读取工程;没有,生成配置说明 | 决定是读配置还是生成 PROJECT_SETUP.md |
| 有哪些外设? | 电机、舵机、步进、编码器、IMU、OLED、超声波、ADC、电流、电压、CAN、RS485、蓝牙、WiFi | 决定引脚表、驱动、测试和调参顺序 |
| 你希望怎么调参? | 模块一个一个带动调参;一边写单独测试代码一边调参;混合模式 | 决定 tests/、TUNING.md 和合入主工程策略 |
| 软件架构倾向是什么? | 裸机循环、状态机调度、FreeRTOS、已有 RTOS/任务框架、不确定 | 决定 ARCHITECTURE_PLAN.md、任务划分、状态机和 ISR-to-task 方式 |
默认推荐:混合模式。先用独立测试代码验证关键硬件,再合入主工程做多环闭环。
用户需求
↓
询问板卡 / 芯片 / IDE / 外设 / 调参方式 / 软件架构倾向
↓
需求分析与模块分类
↓
生成决策树:裸机循环 / 状态机调度 / FreeRTOS / 混合架构
↓
生成整体架构计划:任务、状态、周期、优先级、队列、中断交接、安全路径
↓
检查是否已有项目文件
├─ 有:读取配置、引脚、外设、时钟、中断、DMA、代码风格
└─ 无:生成 CubeMX / CCS / SysConfig / PlatformIO / Arduino 配置说明
↓
访问官网/原厂资料确认芯片能力、引脚复用和电气限制
↓
生成或修正引脚分配表
↓
建立比赛级工程结构
↓
前置所有可调参数
↓
按调参路径生成测试代码和文档
↓
传感器校准 → 执行器开环 → 内环 PID → 外环 PID → 整机联调
Skill 进入项目后,不能立刻写 main.c 或驱动文件。只要项目超过单个外设测试,就必须先生成决策树和整体规划。
| 阶段 | 要做什么 | 输出 |
|---|---|---|
| 需求摘要 | 用一句话描述比赛目标和主控制对象 | 目标、成功标准、风险 |
| 模块分类 | 把外设分成传感器、执行器、通信、UI、安全、后台服务 | 模块清单 |
| 实时性分析 | 判断哪些是硬实时控制,哪些是后台任务 | 周期/优先级表 |
| 架构选择 | 选择裸机、状态机调度、FreeRTOS 或混合架构 | DECISION_TREE.md |
| 总体规划 | 明确模块依赖、任务/状态归属、ISR 交接、队列、故障路径 | ARCHITECTURE_PLAN.md |
| 再实现 | 架构明确后再写 BSP、driver、control、protocol、app | 工程代码 |
入口决策树:
项目只是简单外设测试?
是 -> 裸机 super loop + 少量 timer tick
否
是否有比赛阶段、动作序列、通信解析、故障处理?
是 -> 显式状态机
是否有 UI、通信、日志、存储、网络、多传感器后台服务?
是 -> 考虑 FreeRTOS
是否控制环硬实时,但 UI/通信是后台?
是 -> 定时器/ISR 控制 + 状态机 + FreeRTOS 后台任务的混合架构
状态机是这个 Skill 的默认编程思想。凡是有阶段、有等待、有超时、有故障、有动作序列的地方,都要显式状态化。
| 场景 | 推荐状态 |
|---|---|
| 比赛主流程 | IDLE、ARMED、RUNNING、FINISH、FAULT |
| 模块启动 | POWER_CHECK、INIT、SELF_TEST、READY、ERROR |
| 电机控制 | DISABLED、OPEN_LOOP、CLOSED_LOOP、BRAKE、FAULT |
| 步进运动 | IDLE、HOMING、ACCEL、CRUISE、DECEL、DONE、FAULT |
| 通信解析 | WAIT_HEADER、READ_LEN、READ_PAYLOAD、CHECK_CRC、DISPATCH |
| 传感器校准 | RAW、ZEROING、SCALING、VALIDATING、READY |
状态机规范:
| 要素 | 要求 |
|---|---|
| entry | 进入状态时只执行一次的动作 |
| run | 当前状态周期执行的动作 |
| exit | 离开状态时释放资源或关闭输出 |
| timeout | 非瞬时状态必须有超时保护 |
| fault | 危险状态必须能进入安全输出 |
| log | 状态切换必须可通过串口、OLED 或遥测观察 |
FreeRTOS 不是默认答案,而是架构选择之一。Skill 需要先判断是否值得引入 RTOS。
| 适合 FreeRTOS | 更适合裸机/状态机 |
|---|---|
| 同时存在控制、传感器、通信、UI、日志、存储、网络等多个服务 | 只有简单主循环和少量定时器中断 |
| 各任务周期不同,需要清晰隔离 | 控制抖动要求极低且 RTOS 带来不必要复杂度 |
| ESP32 或厂商 SDK 天然依赖 FreeRTOS | RAM 很小,队伍不熟悉任务、栈、优先级调试 |
| 队列、通知、信号量能显著降低耦合 | 共享资源很少,状态机足够清晰 |
推荐任务划分:
| Task | 优先级 | 触发方式 | 拥有资源 | 通信方式 |
|---|---|---|---|---|
SafetyTask |
最高 | 周期/中断通知 | 故障状态、急停、看门狗 | 直接标志/通知 |
ControlTask |
高 | 固定周期或 timer notify | 控制环、执行器命令 | queue/notify |
SensorTask |
中高 | 固定周期或 data-ready IRQ | 传感器读取与补偿 | queue latest value |
CommTask |
中 | UART/CAN/RS485 RX | 协议解析、参数读写 | queue/stream buffer |
UiTask |
低 | 50-200ms | OLED、按键、蜂鸣器 | event queue |
LogTask |
低 | 遥测周期 | 串口日志/CSV 输出 | queue/stream buffer |
FreeRTOS 规则:
- ISR 只采样、清标志、发通知或推少量数据,不做 OLED、printf、复杂 PID。
- 一个资源只有一个 owner,例如 OLED 归
UiTask,参数服务归CommTask或 config 模块。 - 跨任务数据优先用 queue、stream buffer、task notification,少用裸全局变量。
- 控制周期必须测 jitter,栈大小必须看 high-water mark。
- RTOS 不能替代状态机;任务内部仍然要用状态机表达阶段和故障。
| 模块 | 要解决的问题 | Skill 行为 | 输出物 |
|---|---|---|---|
| 板卡识别 | 用户可能使用不同 MCU 或开发板 | 先询问芯片、板卡、IDE、下载器、电压,再查官方资料确认能力 | 板卡能力表、风险清单 |
| 官网学习 | 用户资料可能不完整或板卡不常见 | 优先访问 datasheet、reference manual、SDK、原理图、pinmux 工具 | 官方依据、假设清单 |
| 项目读取 | 工程可能已有配置,且可能被手改 | 读取配置和生成文件,判断外设、引脚、时钟、中断、DMA | 项目配置摘要 |
| 决策树规划 | 用户需求可能有多种实现路线 | 先生成裸机/状态机/FreeRTOS/混合架构决策树 | DECISION_TREE.md |
| 总体架构 | 代码不能边写边堆 | 先规划模块依赖、状态机、任务、队列、中断交接和安全路径 | ARCHITECTURE_PLAN.md |
| 引脚分配 | 外设多、复用复杂、容易冲突 | 用表格分配 GPIO/UART/I2C/SPI/PWM/ADC/Encoder/CAN/RS485 | PINMAP.md |
| 工程架构 | 比赛代码要能调、能查、能移植 | 生成 app/bsp/drivers/control/protocol/config/tests/docs 分层 |
比赛级工程结构 |
| 调参路径 | 用户可能有不同调参习惯 | 询问模块带调、测试带调或混合模式 | TUNING.md、TEST_PLAN.md |
| 多环 PID | 小车、云台、平衡、路径控制都需要级联 | 支持位置、速度、角度、角速度、电流/力矩/PWM 等环 | CONTROL_CHAIN.md |
| 步进规划 | 阻塞延时会卡主循环,运动不丝滑 | 生成三角/梯形/S 曲线、定时器脉冲、状态机 | 运动规划模块 |
| 传感器补偿 | 真实传感器有零偏、温漂、噪声和非线性 | 生成校准、滤波、线性/非线性补偿、可信度判断 | 补偿参数和校准步骤 |
| 通信调参 | 只靠 printf 不利于比赛现场调参 |
设计帧格式、CRC、心跳、超时、GET/SET 参数命令 | 协议文档和遥测输出 |
当板卡、芯片、外设、开发工具链或引脚复用信息不完整时,Skill 必须优先学习官方资料。
| 优先级 | 资料来源 | 用途 |
|---|---|---|
| 1 | 芯片 datasheet | 电压、电流、封装引脚、ADC 精度、IO 能力 |
| 2 | Reference manual / TRM | 寄存器、定时器、DMA、中断、外设行为 |
| 3 | 官方开发板原理图 | 板载 LED、按键、晶振、下载口、跳帽、供电 |
| 4 | 官方 SDK / HAL / DriverLib 示例 | 初始化顺序、API 用法、推荐工程结构 |
| 5 | CubeMX / SysConfig / ESP-IDF / Pinmux 工具 | 引脚复用和外设冲突确认 |
| 6 | 模块官方手册 | 传感器寄存器、量程、通信协议、校准 |
| 7 | 开源例程和社区资料 | 只能作为参考,不能覆盖官方结论 |
必须查证的关键点:
| 类型 | 必查内容 |
|---|---|
| 电气 | 3.3V/5V 兼容、上拉/下拉、开漏、电平转换、ADC 最大输入 |
| 时钟 | 主频、外部晶振、PLL、Flash wait state、低功耗模式 |
| 定时器 | PWM 通道、输入捕获、编码器模式、定时中断、死区互补输出 |
| ADC/DAC | 通道、采样时间、参考电压、DMA、校准、输入阻抗 |
| 通信 | UART/I2C/SPI/CAN/RS485 引脚复用、速率、DMA、中断 |
| 调试 | SWD/JTAG/串口下载、Boot 脚、复位脚、被占用风险 |
如果用户项目已经存在,Skill 不应直接生成新工程,而应先读已有结构。
| 平台 | 优先读取文件 | 需要提取的信息 |
|---|---|---|
| STM32 CubeMX/HAL | .ioc、Core/Src/main.c、gpio.c、tim.c、adc.c、usart.c、i2c.c、spi.c、stm32xxxx_hal_conf.h、linker script |
时钟、外设、引脚、DMA、NVIC、用户代码区 |
| STM32 LL/裸机 | startup、linker script、system clock、寄存器头文件 | 启动流程、向量表、时钟、外设归属 |
| TI CCS/SysConfig | .syscfg、.project、.cproject、ti_msp_dl_config.c/.h、Board.c/.h、linker command file |
device、package、pinmux、DriverLib、生成文件状态 |
| TI Keil MSPM0 | .uvprojx、.syscfg、ti_msp_dl_config.*、startup .s、.sct |
编译器、包含路径、DriverLib、IRQ handler |
| ESP-IDF | sdkconfig、CMakeLists.txt、main/*.c、idf_component.yml、partitions.csv |
组件、任务、引脚、LEDC、UART/I2C/SPI |
| PlatformIO | platformio.ini、src/、include/、lib/ |
board、framework、串口速率、库依赖 |
| Arduino | .ino、libraries/、pins_arduino.h |
board package、引脚别名、库版本 |
项目读取后应生成:
| 输出项 | 内容 |
|---|---|
| 已启用外设 | UART、I2C、SPI、PWM、ADC、CAN、定时器、中断、DMA |
| 已占用引脚 | 每个模块实际用到的引脚和复用功能 |
| 可用资源 | 剩余 UART、I2C、SPI、ADC、PWM、定时器通道 |
| 冲突风险 | 引脚重复、定时器复用、生成文件漂移、注释与实际代码不一致 |
| 当前代码风格 | HAL、LL、DriverLib、Arduino API、裸寄存器、混合风格 |
如果用户没有已有项目,Skill 需要生成配置辅助文档,而不是只给代码。
| 文件 | 作用 |
|---|---|
DECISION_TREE.md |
记录需求分析、架构分支、选择理由和假设 |
ARCHITECTURE_PLAN.md |
记录模块图、状态机、FreeRTOS/裸机选择、周期、优先级、队列和安全路径 |
PROJECT_SETUP.md |
告诉用户 CubeMX、CCS/SysConfig、PlatformIO、Arduino IDE 里要开哪些外设、哪些不要开 |
PINMAP.md |
明确模块、信号、MCU 引脚、复用功能、电压、上拉/下拉、风险 |
TUNING.md |
明确参数位置、调参顺序、串口输出、正常/异常现象 |
MODULE_BRINGUP.md |
单模块上电、接线、读取、测试、合入主工程步骤 |
TEST_PLAN.md |
需要生成哪些 test_xxx.c,每个测试如何判断通过 |
CONTROL_CHAIN.md |
控制环输入/输出、频率、单位、限幅、依赖关系 |
引脚分配必须用表格表达,不能只写散文。
| 模块 | 信号 | MCU 引脚 | 外设/复用 | 方向 | 电平 | 上拉/下拉 | 频率/时序 | 风险 | 备注 |
|---|---|---|---|---|---|---|---|---|---|
| 调试串口 | TX/RX | TBD | UARTx | 输出/输入 | 3.3V | RX 上拉 | 115200 | 是否占下载口 | 用于日志和调参 |
| 左电机 | PWM | TBD | TIMx_CHy | 输出 | 3.3V | 无 | 10-25kHz | 定时器冲突 | 驱动器输入 |
| 左编码器 | A/B | TBD | TIM Encoder 或 EXTI | 输入 | 3.3V/5V | 视模块而定 | 边沿计数 | 中断负载 | 优先硬件编码器 |
| IMU | SCL/SDA 或 UART | TBD | I2C/UART | 双向 | 3.3V | I2C 上拉 | 400k/9600 | 电平和地址 | 需要校准 |
| OLED | SCL/SDA | TBD | I2C 或模拟 I2C | 双向 | 3.3V | 上拉 | 100k/400k | 与 IMU 共线 | 显示状态 |
分配顺序建议:
- 先保留 SWD/JTAG/BOOT/RESET 等关键调试脚。
- 优先放置固定复用或高速外设:CAN、USB、硬件编码器、PWM 对、SPI。
- 再放 ADC 和模拟信号,注意电机噪声和采样稳定。
- 再放 I2C,确认上拉、电平和地址冲突。
- 再放 UART 调试、蓝牙、RS485。
- 最后放按键、LED、蜂鸣器、普通 GPIO。
调参不是附属说明,而是 Skill 的主路径之一。
| 调参模式 | 适用情况 | Skill 行为 | 优点 | 风险控制 |
|---|---|---|---|---|
| A. 模块一个一个带动调参 | 已有主工程,硬件大体确定 | 在主工程里逐个接入模块并调参 | 合入速度快 | 每接一个模块都输出串口遥测和 pass/fail 标准 |
| B. 一边写单独测试代码一边调参 | 项目刚开始或硬件不确定 | 为每个模块生成 test_xxx.c |
排硬件问题最稳 | 测试文件只做一件事,通过后再合入 |
| C. 混合模式 | 电赛默认推荐 | 关键模块先单测,稳定后进入主工程多环联调 | 兼顾稳和快 | 保留测试记录和最终参数 |
推荐调参顺序:
电源/共地/电平
↓
串口日志或 OLED 显示
↓
传感器 raw 值
↓
传感器校准与滤波
↓
执行器开环方向/死区/限幅
↓
内环 PID
↓
外环 PID
↓
通信在线调参
↓
整机比赛模式
调参输出推荐 CSV:
time_ms,mode,target,actual,error,pid_out,actuator,flags
1234,SPEED,100.0,86.4,13.6,420,500,OK
目标工程结构:
project/
app/
app_main.c
task_control.c
task_comm.c
task_sensor.c
app_mode.c
app_ui.c
bsp/
bsp_gpio.c
bsp_uart.c
bsp_i2c.c
bsp_spi.c
bsp_tim.c
bsp_pwm.c
bsp_adc.c
bsp_encoder.c
drivers/
drv_motor_dc.c
drv_motor_stepper.c
drv_servo.c
drv_oled.c
drv_imu.c
drv_encoder.c
drv_voltage.c
drv_current.c
control/
pid.c
cascade_pid.c
motion_profile.c
filter.c
observer.c
calibration.c
protocol/
protocol_uart.c
protocol_can.c
protocol_rs485.c
crc.c
config/
board_config.h
pin_config.h
tuning_params.h
tuning_params.c
tests/
test_uart_echo.c
test_motor_openloop.c
test_encoder_read.c
test_imu_attitude.c
test_stepper_profile.c
test_pid_speed.c
docs/
DECISION_TREE.md
ARCHITECTURE_PLAN.md
PROJECT_SETUP.md
PINMAP.md
TUNING.md
MODULE_BRINGUP.md
CONTROL_CHAIN.md
TEST_PLAN.md
代码标准:
| 项目 | 要求 |
|---|---|
| 参数 | 所有比赛中可能改的参数集中在 tuning_params.h/.c |
| 中断 | ISR 保持短小,只置标志、读快照或处理必要寄存器 |
| 状态机 | 比赛模式、模块启动、步进运动、通信解析、传感器校准、故障处理使用非阻塞状态机 |
| FreeRTOS | 需要并发服务时先定义任务、优先级、周期、栈、队列、通知和资源 owner |
| 日志 | 每个闭环输出 target、actual、error、output、actuator、flags |
| 安全 | 输出限幅、积分限幅、超时、急停、低压/过流接口 |
| 移植 | 业务层不直接调用 HAL/DriverLib,统一通过 BSP/driver |
常见级联关系:
| 对象 | 外环 | 内环 | 输出 |
|---|---|---|---|
| 小车定距 | 距离/位置环 | 速度环 | 左右电机 PWM |
| 循迹小车 | 路径/线偏差环 | 差速/角速度环 | 左右电机差速 |
| 转向控制 | 角度环 | 角速度/速度环 | 左右轮差速 |
| 平衡车 | 角度环 | 速度/角速度环 | 电机 PWM |
| 云台 | 角度环 | 角速度环 | 电机电流/PWM |
| 步进定位 | 位置规划 | 脉冲发生器 | STEP/DIR |
PID 模块应支持:
| 功能 | 目的 |
|---|---|
| P/I/D | 基础控制 |
dt |
明确控制周期,避免隐含采样时间 |
| 输出限幅 | 防止执行器过驱 |
| 积分限幅 | 防止积分饱和 |
| Anti-windup | 饱和时抑制积分继续恶化 |
| 死区补偿 | 处理电机静摩擦和低速不动 |
| 一阶滤波 | 处理编码器速度和 IMU 噪声 |
| 微分滤波 | 避免 D 项放大噪声 |
| 前馈 | 已知模型时提升响应 |
| 斜坡限制 | 防止输出突变导致打滑、丢步或过流 |
调参顺序:
- 先确认传感器方向、单位、零点。
- 再确认执行器方向、死区、限幅。
- 先开环,再闭环。
- 先调内环,再调外环。
- 先 P,后 I,必要时再 D。
- 出现低速不动,先调死区和静摩擦补偿,不要盲目加 P。
- 出现持续振荡,先降 P 或增加滤波。
- 出现静差,再小幅增加 I。
- 出现超调,降低 P/I 或增加 D、限加速度。
- 每个环都必须有输出限幅、积分限幅、有效值判断和日志输出。
步进电机不能用粗暴阻塞延时实现:
for (...) {
step_high();
delay_us(x);
step_low();
delay_us(x);
}应使用定时器 ISR、PWM、DMA 或非阻塞状态机。
| 能力 | 要求 |
|---|---|
| 三角速度规划 | 距离太短,无法达到最大速度时使用 |
| 梯形速度规划 | 距离足够达到最大速度时使用 |
| S 曲线规划 | 对机械冲击敏感或要求丝滑时使用 |
| 加减速限制 | 防止丢步、打滑、冲击 |
| 非阻塞运行 | 主循环不能被步进脉冲卡死 |
| 回零 | 支持限位开关、回零速度、回零方向 |
| 绝对/相对位置 | 支持 move_to() 和 move_by() |
| 急停 | 任何状态可安全停止 |
状态机:
IDLE → ACCEL → CRUISE → DECEL → DONE
真实传感器默认不理想,必须具备补偿思路。
通用处理链:
raw
↓
范围检查
↓
零点校准
↓
比例系数
↓
安装方向修正
↓
温度/非线性补偿
↓
滤波
↓
单位换算
↓
可信度判断
| 传感器 | 补偿内容 | 滤波建议 | 异常判断 |
|---|---|---|---|
| IMU | gyro bias、acc offset、scale、安装方向、yaw wrap | 互补滤波、Mahony、Madgwick、EKF | 帧头/校验错误、超时、静止漂移 |
| 编码器 | 方向、CPR、减速比、轮径 | 速度一阶滤波或滑动平均 | 不可能跳变、计数溢出、断线 |
| 超声波 | 声速温度补偿、最小/最大距离 | 中值滤波、跳变剔除 | echo 超时、距离越界 |
| 电压采样 | 分压系数、Vref 修正 | 平均或 EMA | 低压报警、ADC 越界 |
| 电流采样 | 零点偏移、比例系数、温漂 | 平均或 EMA | 过流锁存 |
| 灰度/循迹 | 黑白标定、动态阈值、归一化 | 去抖/中值 | 全白、全黑、传感器失效 |
| 温度/压力/力 | 零点、比例、非线性表 | 低通 | 饱和、断线、漂移 |
比赛现场建议支持结构化通信,而不是只靠 printf。
帧格式:
| 字段 | 大小 | 说明 |
|---|---|---|
| header | 2 bytes | 例如 0xA5 0x5A |
| length | 1-2 bytes | payload 长度 |
| command | 1 byte | 命令字 |
| sequence | 1 byte | 序号,可选 |
| payload | n bytes | 参数或遥测数据 |
| crc | 1-2 bytes | CRC8/CRC16 |
命令建议:
| 命令 | 方向 | 用途 |
|---|---|---|
GET_PARAM |
上位机 → MCU | 读取一个参数 |
SET_PARAM |
上位机 → MCU | 修改一个参数 |
SAVE_PARAM |
上位机 → MCU | 保存参数 |
RESET_PARAM |
上位机 → MCU | 恢复默认参数 |
GET_STATUS |
上位机 → MCU | 获取模式、故障、传感器状态 |
START_TEST |
上位机 → MCU | 启动某个模块测试 |
STOP_TEST |
上位机 → MCU | 安全停止测试 |
TELEMETRY |
MCU → 上位机 | 周期输出 target/actual/error/output |
安全规则:
- 参数写入必须限幅。
- 远程控制必须有心跳和超时。
- 不允许通信命令关闭急停或硬安全限制。
- 高速控制 ISR 内不直接打印。
| 文档 | 何时生成 | 必须包含 |
|---|---|---|
DECISION_TREE.md |
需求不止一种实现路线时 | 板卡、项目、调度模型、调参方式、控制架构分支与选择理由 |
ARCHITECTURE_PLAN.md |
非单模块项目进入代码前 | 需求摘要、调度模型、状态机、FreeRTOS 任务、周期、优先级、队列、中断交接、风险 |
PROJECT_SETUP.md |
没有项目或需要修改配置时 | IDE 设置、时钟、外设、NVIC、DMA、哪些不要开 |
PINMAP.md |
任何硬件相关任务 | 模块、信号、引脚、AF、电压、上拉、风险、来源 |
TUNING.md |
有控制、传感器、执行器时 | 参数表、调参路径、串口输出、正常/异常现象 |
MODULE_BRINGUP.md |
模块接入时 | 接线、单测步骤、期望现象、失败排查 |
TEST_PLAN.md |
独立测试或混合模式 | 测试文件、测试目的、通过标准、合入条件 |
CONTROL_CHAIN.md |
闭环控制系统 | 控制环、频率、单位、输入输出、限幅、依赖 |
| 路径 | 作用 |
|---|---|
dian-sai-mcu/SKILL.md |
Skill 主入口,定义触发场景、首问问题、总体工作流和输出要求 |
dian-sai-mcu/agents/openai.yaml |
Codex UI 元信息 |
dian-sai-mcu/references/workflow.md |
板卡识别到整机联调的完整流程 |
dian-sai-mcu/references/project-file-detection.md |
项目文件读取规则 |
dian-sai-mcu/references/architecture-decision-tree.md |
需求分析、决策树和总体规划入口 |
dian-sai-mcu/references/state-machine-freertos.md |
状态机和 FreeRTOS 编程思想 |
dian-sai-mcu/references/official-docs-policy.md |
官网资料优先级和查证规则 |
dian-sai-mcu/references/pin-allocation.md |
引脚分配表和冲突检查 |
dian-sai-mcu/references/tuning-workflow.md |
调参路径:模块带调、测试带调、混合模式 |
dian-sai-mcu/references/control-pid.md |
多环 PID、死区、滤波、限幅和调参顺序 |
dian-sai-mcu/references/motion-profile.md |
步进三角/梯形/S 曲线运动规划 |
dian-sai-mcu/references/sensor-compensation.md |
现实传感器校准、滤波和补偿 |
dian-sai-mcu/references/communication-protocol.md |
UART/RS485/CAN 调参协议和遥测 |
dian-sai-mcu/references/output-docs.md |
必须输出的项目文档规范 |
dian-sai-mcu/references/m0-reference-scan.md |
从本地 m0 工程提炼的参考表 |
dian-sai-mcu/assets/templates/generic-bsp/ |
通用 BSP、PID、状态机、调参参数模板 |
dian-sai-mcu/assets/templates/docs/ |
DECISION_TREE、ARCHITECTURE_PLAN、PINMAP、PROJECT_SETUP、TUNING、TEST_PLAN 模板 |
显式调用:
Use $dian-sai-mcu,帮我读取这个 STM32 小车工程,分配引脚,生成 CubeMX 配置说明和调参文档。
MSPM0 示例:
Use $dian-sai-mcu,我用 MSPM0G3507 + CCS/SysConfig + 编码器直流电机 + IMU,先单独测试再调速度环和角度环。
新项目示例:
Use $dian-sai-mcu,我还没有工程,板子是 STM32F103C8T6,外设有 OLED、MPU6050、两个编码器电机、8 路循迹和蓝牙串口。请先帮我分配引脚,再生成 CubeMX 设置说明、测试代码清单和调参路径。
重构已有项目示例:
Use $dian-sai-mcu,项目里已经有 main.c、.ioc 和电机驱动,但 PID 参数散在代码里。请先读取工程配置,再把调参窗口前置,生成 TUNING.md,并按模块带我调参。
决策树/FreeRTOS 架构示例:
Use $dian-sai-mcu,我要做一个带 OLED、蓝牙调参、IMU、编码器电机和多模式比赛流程的小车。请先分析需求并生成 DECISION_TREE.md 和 ARCHITECTURE_PLAN.md,判断用裸机状态机还是 FreeRTOS,再开始分配引脚和写代码。