4. 射频寄存器与协议栈配置

在 Nordic 无线调试中,真正决定“发得出去、收得回来”的,往往不是应用层代码,而是 RADIO 外设寄存器与协议栈参数的配合。nRF52 与 nRF53 系列都提供独立的 RADIO 硬件外设,它负责 2.4 GHz 物理层收发、地址匹配、CRC、包格式和空中时序;而 SoftDevice(如 S132/S140)或 nRF53 的协议栈则在其上封装了 BLE 链路层、GAP/GATT 与调度器。理解这两层如何分工,是排查“能广播但连不上”“连接后丢包”“距离短”等问题的前提。

RADIO 外设:短距离射频的寄存器骨架

RADIO 外设的核心寄存器可以按“频率—功率—地址—包格式—状态”五组来理解。频率由 FREQUENCY 决定,nRF52 的 BLE 信道映射为 2402 MHz + k×2 MHz,k 取 0~39;广播信道固定为 37/38/39,对应 2402/2426/2480 MHz。发射功率由 TXPOWER 设置,nRF52832 典型档位为 +4、0、−4、−8、−12、−16、−20、−40 dBm,nRF52840 可到 +8 dBm,nRF5340 约 +3 dBm。调试时若发现近距离正常、远距离断连,先确认 TXPOWER 是否被协议栈默认值限制在 0 dBm。

地址与包格式由 BASE0/BASE1、PREFIX0/PREFIX1、PCNF0/PCNF1 共同描述。BLE 广播使用 4 字节访问地址 0x8E89BED6,其中 BASE0 写低 32 位、PREFIX0 写高 8 位;PCNF0 配置 S0/S1 长度、长度字段位数和 CRC 使能,PCNF1 配置最大包长、静态长度、白化使能和字节序。若用私有 2.4 GHz 模式做点对点测试,可自定义地址,但必须保证收发双方 BASE/PREFIX 完全一致,否则会出现“发送完成但接收端无中断”。

状态与事件通过 STATE、EVENTS_READY、EVENTS_ADDRESS、EVENTS_END、EVENTS_DISABLED 观察。典型裸机发送序列是:写 PACKETPTR 指向 RAM 中的包缓冲,置 TASKS_TXEN,等待 EVENTS_READY,再置 TASKS_START,最后等 EVENTS_END 并读 CRCSTATUS。若 CRCSTATUS 为 0,说明对端收到的 CRC 错误,应优先检查白化、字节序和 CRC 初值是否一致。

nRF52/nRF53 RADIO 寄存器与协议栈参数关系 协议栈 / SoftDevice 层 • GAP 角色与广播参数 • 连接间隔 / 从机延迟 • ATT MTU / 数据长度扩展 • 信道图与跳频序列 • 调度器时隙与优先级 ↓ 通过 sd_* API 下发 或直接写 RADIO 寄存器 RADIO 外设寄存器组 FREQUENCY / MAP TXPOWER BASE0/1 PREFIX0/1 PCNF0 / PCNF1 PACKETPTR · CRCINIT · CRCSTATUS · STATE 2.4 GHz 空中接口 • 前导码 + 访问地址 • 报头 + 长度 + S0/S1 • 有效载荷 + CRC • 白化与比特序 • 信道 37/38/39 广播 ↑ 参数不一致 → CRC 错 或收不到 ADDRESS 事件 典型调试判断链:从现象到寄存器/参数定位 现象:收不到包 无 ADDRESS 事件 查地址与频率 BASE/PREFIX/FREQ 查包格式 PCNF0/1 白化/CRC 查功率与信道 TXPOWER/信道图 协议栈 参数覆盖 关键判据:EVENTS_ADDRESS 出现但 CRCSTATUS=0 → 包格式/白化/CRC 不一致; EVENTS_READY 不出现 → 频率或状态机未就绪;连接后丢包 → 连接间隔、信道图或 TXPOWER 被协议栈限制。

SoftDevice 与协议栈参数:谁在覆盖寄存器

