先定义证据,再执行测试
跳转到“先定义证据,再执行测试”一套硬件测试只有把测试条件、操作、实际观察、判据和原始证据连接起来,才能支持验收结论。程序返回 HAL_OK、界面出现绿色勾选,或者内部位置计数改变,都不能单独证明电源、连线和电机正常。
本文将原来的通用十步流程、两套重复的 TMC4361A 测试指南和示例程序,整理为分阶段的板级验证方案。原程序缺少驱动与测试头文件,部分函数直接返回成功;其中“9 项通过、芯片 ID 0x4361”的输出是演示文本,不是测量记录。下面没有声称任何实际电路板已通过测试。
通信实现、四幅原始接线/波形图和轨迹单位见 TMC4361A 与 STM32 控制指南。本文专注于怎样验收这条控制链,避免再维护一份寄存器定义不同的驱动程序。
1. 项目阶段与测试范围
跳转到“1. 项目阶段与测试范围”EVT、DVT、PVT、MP 是常见的项目阶段称呼,具体划分由组织定义,不能只凭名称认定已经符合某项行业标准。
| 阶段 | 主要问题 | 应保留的记录 |
|---|---|---|
| EVT,工程验证 | 原理、接口和关键功能能否成立 | 原理图版本、问题清单、波形、修改前后对照 |
| DVT,设计验证 | 定版设计是否满足各项产品要求 | 需求到测试的对应关系、极限工况、环境与可靠性结果 |
| PVT,生产验证 | 工艺、工装和测试方法能否稳定复制 | 工位程序版本、测试覆盖、重复性、良率与失效分析 |
| MP,量产 | 每台产品是否满足出厂要求 | 序列号、测量结果、判定、返修与复测记录 |
原记录中的十类工作可以放入同一条可追溯的流程:
| 工作 | 具体交付物 |
|---|---|
| 准备 | 板卡、线缆、负载、工具清单;操作条件与人员责任 |
| 外观 | 焊接、方向、缺件、损伤的检查照片 |
| 需求核对 | 每项需求的测量方法、上下限、单位和判定规则 |
| 上电 | 电源设置、限流、启动电流、各电源轨与复位波形 |
| 功能 | 命令、状态、输出和外部实际响应的对应关系 |
| 负载 | 负载配置、温升、误差、响应与限制条件 |
| 校准 | 仪器编号、有效校准状态、量程及测量不确定度处理 |
| 环境 | 温湿度、振动等适用条件、持续时间及前后功能复测 |
| 软件集成 | 固件提交、构建配置、接口协议与故障处理 |
| 记录与追踪 | 原始数据、结论、问题编号、整改和复测 |
长时间运行、温度循环、振动、电源扰动与 EMC 测试应有明确的产品条件和方法;“运行一段时间没有报错”不能代替这些项目。原文中的纹波小于 100 mV、静态电流小于 50 mA、时钟误差小于 0.1% 均没有需求依据,不作为本页的通用合格线。
2. 冻结板卡、接线与版本
跳转到“2. 冻结板卡、接线与版本”先记录板卡型号/序列号、硬件修订、TMC 完整料号、STM32 完整料号、驱动器和电机型号、供电方案、固件提交及构建工具。原稿交替使用 STM32F103RET6 与 ZET6,又给出两套复位/中断接线,不能混为同一块已验证硬件。
STM32F103RE 属于最高 72 MHz、512 KiB Flash、64 KiB SRAM 的高密度型号;RE、ZE 的封装引脚不同,其他 F103 型号也不能照搬这些容量。ST 产品资料
下面保留原测试程序的 PA3 复位、PA2 中断、USART1 日志方案,作为待与原理图核对的例子。控制指南使用另一套 NRST 分配时,应以实际工程为准,不能把两套引脚定义同时复制进去。
| 信号 | STM32 示例 | TMC4361A 或外设端 | 验证重点 |
|---|---|---|---|
| 主控片选 | PA4 GPIO | NSCSIN,2 | 空闲高;整帧期间保持低 |
| 主控 SPI 时钟 | PA5 / SPI1 | SCKIN,3 | 模式 3 与实际频率 |
| 主控读数据 | PA6 / SPI1 | SDOIN,7 | 电平兼容、无悬空或总线冲突 |
| 主控写数据 | PA7 / SPI1 | SDIIN,4 | 与 MISO 不接反 |
| 复位 | PA3 | NRST,39 | 低有效,时序与实际电源/时钟配合 |
| 中断 | PA2 输入 | INTR,33 | 与配置的事件、极性和外部电路一致 |
| 工作时钟 | PA8 / MCO 或独立源 | CLK_EXT,38 | 本例测得 8 MHz 后才采用相应参数 |
| 日志 | PA9/PA10 | USART1 TX/RX | 115200、8N1;确认电平与共地 |
**35 脚是 VDD1V8,不是 CLK16;INTR 是 33 脚,32 脚是 STDBY_CLK。**VDD1V8 是内核稳压相关端,按参考电路去耦。VCC 为 5/26/37 脚,GND 为 6/15/25/36 脚;裸露焊盘与所有去耦按封装和供电章节核对。不能把原清单里的“PC2→35 脚时钟”当作可用接线。
TMC4361A 是轨迹/接口控制器,绕组的 VM 电源、功率级限流、驱动器使能和温度/故障信号属于具体电机驱动电路。“测 VM”“检查 EN”必须写出测量的器件和网络名称,不能凭这些名称假定 TMC4361A 有相应功率驱动引脚。
3. 从断电检查到稳定通信
跳转到“3. 从断电检查到稳定通信”3.1 电源、时钟和复位
跳转到“3.1 电源、时钟和复位”断电完成外观、网络连通、短路与极性检查;按板级设计安排限流供电和驱动器禁用状态。首次上电先观察电流与电源轨,出现异常即停止本轮测试并记录,不能继续自动执行运动项目。
电源记录应包含测量点、负载状态、仪器、量程、探头接法和读数。原程序的 vcc_voltage_mv = 3300 只是常量;未接 ADC 或未录入真实仪表读数,就应记为“未测试”。
用示波器测纹波时可按测试计划采用短接地、AC 耦合和指定带宽,例如 20 MHz 限带;这些设置会影响观察结果,必须随波形保存。只用限带后的纹波图,不能宣称没有更高频噪声。空闲、运动、负载与启动的电流应分开记录,整板输入电流不等于芯片自身电流。
在本例中分别确认 STM32 的 HSE、系统配置以及 TMC CLK_EXT 上实际的 8 MHz。SystemCoreClock 或 RCC 查询函数只说明软件配置,不能证明 PA8 上已有输出;CLK_FREQ=8000000 也不会生成时钟。原程序没有配置 MCO,不能据此推断 TMC 时钟正常。
NRST 拉低后观察寄存器复位和复位事件,保留复位边沿与恢复通信的记录。手册指出 EVENTS(0x0E) bit31 为复位事件;读取 EVENTS 有清除副作用,需要统一消费者。原例中固定延时 10 ms、100 ms 可以是实验等待值,不能写成数据手册规定的普遍最小值。TMC 数据手册,17 章
3.2 SPI 波形与双帧读取
跳转到“3.2 SPI 波形与双帧读取”采用 CPOL=1、CPHA=1、MSB 先传、每帧 5 字节。每次片选低电平必须覆盖完整的 40 个时钟;“CS 低脉宽超过 100 ns”显然不足以说明一帧完整。
TMC 的 SPI 时钟受实际芯片时钟约束,上限为其四分之一。本例 8 MHz 下使用 PCLK2=72 MHz、SPI 分频 64,得到 1.125 MHz,低于 2 MHz 上限;原来的 2.25 MHz 方案不符合这一例子的限制。
这是 40 个时钟本身的时间,尚未包含片选建立/保持、帧间高电平和软件间隙。不能用它代替完整事务实测时长。帧间时序还要满足手册 3.1.1 节;控制指南的 1 μs 留量是该示例的实现选择。
逻辑分析仪可按 CH0=SCK、CH1=MISO、CH2=MOSI、CH3=CS,模式 3、8 位解码,并用 CS 下降沿触发。选择足够的采样率,确认电平门限;数字解码正常不能代替示波器对过冲、边沿和信号完整性的检查。
| 操作 | MOSI 首字节 | 同帧 MISO 数据的含义 |
|---|---|---|
| 请求版本寄存器 | 0x7F | 前一次事务的数据,不是本次版本 |
| 紧接着请求 STATUS | 0x0F | 上一帧请求的版本数据 |
| 请求 XACTUAL | 0x21 | 前一次事务的数据 |
| 紧接着请求 STATUS | 0x0F | 上一帧请求的 XACTUAL |
其余四个 MOSI 字节为读取占位值。每帧同时返回的首字节是所选的 8 位 SPI 事件状态,不能把它当作 32 位 STATUS。两帧之间保持总线所有权,检查底层传输结果;失败时恢复 CS 高并结束该测试项。读取全零或全一需要结合波形、已知配置和供电判断,不能单靠这个模式认定芯片不存在。
3.3 版本与受控回读
跳转到“3.3 版本与受控回读”手册 19.31 节给出只读版本寄存器 0x7F,低 16 位默认值为 0x0002;应保存完整 32 位原始响应并与实际料号/版本资料核对。官方 API 也定义 VERSION_NO=0x7F,其字段掩码与手册表述不同,不能据其中一个片段杜撰 0x4361 产品 ID。版本读数是通信证据之一,不能代替器件身份和全部功能验证。
原稿中的以下名称来自混用或缺失定义:
| 原说法 | TMC4361A 中应核对的内容 |
|---|---|
GSTAT=0x01 | 0x01 为 REF_CONF;当前状态读 STATUS 0x0F |
IFCNT=0x02,每访问一次递增 | 0x02 为 START_CONF,没有该接口计数测试 |
CHIPINFO_DATA 高 16 位得到 0x4361 | 不使用缺失定义;读取并记录版本寄存器 0x7F |
VTARGET 控制速度 | 本页轨迹速度目标使用 VMAX,地址 0x24 |
| RAMPMODE=0 为定位 | 0 为无斜坡速度模式;梯形速度/定位分别为 1/5 |
| STEP_CONF bit0 使能输出 | 低四位编码微步设置,不是通用使能位 |
寄存器回读先选择有明确读写权限、位宽、复位值和副作用的项目。在驱动禁用、轨迹静止的受控配置阶段,可写入实际使用的 CLK_FREQ=8000000并通过双帧读回核对;必要时按测试计划恢复原配置并再次确认。该回读只验证这一个配置通路,不证明所有寄存器都正常。
不要向 GENERAL_CONF 写 0x12345678 或 0xFFFF 做“随机通信测试”,也不要把这些值写到 VMAX。前者会改变工作模式和引脚功能,后者可能产生运动目标。写后紧跟的回送也不等同于寄存器有效值,仍需发起真正的读请求。发生写超时时,芯片可能已经收到命令;停止推进流程、重新核对状态,不盲目重发。
4. 原九项测试应怎样产生结论
跳转到“4. 原九项测试应怎样产生结论”基础条件未满足时,下游项目标记为“阻塞”,不能继续跑完后只把总结果改为失败。下表保留原九项的目的,并补齐其证据边界。
| 测试项 | 需要的实际观察 | 合格判据与边界 |
|---|---|---|
| 硬件连接 | 原理图核对、断电连通/绝缘检查、实际信号 | 逐网络符合设计;HAL 状态 READY 仅表示软件句柄可用 |
| 供电 | 仪表/ADC 的真实读数、启动和负载波形 | 依据该板电源预算及器件规格;固定 3300 常量不参与判定 |
| 复位 | NRST 波形、默认配置、复位事件及重新通信 | 符合已批准的板级时序;拉低后等待不能自动算通过 |
| SPI | 完整帧、模式、时钟、电平、成功/失败计数 | 结合物理波形和已知读数;不是仅看 HAL 返回值 |
| 芯片响应 | 原始版本字、料号记录、重复稳定读取 | 与版本资料匹配;不是虚构产品 ID,也不证明其他功能 |
| 寄存器访问 | 受控配置写入、独立读回、恢复及恢复回读 | 只覆盖所测地址和字段;失败恢复也记录,不静默忽略 |
| 基本运动 | 轨迹状态、STEP 计数、外部位置/速度观察 | 参数/期限符合计划,启动和停止均完成;VACTUAL 非零只证明内部轨迹在变化 |
| STEP/DIR | 高低时间、幅度、频率、方向建立时间与脉冲数 | 满足实际驱动器输入规格;延时 200 ms 后返回成功不构成测量 |
| 中断 | 已知事件、INTR 电平变化、MCU 捕获、清除过程 | 事件/屏蔽/清除策略一致;等待 100 ms 不构成触发证据 |
中断验证应选可控事件,记录 INTR_CONF 选择、EVENT_CLEAR_CONF 策略、事件产生条件及 MCU EXTI 计数。原例只配置输入上拉,没有展示完整 EXTI/NVIC、处理函数与捕获证据,不能声明“MCU 中断功能已完成”。默认读 EVENTS 会清除相应事件;寄存器转储也可能改变测试状态,应区分常规只读监控与显式消费事件。
5. 从空载轨迹到真实机械响应
跳转到“5. 从空载轨迹到真实机械响应”通信、供电和复位通过后,先在驱动器禁用状态检查轨迹与 STEP/DIR 输出,再依板级方案进入低速、短行程的实际运动。测试计划预先给出行程边界、期限、故障动作和停止方法;这不是从本文复制一组参数就能得到的结论。
速度、加速度使用手册规定的不同定点单位,具体换算见控制指南。先设置静止目标和可核对的配置,再允许运动;定位使用 RAMPMODE=5 等明确模式,不能沿用原稿的模式 0。
例如 1.8° 电机、16 微步和 60 RPM 对应 3200 pulse/rev、3.2 kHz。用分析仪统计输出脉冲,再与编码器或独立测量的位置/速度对照;内部 XACTUAL/XTARGET 相等不能排除失步。验证加速、稳速、减速、反向和停止时,分别保留时间轴和误差,而非只读取某一时刻的 VACTUAL。
限位、急停、过压/过流和温度等项目先分配到具体控制器、驱动器和硬件回路,写出预期响应、输出状态和恢复条件。不能笼统声称一个 TMC 状态位覆盖所有保护。断电、失联、超时、退出菜单与复位都要有明确处理;程序停止打印不等于电机停止。
编码器选装时,记录供电/电平、A/B/N 接线、分辨率和比例,手动转动核对方向与计数,再测闭环误差。未安装编码器可按批准范围记“不适用”,不能据此把闭环精度项目判为通过。
6. 测试软件与诊断菜单
跳转到“6. 测试软件与诊断菜单”原文件分工仍然有用:
| 模块 | 应负责什么 |
|---|---|
| TMC 驱动 | 一帧传输、事务独占、双帧读、返回值与寄存器边界 |
| 测试配置 | 板型、引脚、版本、判据、测试期限及允许执行的项目 |
| 测试执行器 | 检查前置条件、调用观测接口、判定、保存证据、处理失败 |
| 主程序 | 时钟/外设、人员操作、状态机与已验证的停止路径 |
| 报告与日志 | 记录实际结果、耗时和原始证据链接,不合成成功读数 |
USART1 仍可使用 115200、8N1。菜单 1/2 分别触发已定义的基础/完整计划,3–7 执行连接、通信、版本、回读和运动单项,8 做受限状态快照,9 查看当前结果,R 请求受控复位,M 显示菜单,Q 结束计划。每个动作仍需检查当前阶段;Q/R 不能绕过运动停止与重新初始化。
自动、快速、自定义、连续模式使用同一套用例定义,只改变选择和重复次数。连续测试记录运行次数、时长、首次失败、错误计数及原始证据;不能每轮清零全局状态后只显示最后一次成功。
原示例软件需要同时修正这些问题:
- 每轮初始化报告及状态快照,避免上轮的
chip_detected=true留在本轮失败后。 - 区分通过、失败、执行错误、阻塞、未测试和不适用;无测量不能默认为通过。
- 所有通信和等待有明确期限;HAL 超时依赖可运行的时基。原
__disable_irq()后调用HAL_Delay()的错误循环可能永远不再闪灯。 - 不重写工程已经提供的 SysTick/中断入口,不把零散头文件当成已链接完整固件。
- UART 日志使用有界输出并检查结果;
HAL_MAX_DELAY可能阻塞测试和故障处理。 - 记录失败的恢复动作、报告容量不足与日志截断;不能超过 20 项就静默丢失记录。
- 无已执行项目时不要计算
passed/total;不把阻塞和不适用都算作普通失败或从完成度中悄悄消失。
7. 报告必须保留“未测试”
跳转到“7. 报告必须保留“未测试””下面是 Python 3.11 的离线报告示例。它演示测量判据与执行状态的分离,不会访问硬件,也不会证明板卡合格。数值上下限只能由批准的测试要求提供;单项范围判断仍不包含仪表不确定度和测量方法是否正确的审核。
from collections import Counterfrom dataclasses import dataclassfrom enum import Enumfrom math import isfinite
class Status(str, Enum): PASS = "PASS" FAIL = "FAIL" ERROR = "ERROR" BLOCKED = "BLOCKED" NOT_RUN = "NOT_RUN" NOT_APPLICABLE = "NOT_APPLICABLE"
@dataclass(frozen=True)class Result: name: str status: Status evidence: str
def range_result(name, value, lower, upper, unit, required_unit, evidence): def finite_number(number): return type(number) is int or (type(number) is float and isfinite(number))
if not all(finite_number(x) for x in (lower, upper)) or lower > upper: return Result(name, Status.ERROR, "Invalid configured limits") if not required_unit or unit != required_unit: return Result(name, Status.ERROR, "Unit mismatch") if value is None: return Result(name, Status.NOT_RUN, "No observation") if not finite_number(value) or not evidence.strip(): return Result(name, Status.ERROR, "Invalid observation or missing evidence") status = Status.PASS if lower <= value <= upper else Status.FAIL return Result(name, status, evidence)
def summarize(results): if len({row.name for row in results}) != len(results): raise ValueError("Duplicate test name") if any(not row.name or not isinstance(row.status, Status) for row in results): raise ValueError("Invalid result") if any(row.status != Status.NOT_RUN and not row.evidence.strip() for row in results): raise ValueError("An executed/blocked/excluded item requires evidence or reason") counts = Counter(row.status for row in results) applicable = len(results) - counts[Status.NOT_APPLICABLE] if applicable == 0: overall = "NO_APPLICABLE_TESTS" elif counts[Status.FAIL] or counts[Status.ERROR]: overall = "NOT_ACCEPTED" elif counts[Status.BLOCKED] or counts[Status.NOT_RUN]: overall = "INCOMPLETE" else: overall = "PASS" return overall, {status.value: counts[status] for status in Status}
if __name__ == "__main__": # Synthetic limits and observation exercise software; not a hardware specification. rows = [ range_result("frame time", 35.6, 35.0, 36.0, "us", "us", "synthetic example"), Result("supply", Status.NOT_RUN, "No instrument reading"), Result("motion", Status.BLOCKED, "Supply test has not passed"), ] overall, counts = summarize(rows) assert overall == "INCOMPLETE" assert counts["PASS"] == 1 and counts["NOT_RUN"] == 1 and counts["BLOCKED"] == 1 print(overall, counts)演示中只有一个合成的逻辑分析仪读数,供电与运动仍未测试,因此整体必须是 INCOMPLETE。即便所有软件断言通过,也只是说明报告程序按所列规则工作。
实际记录至少包含:
| 字段 | 应填写的内容 |
|---|---|
| 样品与版本 | 序列号、硬件修订、器件/驱动器型号、固件提交与构建配置 |
| 条件 | 电源、负载、温度、设备连接及测试前状态 |
| 仪器 | 编号、校准状态、量程、带宽/采样率/探头配置 |
| 用例与要求 | 唯一用例编号、要求编号、单位、判据及适用范围 |
| 观察 | 实测值、波形/日志文件、时间戳、操作者;未测留空并说明原因 |
| 结果 | PASS/FAIL/ERROR/BLOCKED/NOT_RUN/NOT_APPLICABLE,不使用预填勾选 |
| 异常与复测 | 问题编号、处置、修改版本、新证据以及复测结论 |
原演示里的“9/9、1247 ms、100%”不得直接复制到真实报告。测试计划、演示输出、离线代码检查和实际硬件验收是四种不同记录。
8. 根据证据排查
跳转到“8. 根据证据排查”| 现象 | 优先检查 | 不能直接下的结论 |
|---|---|---|
| 读数全 0 / 全 1 | 供电、CLK_EXT、复位、电平、CS 帧长、双帧顺序、MISO | 仅凭一个数值判芯片损坏 |
| 写入/回读不同 | 权限、字段宽度、写回送与真正读回、复位或并发事务 | 所有地址都应原样保存任意 32 位值 |
| 内部位置变而电机不动 | STEP/DIR、电平/脉宽、驱动使能与报警、电机/机械连接 | 内部计数能证明机械到位 |
| INTR 有变化而 MCU 无捕获 | 引脚分配、EXTI/NVIC、极性、清除策略与处理耗时 | TMC 事件位变化自动证明 MCU 中断正确 |
| 日志或菜单卡住 | HAL 时基、串口阻塞、总线等待、错误处理与锁 | 卡住期间控制器一定停止运动 |
| 负载/温度变化后异常 | 条件与波形对比、电源预算、驱动/机械限制、通信错误计数 | 常温空载通过能覆盖全部环境 |
资料依据:原始测试记录、TMC4361A V1.26 数据手册、固定版本的官方寄存器定义、STM32F103RE 产品资料。这里只核对与本测试方案相关的章节,不代表完整硬件认证或整本手册审查。