4、UWB物理层(PHY)适配:信道选择、PRF配置、PHR编码、STS生成与验证

物理层适配,说白了就是让UWB芯片的射频前端和基带处理,跟你实际的应用场景对上号。我见过不少团队,芯片选型没问题,代码也没跑飞,但测出来的测距精度就是差一截,或者功耗压不下去。问题出在哪?多半是物理层这几个参数没调明白。

这一章,咱们就掰开揉碎,把信道选择、PRF配置、PHR编码、STS生成与验证这四个核心模块讲透。每个点我都会结合项目里踩过的坑来说,希望能帮你少走弯路。

核心观点:物理层适配不是“选一个默认配置就完事”,而是要在通信距离、数据速率、测距精度、功耗、抗多径能力这五个维度之间做权衡。没有银弹,只有最合适的组合。

UWB物理层适配核心模块 PHY 适配决策 信道选择 CH 1/2/3/4/5/9 PRF 配置 16 MHz / 64 MHz PHR 编码 速率/长度/纠错 STS 生成与验证 安全测距核心 权衡维度:通信距离 ↔ 数据速率 ↔ 测距精度 ↔ 功耗 ↔ 抗多径能力 每个模块的配置都会影响其他模块的表现 需要根据应用场景做整体权衡

4.1 信道选择:别小看这个“选择题”

UWB标准定义了多个信道,从CH 1到CH 9,中心频率从3.5 GHz到9.5 GHz不等。但实际产品里,最常用的是CH 2(4.0 GHz)、CH 5(6.5 GHz)和CH 9(8.0 GHz)。

我个人习惯,做室内定位项目时优先选CH 5。为什么?因为6.5 GHz这个频段,既避开了2.4G/5G Wi-Fi的强干扰,又不像CH 9那样在8 GHz以上衰减太快。我在一个仓储机器人项目里,一开始用了CH 9,结果在金属货架密集区,信号反射得一塌糊涂,测距抖动超过30厘米。后来切到CH 5,多径问题明显改善,抖动降到了5厘米以内。

信道编号 中心频率 (MHz) 带宽 (MHz) 典型应用场景 注意事项
CH 1 3494.4 499.2 低功耗、短距离 易受Wi-Fi 2.4G谐波干扰
CH 2 3993.6 499.2 室内定位、IoT 平衡性好,推荐首选
CH 3 4492.8 499.2 工业场景 部分国家法规受限
CH 4 4992.0 499.2 高精度测距 与5G NR频段有重叠风险
CH 5 6489.6 499.2 室内定位(推荐) 抗干扰能力强,多径抑制好
CH 9 7987.2 499.2 高精度、短距离 衰减大,穿透力弱

我的经验:如果你做的是消费级产品,优先考虑CH 5。如果是工业级且对距离要求高,CH 2更稳妥。CH 9只适合视距(LOS)环境下的高精度场景,非视距(NLOS)下慎用。

4.2 PRF配置:16 MHz vs 64 MHz,怎么选?

PRF,脉冲重复频率,说白了就是一秒钟发多少个脉冲。标准里定义了两种:16 MHz和64 MHz。这个参数直接影响测距精度和功耗。

你想想看,64 MHz的PRF,脉冲密度是16 MHz的四倍。这意味着什么?接收端能拿到更多的脉冲样本,做到达时间估计(TOA)时精度更高。我做过对比测试,在同样的信噪比下,64 MHz PRF的测距标准差比16 MHz低了大约40%。

但代价也很明显——功耗。64 MHz PRF下,发射机的工作电流大概比16 MHz高出30%到50%。对于电池供电的设备,这个差距很要命。

参数 16 MHz PRF 64 MHz PRF
脉冲间隔 62.5 ns 15.625 ns
测距精度 中等(约±10 cm) 高(约±3 cm)
功耗 低 高(约+40%)
抗多径能力 一般 强
最大通信距离 较远 稍近(约缩短15%)
推荐场景 低功耗IoT、标签 高精度基站、工业定位

注意:PRF的选择会影响PHR的编码方式。IEEE 802.15.4z标准里,16 MHz PRF和64 MHz PRF对应的PHR编码参数不同。如果你改了PRF但没同步更新PHR配置,接收端会直接丢包。我曾经在这个坑里爬了三天才找到原因。

4.3 PHR编码:帧头里的“小算盘”

PHR,物理层头部,它告诉接收端这一帧的速率、长度、以及是否使用STS。别看它只有几十个比特,编码错了整帧都解不出来。