使用 SoftDevice 时,RADIO 寄存器由协议栈统一管理,应用不能随意直接写 FREQUENCY 或 TXPOWER,否则会与协议栈调度冲突。此时应通过 sd_ble_gap_adv_set_configure()、sd_ble_gap_adv_start()、sd_ble_gap_connect() 等 API 设置广播与连接参数。例如广播间隔由 adv_params.interval 以 0.625 ms 为单位给出,设为 160 即 100 ms;连接间隔在 ble_gap_conn_params_t 中由 min_conn_interval 和 max_conn_interval 以 1.25 ms 为单位给出,设为 24 即 30 ms。若把连接间隔设得过小(如 7.5 ms),而从机延迟和 supervision timeout 不匹配,就会出现频繁断连。

nRF53 的协议栈运行在 network core 上,application core 通过 IPC 与它通信。此时 RADIO 寄存器位于 network core,应用侧只能通过 bt_* API 或 HCI 命令间接配置。调试 nRF53 时,若发现 application core 写寄存器无效,应确认当前是否已启用协议栈、是否在正确的核上操作。对于需要裸机 2.4 GHz 私有协议的场景,可以关闭协议栈,直接使用 nrf_radio_* HAL 或寄存器操作,此时才拥有对 FREQUENCY、TXPOWER、PCNF0/1 的完全控制权。

参数配置示例与观察方法

下面给出一段基于 nRF5 SDK 的广播参数配置示例,用于把广播间隔设为 100 ms、发射功率设为 +4 dBm,并观察实际生效值。示例参数属于教学假设,实际应以芯片手册和协议栈版本为准。

// 广播参数:100 ms 间隔,可连接,使用信道 37/38/39
ble_gap_adv_params_t adv_params = {
    .properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED,
    .p_peer_addr     = NULL,
    .fp              = BLE_GAP_ADV_FP_ANY,
    .interval        = 160,   // 160 × 0.625 ms = 100 ms
    .duration        = 0,     // 0 表示持续广播
    .primary_phy     = BLE_GAP_PHY_1MBPS,
};
// 发射功率:+4 dBm(需协议栈支持)
sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, adv_handle, 4);
// 启动广播
sd_ble_gap_adv_start(adv_handle, &adv_params, APP_IRQ_PRIORITY_LOWEST);

配置完成后,用 nRF Connect 手机 App 或 Sniffer 观察:广播包应约每 100 ms 出现一次,RSSI 在 1 米处约 −40~−55 dBm。若 RSSI 明显偏低,先查 sd_ble_gap_tx_power_set() 返回值是否为 NRF_SUCCESS,再确认天线匹配和供电。若广播间隔明显偏离 100 ms,检查是否有其他高优先级中断抢占,或协议栈时钟源是否使用外部 32.768 kHz 晶振。

调试建议:先用裸机 RADIO 私有模式验证地址、频率、包格式和 CRC 是否自洽,再切回 SoftDevice 验证协议栈参数。这样可以把“寄存器层错误”和“协议栈参数错误”分开定位,避免同时改多个变量。
注意:直接写 RADIO 寄存器与启用 SoftDevice 不能同时进行。若在协议栈已初始化后操作 NRF_RADIO,可能触发 HardFault 或导致连接异常。切换模式前应先调用 sd_softdevice_disable() 并确认协议栈已完全停止。

常见参数对照与排查要点

参数寄存器/API典型值异常表现
广播信道频率FREQUENCY / adv 信道2402/2426/2480 MHz收不到广播包
发射功率TXPOWER / sd_ble_gap_tx_power_set0~+4 dBm距离短、RSSI 低
访问地址BASE0/PREFIX00x8E89BED6无 ADDRESS 事件
CRC 与白化PCNF0/PCNF1CRC 使能、白化开CRCSTATUS=0
连接间隔ble_gap_conn_params_t30~50 ms频繁断连或延迟高
ATT MTUsd_ble_gattc_exchange_mtu_request247 字节吞吐上不去

最后强调一个工程习惯:每次修改射频参数后,不要只看“有没有连上”,而要同时记录 RSSI、CRCSTATUS、连接间隔实际值和丢包率。把寄存器层与协议栈层的参数分开记录,才能在出现“时好时坏”的偶发问题时快速定位是频率漂移、功率不足,还是协议栈调度被抢占。