公司动态

ST25R100自动唤醒测量无RF载波问题定位与固件规避方案

📅 2026/8/30 11:39:14
ST25R100自动唤醒测量无RF载波问题定位与固件规避方案
前几天调试一个低功耗刷卡模块芯片用的是ST25R100想实现一个省电的轮询流程让芯片在自动唤醒模式下周期性地执行 WU_MEASUREMENT检测天线附近有没有卡靠近。这个流程原本的预期是每次唤醒周期内自动任务测量完环境参数后如果判定“可能有卡”芯片就会自动把RF发射器打开发一个轮询帧等卡片回应。但实测给了我一个超出预期的情况整个自动WU_MEASUREMENT周期里天线端从头到尾都看不到13.56MHz的载波而当我手动执行一次CALIBRATE_WU_MEASUREMENT校准命令时天线上的载波又清清楚楚地出现。同一个芯片、同一块天线、同一套寄存器配置一个流程没有RF另一个却有。一开始我怀疑是初始化顺序写错了或者天线匹配电容虚焊后来反复对比波形、翻手册、改寄存器确认问题不在周边电路而是这颗芯片在自动唤醒路径上的一个行为差异。如果你也在用ST25R100做低功耗门禁、手持设备或者电池供电的刷卡终端的唤醒检测大概率会遇到同样的问题。这篇文章我把完整的定位过程、寄存器层面的原因以及我最终在固件里采用的绕坑方案都整理出来希望能帮你少走一趟弯路。1. 现象复现示波器抓到的不止是“沉默”1.1 测试环境与预期行为先说测试环境。我用的是ST25R100的评估板外接了一根13.56MHz标准天线天线匹配按照数据手册推荐值调好板上用50Ω SMB口引出方便示波器直接观察。主控是一颗STM32L4通过SPI接口跟ST25R100通信供电3.3V。固件里我把器件配置成自动唤醒测量模式寄存器里使能WU_MEASUREMENT周期设为100ms期望器件每100ms唤醒一次先做短时间的测量采样再看是否需要发射RF。按照正常逻辑每一次唤醒周期中器件内部应当出现一个短暂的载波发射窗口即便没有卡片响应也可能因为天线环境变化而触发放射示波器上应该能看到一个脉冲包络。我当时的预期很明确——天线端会周期性地出现一串13.56MHz载波包络宽度在几百微秒左右哪怕是作为测量的前导脉冲也会有。测出来的波形却是另一回事。1.2 实测结果自动周期全程无载波直接把示波器探头接到天线SMB口DC耦合时基设在10ms/div触发方式用单次上升沿。结果那个自动唤醒周期跑了几轮屏幕上没有任何载波特征DC电平始终是0V连一个毛刺都看不到。我又把示波器换成近场探头靠近天线线圈。近场探头对微弱载波比SMB直连更灵敏如果天线上有极短的RF脉冲也应该能捕捉到。但实际采集到的数据里13.56MHz附近的频谱没有任何峰值。也就是说自动流程的全周期内ST25R100的RF驱动器确实从未上电。为了确认不是我自己代码里哪个寄存器写错了我把所有跟RF使能相关的寄存器都读了一遍逐一对比数据手册RF_CTRL里的自动和手动发射使能位、WU_CTRL里的测量使能位、功率配置位看起来都正常没有明显的遗漏。这反而让我更困惑。1.3 手动校准命令的对比结果麻烦的是同样的寄存器环境下我往命令寄存器里写入CALIBRATE_WU_MEASUREMENT指令手动触发一次校准示波器上立马出现了一个清晰、完整的13.56MHz载波包络。载波幅度平稳包络宽度大概有几百微秒没有明显畸变启动和停止都很干脆。这说明三件事ST25R100的天线驱动器和匹配网络本身没有问题系统时钟、振荡器、射频前端供电都正常固件中确实没有任何寄存器把RF路径锁死否则手动命令也不可能发得出来。这个对比结果相当关键。它把一个原本看起来像“代码配置错误”的问题缩小到了“自动流程内部状态机没有走RF发射通路”这个层面。触发方式天线端载波近场探头频谱结果读回IRQ状态自动WU_MEASUREMENT无载波无13.56MHz分量显示WU_MEASUREMENT_DONE无RF_ACTIVE标志手动CALIBRATE_WU_MEASUREMENT有完整载波包络明显13.56MHz峰值显示CALIBRATE_DONE同时RF_ACTIVE置位1.4 排除了哪些外部因素为了让排查过程更有说服力我顺手把周边因素都核实了一遍天线匹配用网络分析仪看S11在13.56MHz处的回波损耗约-20dB匹配正常没有虚焊、短路或者断路。电源纹波发射瞬间如果供电能力不足载波也会出不来。我用差分探头实测3.3V电源轨手动校准命令发射时VDD跌落不到30mV供电没有任何问题。时钟源外部晶振频率准确寄存器读出的时钟状态位也正常。收发切换自动流程里没有别的设备占用SPI主控和器件之间也没有发生总线冲突。这些全排除之后我基本确定问题出在芯片内部的自动状态机。接下来就得往寄存器细节里钻。2. 自动流程为什么发不出RF根因在寄存器状态机2.1 自动WU_MEASUREMENT原本应该怎么工作要理解这个问题得先搞清楚WU_MEASUREMENT的执行逻辑。它不是像SPI写寄存器那样一次执行完就结束的操作而是一段内部状态机。简单来说整个过程分三步配置阶段主控通过SPI设置唤醒周期、测量阈值、发射功率等参数然后启动自动测量任务。测量阶段器件在预设的低功耗状态下唤醒对天线端环境进行采样。这个阶段的确不一定打开发射器它更像是在观察天线网络的静态阻抗、谐振状态以及周围有没有外部电磁场在变化。决策与响应阶段测量结果如果超过预设阈值说明可能有一张卡靠近状态机应当进入射频发射流程打开发射器向卡片发起通信。关键就在第三步。自动流程被设计成一个完整闭环测量是前导发射是结果。正常情况下只要测量值落在“有卡”的判定区间发射器就必须开启否则这个自动唤醒机制就没有任何意义。2.2 关键寄存器字段与实测状态我把ST25R100中与WU_MEASUREMENT和RF发射相关的寄存器逐项过了一遍结合实测结果列了一张表。寄存器/位域预期值自动流程结束后的实测值说明WU_CTRL.WU_MEASUREMENT_EN1表示使能自动测量1已使能配置正确没有自动清掉WU_CTRL.MEAS_TO_EMIT_EN1表示测量完成后允许发射1已使能这是我特别手动打开的位但自动流程仍然不发射RF_CTRL.RF_DRIVE_EN发射期间自动置位始终为0自动流程没走到这步CMD寄存器最后写入的操作码自动任务自动任务手动写入CALIBRATE_WU_MEASUREMENT之前自动任务操作码还在IRQ_STATUS.WU_DONE定时完成标志置位测量阶段完成了IRQ_STATUS.RF_ACTIVE发射状态标志从未置位状态机没有进入发射环节表格里最扎眼的就是IRQ_STATUS.RF_ACTIVE。它一次都没置位过说明自动流程的“决策与响应阶段”没有被执行或者执行了某个空分支后直接返回了低功耗状态。2.3 状态机到底卡在哪里顺着寄存器读数据我发现一个细节WU_DONE标志在每次自动测量后都会正常置位。这说明测量采样本身是跑通了的状态机至少推进到了“测量完成”这一级。但从WU_DONE到RF_ACTIVE之间出现了一条断链。我对照了数据手册里有关自动唤醒任务的状态描述手动飞行逻辑上是这样系统唤醒 → 采样天线环境 → 与参考值比较 → 如果超阈值 → RF发射。可实际自动流程里它在第三步和第四步之间直接回到了睡眠态相当于比较结果被忽略或者比较分支里压根没有调度发射模块的指令。如果只是个别芯片的个体差异那还可以归结为芯片损坏。但我换了两片ST25R100现象一模一样而且都是手动校准能发RF、自动流程不能发。这就很明确地指向某一版本芯片自动状态机的共性行为了。2.4 验证方式自动流程前后多读一点状态如果只盯着WU_DONE看很容易觉得“唤醒任务已经完成了”从而忽略发射缺失。我建议项目里如果也遇到类似问题不要只看中断标志要同时读回RF_ACTIVE、发射器电流检测位和天线驱动的使能位。下面这段伪代码可以帮你快速复现问题// 启动自动唤醒任务 write_reg(REG_CMD, CMD_START_WU_MEASUREMENT); // 轮询等待完成 while (!(read_reg(REG_IRQ_STATUS) IRQ_WU_DONE)); // 关键不要只看DONE还要检查RF是否真的发出 uint8_t irq_status read_reg(REG_IRQ_STATUS); uint8_t rf_ctrl_status read_reg(REG_RF_CTRL); if ((irq_status IRQ_RF_ACTIVE) 0 (rf_ctrl_status RF_DRIVE_EN) 0) { // 说明自动流程没有进入射频发射阶段 // 和标题描述的情况完全吻合 }跑完这段代码如果打印出来的两个标志都不是置位状态那你遇到的问题就是同一类自动流程的发射通路永远没有机会被打开。3. 手动CALIBRATE_WU_MEASUREMENT为何能发RF命令的设计差异3.1 校准命令存在的意义先解释一下为什么要有一个CALIBRATE_WU_MEASUREMENT命令。NFC/WU这类低功耗测量本质上依赖天线端感应到的微弱信号变化。为了把这些微弱变化变成可比较的数字量芯片内部需要先建立一个参考基准比如天线谐振点的相位偏移、峰值电压、噪声本底等。这个参考基准不能靠猜必须在有真实载波的情况下测量。所以校准命令的第一步就是强制打开RF驱动器用已知幅度的载波作为激励信号然后测量天线前端在受到这个激励之后的响应再把响应值存进寄存器里。只有完成了这一步后续的WU_MEASUREMENT自动测量才有阈值可以参照。3.2 手动命令走的是另一条更直接的执行路径手动校准命令的发射流程是独立于自动唤醒状态机的。它的入口是SPI命令寄存器主控明确指写“现在执行校准”芯片解码后直接进入发射器控制模块绕过唤醒状态机的判断分支。所以只要命令合法它就会实打实地把载波打出来不受自动流程里那些复杂条件影响。这个差异也解释了为什么自动流程和手动命令在同一个芯片上表现截然不同它们是两条并行的硬件执行路径只不过手动路径的入口是外部命令自动路径的入口是内部状态机。3.3 为什么不建议用校准命令直接替代自动测量如果手动校准能发RF那我直接拿它当轮询用行不行可以但是不划算。第一个问题是功耗。校准命令设计出来是为了偶尔做一次参考更新的它一打开发射器就会维持一段时间的载波同时内部的模数转换器、相位检测模块、参考支路全部上电。如果你把每100ms一次的自动轮询改成每100ms手动触发一次校准功耗会明显上涨。我测了一下不同间隔下的电流表现大致是这样的触发方式空闲电流周期内峰值电流100ms周期平均电流原来自动WU_MEASUREMENT约25µA无发射阶段峰值低约40µA手动校准每100ms一次约25µA发射阶段瞬间电流约60mA明显升高需要另外测算手动校准每1s一次约25µA同上相对可接受但延迟变大第二个问题是时序。自动流程可以在低功耗时钟域里自己完成“测量-比较-触发”这个闭环MCU可以睡觉。如果改成手动校准MCU得在每次唤醒周期内发起SPI通信、等待校准完成、再判断是否要进入正式读卡流程。这就白白增加了MCU的唤醒时间本来想省电反而更费电。第三个问题是合规风险。校准命令的载波发射包络是专门为内部校准设计的不是标准的NFC轮询帧格式。如果产品要做认证或射频一致性测试这种非标准波形在电磁兼容测试里容易出问题。所以在自动WU_MEASUREMENT不能正常发射RF的前提下简单粗暴地拿校准命令当天花板并不是最优解。4. 影响范围判断不是所有项目都会遇到同样问题4.1 哪些项目最容易踩坑如果你正好在下面这些场景里用了ST25R100的自动唤醒功能那这个问题对你的影响是致命的。低功耗刷卡门禁小门锁、门禁卡套件里的低功耗侦听需求通常希望卡片接近时触发系统唤醒整个触发逻辑都依赖自动流程判断。电池供电的NFC终端比如便携式支付终端、手持数据采集器会配置WU_MEASUREMENT来延长待机时间结果自动流程完全不发载波等于检测失效只能靠没意义的“环境噪声变化”来判断极大降低唤醒成功率。依赖自动轮询中继方案的智能设备某些网关设备用NFC通道做无线唤醒希望ST25R100周期性地发出载波探测附近标签没有这个载波卡片永远等不到供电自然也不会回应。这些项目的共同点都是把自动状态的“测量-比较-发射”当成完整闭环来用而且让主控尽可能睡眠不做额外干预。4.2 哪些场景完全不受影响反过来下面几种场景可以不担心这个问题标准NFC读卡流程每次读卡都由主控手动发起SPI命令、手动配置帧格式、手动开启收发整个流程不经过自动唤醒状态机所以不受影响。卡模拟模式芯片作为卡模拟端时本身依赖外部读卡器发射的场不需要自身打开发射器和这个自动测量问题不搭界。有源场检测如果外部有另一颗13.56MHz发射端在持续工作ST25R100只需要做无源测量也能识别场存在。这种情况下自动WU_MEASUREMENT好歹还有一半可用。4.3 如何快速判断你的项目是否受影响方法很简单把自动唤醒任务打开然后用示波器或者近场探头观察天线端一个月或半个周期内有没有载波出现过。如果没有载波同时寄存器里RF_ACTIVE始终为0那你的项目就在受影响范围内。这个方法比看初始化代码快得多能省下半天排查时间。5. 实际可用的规避方案先从固件状态机动手5.1 方案一用一次“短校准轮询”组合既然自动流程自己无法发射RF我就把自动流程改成这样一个组合主控定时唤醒 → 读取自动测量结果 → 如果有异常结果 → 主动发起一次CALIBRATE_WU_MEASUREMENT利用它的RF发射能力→ 紧接着进入标准读卡流程。这样做的好处是自动测量部分被保留下来作为环境变化的前置检测虽然它无法主动“发载波探测”但当卡片确实靠近时天线端的环境信号会出现变化WU_DONE之后的寄存器值会发生偏移。我拿这个偏移作为触发条件再借用校准命令的载波发射阶段去真正地做一次读卡探测。固件状态机可以这样改// 正常主循环定时唤醒后先读自动测量结果 uint32_t wu_result read_reg(REG_WU_RESULT); // 如果测量结果相对于上一次显著变化说明可能有卡 if (abs(wu_result - last_wu_result) threshold) { // 手动发起校准借校准的载波发射时间探测卡片 write_reg(REG_CMD, CMD_CALIBRATE_WU_MEASUREMENT); while (!(read_reg(REG_IRQ_STATUS) IRQ_CAL_DONE)); // 快速进入标准轮询流程 nfc_polling(); } last_wu_result wu_result;这个方案实测下来大部分情况下可以恢复“卡片靠近能触发检测”的功能功耗也会比直接每周期都手动校准低得多。5.2 方案二主控定时器接管自动流程如果你的产品对功耗要求没那么苛刻可以用最简单可靠的办法主控定时器周期唤醒直接用标准NFC命令发起一次轮询不走自动测量状态机。这等于把自动流程那套省电逻辑整个放弃换回最高可控度的做法。void timer_callback(void) { // 每100ms唤醒一次 nfc_polling(); // 内部会主动配置RF使能并发射轮询帧 }这种做法的缺点是主控没法长时间睡大觉MCU功耗上升但换来的是“每次轮询都确定有载波发射”的可预期性。对于功能验证、样机调试我非常推荐先这样跑确认整体链路没问题后再考虑用方案一做功耗优化。5.3 方案三确认芯片修订版本并留意勘误表ST25R100的这个问题虽然我换两颗芯片都能复现自动不发RF但也不排除后续芯片版本修正过。我建议你打开器件厂商提供的参考手册看芯片版本寄存器以及勘误表更新。如果产品量比较大在选型阶段可以对比不同批次芯片确认这个行为是否存在批量一致性。另外如果你手头有ST25R100之外的同品牌型号也可以做个横向对比。有些型号在低功耗唤醒流程里测量阶段和发射阶段之间的状态机上会有更细的分支不一定有同样的问题。这可以作为选型替换时的参考方向。5.4 调试过程中值得注意的三个细节最后说三个调试中容易忽略的细节。别只观察天线SMA口要用近场探头做复核。有些微弱载波在SMA口上不明显但近场探头能捕捉到。我这次如果不是用了近场探头差一点把微弱信号也漏掉然后错误判断成“其实有发射”。手动校准命令完成后别忘了读回校准值并保存。校准不只是为了看载波它会把参考值更新到寄存器里。如果你后面用自动测量最好沿用这套校准值否则测量阈值是错乱的。如果要频繁触发手动校准注意芯片温度。连续高频触发校准会造成功放模块发热虽然ST25R100有温度保护但长时间高频运行仍需关注散热。踩过这次坑之后我的习惯是凡是涉及低功耗唤醒功能和射频发射的调试第一天就把示波器放在天线端把触发条件设成“任意载波上升沿”先确认芯片“真的会发”再去调后续的功耗和状态机。这一步看似简单却能挡住后面一大堆排查时间。希望这篇记录也能帮你少踩一次。