PHR的编码有几个关键字段:

  • Data Rate(3 bit): 6.8 Mbps、27.2 Mbps、110 kbps 等。速率越低,灵敏度越高,距离越远。
  • Frame Length(10 bit): 最大1023字节。注意,这个长度包括PHR本身吗?不包括。PHR是单独编码的。
  • Ranging Bit(1 bit): 指示这一帧是否用于测距。如果置1,接收端会启动STS验证流程。
  • STS Configuration(若干bit): 指示STS的长度和类型。

我个人习惯,在做测距应用时,PHR里的Ranging Bit一定要置1。否则接收端不会启动高精度TOA估计,测距精度会大打折扣。我在一个早期项目里就犯过这个错——Ranging Bit忘了置位,结果测出来的距离忽远忽近,排查了两天才发现是这里的问题。

关键点:PHR使用卷积码进行纠错,码率是1/2。这意味着PHR的19个信息比特,实际发送时是38个编码比特。接收端用维特比译码来恢复。所以PHR本身就有一定的抗干扰能力,但在极低信噪比下,它仍然是整帧的瓶颈。

4.4 STS生成与验证:安全测距的“守门员”

STS,加扰时间戳序列。这是IEEE 802.15.4z标准引入的核心安全机制。它的作用是什么?防止攻击者通过“距离欺骗”或“信号重放”来篡改测距结果。

说白了,STS就是一个只有合法设备才知道的伪随机序列。发送端在发送测距帧时,会在帧末尾附加一段STS。接收端收到后,用预先共享的密钥和相同的算法,自己生成一段STS,然后跟收到的做比对。如果匹配,说明这个帧是合法的;如果不匹配,直接丢弃。

STS的生成过程大致如下:

  1. 密钥协商: 通信双方预先共享一个128位的密钥(或通过UWB的密钥协商协议交换)。
  2. 种子生成: 用密钥加上当前帧的序列号、时间戳等信息,通过AES-128加密,生成一个初始种子。
  3. 序列扩展: 把种子输入到一个线性反馈移位寄存器(LFSR)中,生成一段长度为N的STS序列。N可以是32、64、128、256个符号。
  4. 调制映射: 把STS序列映射成BPM-BPSK调制符号,插入到帧末尾。
// STS 生成伪代码示例(简化版)
uint8_t sts_key[16] = {0x2B, 0x7E, 0x15, 0x16, ...}; // 128位密钥
uint32_t frame_seq_num = 0x1234;
uint64_t timestamp = 0xABCDEF0123456789;

// 1. 生成种子
uint8_t seed[16];
aes128_encrypt(sts_key, frame_seq_num, timestamp, seed);

// 2. 初始化LFSR(32阶)
uint32_t lfsr_state = (seed[0] << 24) | (seed[1] << 16) | (seed[2] << 8) | seed[3];

// 3. 生成64个STS符号
uint8_t sts_symbols[64];
for (int i = 0; i < 64; i++) {
    sts_symbols[i] = lfsr_state & 0x01;  // 取最低位
    lfsr_state = (lfsr_state >> 1) ^ (-(sts_symbols[i]) & 0x80000057); // 反馈多项式
}

我的建议:STS的长度不是越长越好。64个符号的STS已经能提供足够的安全性,同时开销可控。256个符号的STS虽然更安全,但会显著增加帧长度和功耗。在大多数商业场景下,64符号的STS是性价比最高的选择。

4.5 验证流程:接收端怎么“验货”?

接收端的STS验证,核心是“本地生成 + 滑动相关”。

具体流程:

  1. 接收端解析PHR,发现Ranging Bit为1,且STS配置字段指示了STS长度。
  2. 接收端用本地存储的密钥,加上从帧头解析出的序列号和时间戳,生成本地STS序列。
  3. 接收端在帧末尾的预期位置,用本地STS序列与接收信号做滑动相关。
  4. 如果相关峰值超过预设门限(通常取0.7到0.8),则认为STS验证通过。
  5. 验证通过后,接收端才使用该帧进行TOA估计和测距计算。

避坑指南:我曾经在一个项目中,发现STS验证总是失败。排查到最后,发现是发送端和接收端的时间戳同步出了问题。发送端用的时间戳是发送时刻的,接收端用的时间戳是接收时刻的,两者差了飞行时间。虽然这个差值很小(纳秒级),但足以让AES加密结果完全不同。解决方案是:发送端把时间戳放在帧头里明文传输,接收端用这个时间戳来生成STS,而不是用本地时间。