4、UWB物理层(PHY)适配:信道选择、PRF配置、PHR编码、STS生成与验证
物理层适配,说白了就是让UWB芯片的射频前端和基带处理,跟你实际的应用场景对上号。我见过不少团队,芯片选型没问题,代码也没跑飞,但测出来的测距精度就是差一截,或者功耗压不下去。问题出在哪?多半是物理层这几个参数没调明白。
这一章,咱们就掰开揉碎,把信道选择、PRF配置、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的生成过程大致如下:
- 密钥协商: 通信双方预先共享一个128位的密钥(或通过UWB的密钥协商协议交换)。
- 种子生成: 用密钥加上当前帧的序列号、时间戳等信息,通过AES-128加密,生成一个初始种子。
- 序列扩展: 把种子输入到一个线性反馈移位寄存器(LFSR)中,生成一段长度为N的STS序列。N可以是32、64、128、256个符号。
- 调制映射: 把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验证,核心是“本地生成 + 滑动相关”。
具体流程:
- 接收端解析PHR,发现Ranging Bit为1,且STS配置字段指示了STS长度。
- 接收端用本地存储的密钥,加上从帧头解析出的序列号和时间戳,生成本地STS序列。
- 接收端在帧末尾的预期位置,用本地STS序列与接收信号做滑动相关。
- 如果相关峰值超过预设门限(通常取0.7到0.8),则认为STS验证通过。
- 验证通过后,接收端才使用该帧进行TOA估计和测距计算。
避坑指南:我曾经在一个项目中,发现STS验证总是失败。排查到最后,发现是发送端和接收端的时间戳同步出了问题。发送端用的时间戳是发送时刻的,接收端用的时间戳是接收时刻的,两者差了飞行时间。虽然这个差值很小(纳秒级),但足以让AES加密结果完全不同。解决方案是:发送端把时间戳放在帧头里明文传输,接收端用这个时间戳来生成STS,而不是用本地时间。