资讯动态

Nucleo-WBA25CE1实战:BLE Direct Test Mode射频测试全流程指南

发布时间:2026/8/30 5:13:03 来源:尧图企业网站定制
做带蓝牙低功耗功能的产品拿到Nucleo-WBA25CE1这块板子之后想确认射频性能第一件正经事就是把Direct Test Mode跑通。这步不做后面什么发射功率、接收灵敏度、频偏校准全是空谈。DTM说白了就是把协议栈绕过去让射频前端直接按测试指令吐信号或者收信号这样才能用频谱仪、综测仪这些外部设备对DUT做客观测量而不是靠手机App连上之后“感觉信号还行”。这篇文章就围绕Nucleo-WBA25CE1 Direct Test Mode这条线展开把原理、硬件准备、固件烧录、串口命令、实测过程和踩坑经验一次性讲透。适合做蓝牙产品的嵌入式工程师、硬件工程师以及准备送蓝牙认证预测试的团队参考。我会尽可能把实操细节写细命令格式直接给到可以复制粘贴的程度。1. DTM为什么绕不开射频测试的底层逻辑1.1 正常BLE通话模式为什么不能直接测射频很多人第一次接触DTM会有一个疑问我把两台设备连起来发数据不就能验证射频通路了吗能是能但没法量化更没法复现。正常的BLE连接过程包含了链路层状态机、白化与CRC、数据包重传、跳频调度、加密甚至还有CPU负载带来的时序抖动。A点发过去一个包B点收到了只能说明“链路没断”但你说不清是发射功率够高、接收灵敏度好还是刚好两个设备离得近。更麻烦的是你用频谱仪去看正常连接时的发射信号会看到跳频带来的频谱跳变单次捕获窗口里很难稳定测到某一信道上的发射功率和调制质量。DTM的工作方式完全不同。它不建立连接不跳频不做重传直接命令射频收发器在某个固定信道上连续发射或者连续接收测试数据包。测试数据包的payload是标准定义的伪随机序列PRBS9等不需要完整协议栈参与。这样频谱仪可以稳定地捕获单信道信号综测仪可以精确统计误包率。这才叫可测量的、可复现的射频测试环境。1.2 BLE射频测试核心看哪几项在蓝牙认证测试和产线射频校准里和DTM直接相关的测试项主要是这些测试项测量方式判定依据发射功率频谱仪测量DUT连续发射时信道中心频率上的峰值/平均功率符合芯片标称范围且在规定限值内频率偏移/频偏误差分析发射信号中心频率与标称频率的偏差典型要求±150kHz以内调制特征测量GFSK调制的频偏和过零点误差符合BT规范中调制特性的模板单载波/接近单载波使用全0或全1payload观察频谱形状主要用于天线匹配和频偏排查接收灵敏度综测仪发送已知数量测试包DUT统计接收成功数量计算PER通常以PER≤30.8%对应的输入功率作为灵敏度值这些测试全部走DTM。所以你在产品的测试报告中会看到类似“TX Power 2402MHz”“PER -70dBm”这样的描述没有一个不是基于DTM测出来的。1.3 HCI层怎么驱动DTMDTM在协议栈里的落点是HCIHost Controller Interface。从PC上位机或者测试设备下发一条HCI指令芯片控制器收到后进入测试模式然后执行发射或者接收动作。核心指令就三条HCI_LE_Transmitter_TestOpCode 0x201E进入发射模式按指定信道、指定包长、指定payload类型连续发射测试包。HCI_LE_Receiver_TestOpCode 0x201F进入接收模式在指定信道上接收测试包并计数。HCI_LE_Test_EndOpCode 0x2020结束测试并返回统计结果。发射模式下返回已发送包数量接收模式下返回已接收包数量。这三条命令是蓝牙核心规范里定义的所有BLE芯片的DTM固件都会支持。这也是为什么只要硬件没问题任何一片BLE芯片的DTM测试流程都是统一的工具链可以通用。2. Nucleo-WBA25CE1这个平台怎么搭起来2.1 板子接口先认全Nucleo-WBA25CE1是一块带板载ST-LINK调试器的Nucleo开发板。拿到板子后先别急着插线把接口认一遍。板子上几个关键点USB Type-C口板上ST-LINK的USB口集成了调试烧录、虚拟串口、供电三合一功能。整个实验过程只需要这一根USB线。ST-LINK LEDUSB供电正常后这个灯会亮调试器识别到目标芯片后状态会变化。用户按键和LEDDTM固件一般用不到但后文判断固件是否跑起来时可能会用到。天线区域WBA25CE1这类BLE SoC的Nucleo板通常会保留板载PCB天线或者预留UFL/SMA天线座。做射频测试时一定要确认天线连接良好如果是板载天线周围不要放金属物体。2.2 硬件连接和测试环境摆放硬件连接相当简单USB线连到电脑板子通电ST-LINK虚拟串口会在系统里枚举出来。真正容易被忽略的是测试环境的物理摆放。测试DTM发射信号时天线附近不要有人、不要放手机、不要放金属水杯。哪怕是手靠近天线频谱仪看到的功率都会变化好几dB。如果你在办公桌上做测试建议给板子一个固定位置把天线朝向一个开阔方向不要每次测试换个地方。我自己的习惯是准备一个小的塑料支架把板子竖起来固定天线朝上周围30cm内清空。这样连续几天测量的数据才有可比性。做产线校准的人更讲究用的是屏蔽箱箱体内部有射频吸波材料天线通过射频线直连测试仪。咱们前期做研发摸底不需要这么严格但至少保证横向对比时物理环境一致。2.3 开发环境需要装什么跑DTM实验需要准备三样东西STM32CubeIDEST官方IDE用来编译和烧录官方固件包里的DTM例程。STM32CubeProgrammer可选。如果你不想在IDE里烧录可以用这个独立工具直接下载hex文件。STM32CubeWBA固件包从ST官网或GitHubSTMicroelectronics/STM32CubeWBA下载。这个包体积比较大包含了WBA系列所有外设例程和BLE应用例程。安装顺序无所谓全部装完之后在设备管理器里确认一下插上Nucleo板应该能看到一个STLink虚拟串口设备。有些Windows系统需要装ST-LINK驱动一般装STM32CubeIDE或者CubeProgrammer时会自动装上。3. 编译烧录官方DTM固件拿到一台只剩测试功能的裸机3.1 固件包里的DTM例程藏在哪里打开STM32CubeWBA固件包看目录结构。在Projects文件夹下按板卡型号能找到专门的例程目录。WBA系列对应的板卡目录名可能是NUCLEO-WBA25CE1或其他类似命名进去之后找到Applications再进BLE子目录就能看到DTM工程。DTM例程的工程目录下一般同时包含EWARM、MDK-ARM、STM32CubeIDE三种IDE的工程文件。如果你用的是STM32CubeIDE直接导入这个文件夹即可。不要直接在固件包原目录里编译先把例程整个复制到自己的工作目录再导入工程。原因很简单固件包经常会被多个项目共享在你编译过程中产生的一堆临时文件会污染原包下次别人再用容易出问题。导入工程之后先别急着点Build看一下编译目标是不是Release模式。Debug模式在优化级别和宏定义上有时会加进调试输出而DTM测试对时序有一定要求统一用Release模式最稳妥。3.2 编译配置里值得留意的几个点DTM例程编译配置中几个关键选项会和实际测试行为相关系统时钟配置WBA25CE1的BLE子系统依赖系统时钟一般保持例程默认。不要手动去改时钟树除非你清楚知道BLE射频前端对时钟精度的要求。内部PLL配置错了可能导致发射频偏直接飘到几kHz以上。UART接口配置DTM例程通过UART接收HCI命令。例程默认使用板载ST-LINK虚拟串口对应的UART引脚。如果你改了串口引脚映射记得同步改PC端的串口号和配置。TX功率初始值有些版本的DTM例程会在代码里定义一个默认发射功率常量通常在RF层初始化时设置。如果需要固定小功率输出可以改这个值后重新编译。编译时如果报错缺头文件基本是工程路径引用问题。在固件包中不同例程之间会有共享代码复制例程目录时会把相对路径带回去STM32CubeIDE会提示缺失路径手动重新添加固件包里的Drivers和Middlewares路径即可。3.3 烧录与启动验证编译通过之后烧录就简单了。直接在STM32CubeIDE里点击Run或者DebugIDE会自动通过板载ST-LINK把固件下载到WBA25CE1然后自动运行。如果你习惯用STM32CubeProgrammer烧录操作步骤是在固件包编译输出目录找到bin或hex文件。打开STM32CubeProgrammer确认ST-LINK连接方式点击Connect。在Download页签选择要烧录的文件地址保持默认点击Download。烧录完成后按下板子上的复位键让固件重新启动。固件启动后怎么判断DTM代码在跑最直观的方法是打开电脑的设备管理器确认ST-LINK虚拟串口还在。然后打开一个串口终端PuTTY或串口助手波特率设为115200数据位8停止位1无校验。DTM固件启动时一般不会主动打印任何内容但如果你发送一条非法HCI命令或者正常HCI命令它会返回Command Complete事件。所以“能收到响应”就是固件跑起来的最好证明。这里有个非常容易踩的坑ST-LINK虚拟串口有几种枚举模式默认枚举出来的是STLink Virtual COM Port波特率无所谓虚拟串口不实际限制速率但串口编号可能不是COM1。你需要在设备管理器里看清楚实际分配的COM口号然后在上位机里选对。4. 串口下发DTM命令实测一发一收4.1 上位机怎么选图形工具还是串口脚本DTM命令本质上就是串口上的HCI数据包所以至少有两种方式驱动。第一种是ST官方出的一些RF测试工具图形界面连上串口后点选信道、包长、payload类型点Start就开始测试。这类工具对初学者友好不用记任何命令格式缺点是如果工具版本不支持WBA25CE1或者你想自动批量测试时就显得笨重。第二种是自己写串口脚本通过pyserial发送HCI原始命令。这种方式看起来没有图形界面直观但胜在可控性和可重复性。测试参数一变改一下命令行参数就能跑而且很容易集成到自动化测试框架里。我后面给出的示例以Python脚本为主同时会标注对应的十六进制字节你用串口调试助手手动发送也能复现。4.2 用Python串口脚本跑一次发射测试先说明HCI命令报文的基本格式。一条HCI Command Packet由三部分组成OpCode2字节小端序、参数总长度1字节、参数列表。DTM相关命令的参数和返回包格式都是固定的。先看发射测试。命令是HCI_LE_Transmitter_TestOpCode为0x201E。拆成字节就是低位0x1E、高位0x20。命令参数有三个测试信道1字节、测试包长度1字节、payload类型1字节所以参数总长度填0x03。假设我要在信道37对应2402MHz上发射payload长度37字节payload类型用PRBS9值0x00那完整命令是1E 20 03 25 25 00逐字节拆解字节值含义0x1E 0x20OpCode 0x201E发射测试命令0x03参数长度3字节0x25信道37广播信道物理频率2402MHz0x25包长37payload长度37字节0x00PRBS9标准伪随机码型把这个命令发送到串口正常情况下会在几百毫秒内收到Command Complete事件返回字节大致是0E 04 01 1E 20 00。最后那个0x00就是Status表示成功。下面的Python脚本可以直接跑import serial import time # 按自己机器上的实际串口号修改 ser serial.Serial(COM7, 115200, timeout0.5) def send_hci(cmd_hex, desc): data bytes.fromhex(cmd_hex) ser.reset_input_buffer() ser.write(data) time.sleep(0.3) resp ser.read(255) print(f[{desc}]) print(f TX {data.hex( ).upper()}) print(f RX {resp.hex( ).upper()}) return resp # 发射测试信道372402MHz37字节PRBS9 send_hci(1E 20 03 25 25 00, Start TX) time.sleep(2) # 结束测试并返回发送包数量 send_hci(20 20 00, Stop TX) ser.close()运行后如果看到响应中的Status为0x00说明命令已被接受射频前端正在持续发射测试包。这时频谱仪应该能在这个信道的中心频率上看到稳定的能量。4.3 用频谱仪验证发射信号有了频谱仪就能直观验证DTM发射是否正常。先用频谱仪的中心频率设置为2402MHzSPAN适当放大到2MHz到5MHz这样能看到完整的GFSK信号包络。然后打开Max Hold等几秒钟屏幕上应该出现一个稳定的信号峰峰值附近可以看到GFSK信号典型的频谱包络。如果只看单信道功率把SPAN收窄到500kHzRBW设为100kHz读取峰值功率。这个值就是当前发射功率。对比芯片数据手册上的标称功率范围可以初步判断射频通路有没有问题。这里有一个很实用的技巧把payload类型改成全1值0x04和全0值0x05再各测一次。全1或全0的GFSK调制信号会呈现出接近单载波的频谱特征中心频率的偏移量可以直接反映频偏大小。比如中心频率在2402.05MHz处出现峰值说明频偏约50kHz这在BLE的可接受范围内规范允许最大±150kHz。如果偏到2402.3MHz那就说明晶振或PLL有问题要继续排查。4.4 跑一次接收测试并统计PER接收测试比发射测试稍微复杂一点因为单靠DUT自己是不能算PER的需要一个测试仪器或者另一块板子作为数据源。标准做法是用综测仪持续发送测试包DUT接收并计数。但实验室条件没那么齐全时可以用两块Nucleo板互测一块跑发射测试一块跑接收测试。接收测试的命令是HCI_LE_Receiver_TestOpCode为0x201F。参数只有两个测试信道和payload类型参数总长度为0x02。例如在信道19对应2440MHz上接收PRBS91F 20 02 13 00逐字节拆解字节值含义0x1F 0x20OpCode 0x201F接收测试命令0x02参数长度2字节0x13信道19物理频率2440MHz0x00PRBS9接收payload类型接收端进入接收模式后会统计在指定信道上收到的有效测试包数量。要结束测试并拿回这个统计值发送HCI_LE_Test_End20 20 00返回的Command Complete事件会带2字节的Num_Of_Packets。比如返回0E 06 01 20 20 00 5A 00那么0x005A90说明收到了90个包。如果发射端实际发了100个包那PER就是(100-90)/10010%。需要注意这种双板互测方式下发射端固定信道连续发包接收端也固定在同一信道上统计两者并没有真正的链路层握手所以实测的PER会受环境、天线朝向等因素影响。这个方法的价值在于快速验证接收通路的硬件和固件配置而不是替代综测仪做最终认证测试。5. 射频实测踩坑清单与排查思路5.1 命令发出去了串口毫无反应这是最常遇到的问题。命令发过去没有任何返回或者返回的字节完全不对。排查链路按顺序走串口号对不对设备管理器里看虚拟串口实际分配的COM号特别是电脑接了多个USB设备时COM号可能变。用脚本时先打印出可用的串口列表不要太自信地写死COM7。波特率对不对DTM例程默认一般是115200但有些固件版本的串口初始化配置是38400或者9600。打开例程源码搜UART初始化看波特率实际设置值。接线对不对Nucleo板上的ST-LINK虚拟串口默认接在特定UART引脚上但如果你改过跳线或使用了扩展板可能导致信号没到ST-LINK的串口收发端。固件有没有跑起来如果发送HCI命令后完全没有响应且指示灯状态异常重新烧录按复位键再用一个简单的串口终端发0x01看有没有回包。还有一个我自己踩过的坑在Windows上打开多个串口软件比如同时开了串口助手和Python脚本导致串口被占用Python脚本打开串口时静默失败或者发出去的数据没有真正送到板上。所以一定要保证同一时刻只有一个程序占用串口。5.2 频谱仪频率和预期对不上发射测试启动了频谱仪也在扫但中心频率上没看到信号旁边频率倒是有能量。这种情况绝大多数是信道号理解错了。DTM命令里的信道号是BLE物理信道号不是直接对应的MHz频率。物理信道号0-10对应2404到2424MHz信道11-36对应2428到2476MHz而信道37、38、39分别对应2402、2426、2480MHz这三个广播信道。也就是说如果你想测2402MHz命令里的信道号应该是37不是0。如果你填了0实际发射频率是2404MHz频谱仪却盯在2402MHz自然看不到。几个常用频率点的信道号直接背下来目标频率命令信道号十六进制2402MHz370x252404MHz00x002426MHz380x262440MHz190x132480MHz390x27测试多信道时建议写一个频率和信道号的映射表不要在脚本里手动改数字能少犯一半错误。5.3 接收测试PER严重偏高如果真的按上面步骤测出了PER结果却差到离谱先不要怀疑芯片检查这三项。第一两侧信道是否一致。发射端信道37接收端信道如果填错成19两边频点差了38MHzPER肯定100%。先核对信道号。第二天线物理环境。两块板子距离太远、天线互相对着、中间有金属遮挡都会让接收灵敏度下降。研发桌上测试时距离控制在1米内天线尽量正对。第三发射端功率设置。有些DTM固件默认发射功率不是最大如果接收端本来就处于灵敏度边缘发射端降了3dBPER会显著恶化。先确认发射端是否按最高功率发射或者干脆把两块板子靠近到20cm排除功率因素后看PER是否明显下降。5.4 发射功率设置不生效或者实际功率和预期差很多标准HCI的DTM命令里并没有“设置发射功率”这个参数这是很多刚接触DTM的人会困惑的地方。HCI_LE_Transmitter_Test的参数只有信道、包长、payload类型没有功率。在这类芯片的DTM实现里功率通常有两种方式控制通过厂商私有HCI命令动态调整。具体OpCode需要看固件源码里的命令处理部分一般在HCI vendor command分支里有相应的case处理。在固件源码中直接修改初始化时的TX功率变量重新编译烧录。这个变量通常在射频驱动初始化时被调用。如果你在测试中发现实际发射功率和预期值差很多先别急着找命令直接在源码里全局搜tx_power或者TxPower看看默认值是多少。ST的BLE协议栈里功率值一般以dBm为单位是个有符号整数。把它改成你想测的值重新编译烧录再上频谱仪确认。实测发现改代码后固件里可能有一个运行时校验逻辑把功率限制在芯片允许范围内所以如果你设置的值超出范围它会静默回退到最大值或最小值。5.5 测试结果不稳定同一参数测三遍三次都不一样如果你连续三次测同一个发射功率频谱仪读数波动超过1dB先别急着怀疑芯片。这个现象很大概率是环境因素而不是芯片问题。人为因素最容易引起波动。手放在板子附近、人身体靠近天线、桌面上的金属器件移动都会改变天线的近场阻抗直接影响辐射功率测量。正确做法是固定板子位置人离开天线1米以上用RF线直连或者屏蔽箱测量。其次是电源因素。Nucleo板通过USB供电如果USB口供电不稳或者线材过长压降会导致WBA25CE1内部射频PA的供电波动功率自然会抖动。换一根短粗的USB线或者用外部稳压电源单独给板子供电对比一下测试结果往往能看出差别。我个人经验是一旦测试环境固定下来不要频繁改动板子的位置和朝向。研发阶段的数据可能不会像认证实验室那么漂亮但保持一致性才能让横向对比有意义。再分享一个我一直沿用的习惯把DTM测试脚本、信道映射表、上位机串口配置做成一套标准的模板存到项目仓库里和固件代码放在一起。芯片换型号、频率改配置的时候只需要改脚本里的参数不用重新摸索。这样不管是自己后续调试还是同事接手整个射频验证流程都能快速复现。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价