OUT / 03 · 上板验证清单 · 样张
上板验证清单 · 样张:客户板到货前,先在同族开发板上把能验的都验掉
一个从某国产 Cortex-M4 移植到 STM32C531 的电源类控制板项目,代码写完时客户样板还没到。我们按验证清单在同族的 NUCLEO-C542RC 开发板上先跑:8 个外设步骤逐个通过,受控出波的 T0~T6 全部通过(含后来追加的 T3b),另有 1 项 T3c 部分通过、照实标为未验收;过程中抓出 4 个客户板上必然会复现的真问题。客户板到货后只需复测板级差异项。
这份清单解决什么问题
- 板子到了先验什么、后验什么:从不上电的静态检查,到逐个外设单步验证,再到出波前的强制关卡,最后才上控制环。一次只验一步,前一步通过才进下一步。
- 看到什么算对:每条判据都写清预期值和测量方法,而且预期值是现场读源码算出来的,不凭记忆、不信注释。
- 出了问题先查哪:每一阶段配一张异常对照表,先查软件和接线,再动硬件。
- 烧录和测量次数压到最少:能用读寄存器确认的,不再上示波器;一次上电能验几项就验几项。
清单的结构
| 阶段 | 内容 | 出口条件 |
|---|---|---|
| 0 · 上电前 | 编译零 warning;供电、晶振、刹车输入上拉、死区参数等静态确认 | 全部确认,不上电也能完成 |
| 1 · 单步验证 | 时钟 → GPIO → 时基 → 串口 → ADC → DMA → FLASH → PWM 骨架,每步一个独立测试程序,不出波 | 8 步全部通过 |
| 2 · 出波前强制关卡 | 阶段 1 全绿;刹车输入能立即关断 PWM;低压、限流、假负载 | 全部通过才允许上功率 |
| 3 · 控制环上电 | 集成固件,低压限流台架,逐项验证保护与标定 | 目标板实测通过才算完成 |
节选两条阶段 1 的判据,看写法:
| 步骤 | 判据 | 怎么测 |
|---|---|---|
| 时钟 | 时钟输出引脚 = 系统时钟 ÷ 8 = 18 MHz,即系统时钟 144 MHz | 示波器 |
| FLASH 标定参数 | 发标定命令 → 回「已保存」→ 断电重启后参数保持 | 串口 + 断电 |
在同族开发板上的执行结果
客户的 STM32C531 样板没到,我们拿到了 NUCLEO-C542RC:同一份参考手册(RM0522)、同一系列。先核对两颗芯片的差异:中断号、外设基址、引脚复用逐项对过,芯片层面唯一必须改的是内部时钟基准(8 → 24 MHz);开发板上另有个别引脚和板载器件冲突(例如指示灯换了一个脚)。两者用同一个编译开关切换,不动业务代码。
阶段 1:8 个单步验证在一天内全部通过。
阶段 3 的受控出波:开发板上没有功率级,出波只是 MCU 引脚上的电平,没有电气风险。转速信号用的是示波器前面板自带的探头补偿方波,零元件、零代码改动。
| 项 | 判据 | 实测 | 结果 |
|---|---|---|---|
| T0 | 转速信号识别正确,起机条件满足 | 读数与理论值偏差约 0.03% | 通过 |
| T1 | 起机后出互补 PWM,载波约 30 kHz | 30.025 kHz(频率计),两对互补无重叠 | 通过 |
| T2 | 死区约 278 ns(±20 ns) | 279.00 ns / 279.00 ns(两个方向,光标法),偏差 +0.4% | 通过 |
| T3 | 刹车输入拉低,PWM 立即由硬件关断;释放后下一个更新事件自动恢复,无需复位 | BDTR 从 0xD028 变为 0x5028(MOE 清零),释放后回到 0xD028 | 通过 |
| T3b | 计数器停着时,刹车释放后不得提前恢复 | 释放后仍无 PWM;只置 CEN 后第一个更新事件恢复约 30 kHz | 通过 |
| T3c | 软件故障触发后能清除并恢复出波 | 代码路径和故障前态已确认;开发板上只能给采样通道接地或接 3.3 V 两个极端电平,恢复后又立即触发保护,拿不到稳定的最终判据 | 部分通过,未验收 |
| T4 | 遥测帧逐字段正确,500 ms 一帧 | 各字段与在线读寄存器、FLASH 存值三方一致 | 通过 |
| T5 | 标定参数加 / 减 / 保存 / 复位读回 | 四步全部命中;保存瞬间 PWM 短暂中断,寄存器确认没有失控 | 通过 |
| T6 | 控制中断单次耗时小于 66.7 µs(15 kHz 周期) | 90 次采样中 47 次落在该中断内,折算约 34.8 µs,余量约 48% | 通过 |
T5 那次「保存瞬间 PWM 短暂中断」是预告过的现象:擦 FLASH 时 CPU 取指被阻塞,控制中断会冻结几毫秒。它换来一条交给客户的操作告诫:标定参数要在停波或轻载状态下保存。
两个判据写法的例子
- 判据来自源码,不信注释。 集成冒烟那一步,源码注释写某个计数「卡在 1」,按代码逐行读出来应该是 2,判据写的是 2,实测也是 2。按注释写判据,这一步会被误判为失败。
- 测不到就照实写「未验收」。 T3c 的代码路径已经确认,但开发板上凑不出稳定的中间电平,恢复后会立刻再次触发保护。我们没有为了让它通过去改保护阈值、加分压电阻,而是把它标为部分通过、留到客户板复验。
执行中抓出的 4 个真问题
它们在客户板上一样会出现,提前在开发板上修掉了:
- ADC 读数卡在 3568。 ADC1_IN7 由两个引脚共用、复位默认接错了那一个。完整过程见 CASE/01。
- FLASH 写入静默失败。 STM32C5 的最小编程单位是 128 位,按 64 位写完后必须再置一个强制提交位,否则数据不落地,也没有任何错误标志。
- FLASH 擦除寻址错误。 驱动按「每页 2 KB」计算页号,而这颗芯片实际是每页 8 KB、分两个 bank。第一次保存看起来成功,第二次保存就会让参数区损坏、上电读参数时卡死,等于现场标定到第二次就变砖。
- 测试程序的采集时序。 ADC 触发后先打印、再等转换完成,串口一个字符约 1 ms,远比 6 个通道约 50 µs 的转换慢,导致一直等不到。这是测试脚手架的问题,不在产品代码里。
验证方法上的几个做法
- 不占调试口读寄存器和内存:用 STM32CubeProgrammer 命令行以不复位的方式连接,直接读外设寄存器和 RAM 变量,示波器只用来确认寄存器给不了的物理量。
- 中断耗时零改码测量:随机暂停内核,读当前异常号,统计有多少次落在目标中断里,再按中断频率折算单次耗时。不用加 GPIO 翻转、不用改代码。
- 现成设备当信号源:示波器前面板的探头补偿端子本身就是一个约 1 kHz 的方波源,拿来当转速信号,免去一台信号发生器。
验证边界
| 项 | 状态 |
|---|---|
| 阶段 1 的 8 个单步 | 同族开发板实测通过 |
| 受控出波 T0~T6 | 同族开发板实测通过 T3c 部分通过、未验收 |
| 功率级死区是否足够防直通 | 未测 开发板没有功率级 |
| 真实模拟前端与标定、三环控制、各项保护阈值 | 未测 留客户板 |
| 客户 STM32C531 板 | 样板未到 一项都没测;项目完成数仍为 0 |
同族开发板上通过,不等于客户板通过。清单的勾选框留给客户板实测,不拿开发板的结果代勾。
结论—依据—验证状态对照
| # | 结论 | 依据 | 类型 |
|---|---|---|---|
| 1 | C531 固件可在 C542 上运行,唯一必改是内部时钟基准 | 两颗芯片同属 RM0522;中断号、基址、引脚复用逐项核对(项目阶段 0 差异查证记录) | 项目核对记录 |
| 2 | 死区理论值 277.8 ns | DTG = 0x28 = 40,DT = DTG × tDTS(RM0522 Rev 1 §31.6.20,第 1101 页);CKD = 00 时 tDTS = 定时器时钟周期(第 1061 页),144 MHz 下为 6.944 ns | 手册原文 + 计算 |
| 3 | 死区实测 279.00 ns | 示波器光标法,两个方向各测一次 | 实测 |
| 4 | 刹车时硬件清 MOE;AOE = 1 时在下一更新事件自动恢复 | RM0522 §31.6.20 TIM_BDTR 的 MOE / AOE 位,第 1100 页 | 手册原文 |
| 5 | T3 / T3b 行为与手册定义一致 | 各状态下 CR1 / SR / BDTR 读回值 + 示波器 | 实测 |
| 6 | 控制中断单次约 34.8 µs | 90 次随机暂停读异常号,47 次命中 | 实测(统计估算) |
| 7 | 4 个真问题在客户板上会复现 | 均为驱动或配置层面的问题,与开发板无关 | 推断 |
| 8 | 客户板上全部通过 | — | 未验证 |
「实测」均在 NUCLEO-C542RC 同族开发板上完成。
需要一份验证清单
需要为一个移植或新开发的项目准备上板验证清单,发来这几项就能开始:芯片型号、工程现状(编译是否通过、有没有老工程)、手上有哪些板子和仪器、哪些功能在上功率前必须先确认。