POCSAG 协议考古 - 协议基本格式
在智能手机普及之前,有一个时代的移动通信是靠 BP 机(Pager/寻呼机)撑起来的。POCSAG 就是那个时代最成功的寻呼协议之一。虽然 BP 机早已淡出大众视野,但 POCSAG 在今天并没有完全消失——一些医院的老式内部呼叫系统、工厂的报警通知、铁路列车接近预警(800MHz 机车电台 LBJ)等场景中,仍然能看到它的身影。
今天让我们翻开这份来自上世纪的技术文档,看看它是如何在极其有限的带宽和功耗约束下,设计出一套完整的一对多消息广播系统的。
什么是 POCSAG
POCSAG 全称是 Post Office Code Standardization Advisory Group(邮政总局编码标准化咨询组),由当时掌管全英电信的英国邮政总局制定。它是一种无线数据传输的协议,用于向"寻呼机"(Pager)单向发送消息。
POCSAG 定义了三种标准数据速率:512 bps、1200 bps、2400 bps。512 bps 的通信距离最远,而 1200 和 2400 bps 允许每秒传的寻呼消息数量更多。
物理层:调制方式
POCSAG 采用 Frequency Shift Keying(FSK,频移键控)调制。FSK 是一种数字调制技术,用载波频率的变化来表示数字信号——不同的频率对应不同的 bit 值,接收端通过检测频率来判断发过来的是 0 还是 1。
具体到 POCSAG:在射频载波上使用 ±4500Hz 的频偏,高频代表数字 0,低频代表数字 1。同一个传输频道上可以混合不同速率的数据块。
CAP Code:寻呼机的"身份证"
CAP Code(Channel Access Protocol code,频道接入协议码)是每台寻呼机独一无二的地址标识,总共 21 位,这意味着一个频道理论上可以分配 2097152 个不同的地址。
这 21 位实际上被拆成了两部分:
| 字段 | 位数 | 位置 |
|---|---|---|
| 地址位(Address bits) | 18 bit | 高位(MSB) |
| 帧位置位(Frame location bits) | 3 bit | 低位(LSB) |
拆出 3 个帧位置位的设计非常精巧——它允许寻呼机只在"属于自己"的那几帧时间里打开接收器,其他帧时间直接断电休眠,显著延长电池寿命。后文会详细展开。
POCSAG 的传输格式总览
一次完整的 POCSAG 传输由 前导码 + 若干批次 组成:
| 前导码 (Preamble) | 一个或多个 Batch |
|---|---|
| 576 bit,交替 1-0 | 每 Batch = FSC + 8 × Frame |
每个 Batch(批次)的结构如下:
| FSC | Frame 0 | Frame 1 | ... | Frame 7 |
|---|---|---|---|---|
| 32 bit 帧同步码 | 2 个 codeword (64 bit) | 2 个 codeword (64 bit) | ... | 2 个 codeword (64 bit) |
其中:
- FSC(Frame Synchronization Code):32 位帧同步码,标记每个 Batch 的开始
- 8 个 Frame(帧):每个 Frame 固定 2 个 32-bit codeword,一个 Batch 最多承载 16 个地址或消息 codeword
逻辑上可以表示为:
1Batch = FSC(32bit) + [Frame0 + Frame1 + ... + Frame7]
2Frame = Codeword_A(32bit) + Codeword_B(32bit)
所有同步码和 codeword 都是 MSB(最高位)先发送。
前导码(Preamble)
前导码是 576 位交替的 1-0 序列(即 10101010... 重复 576 次)。它的作用有三:
- 唤醒寻呼机:寻呼机平时处于深度休眠,只周期性地醒来"听"一下频道上有没有前导码
- 时钟同步:一旦检测到前导码,寻呼机就用它来锁定比特率时钟,确认数据速率(512/1200/2400 bps)
- 速率标识:前导码的交替频率直接说明了后续数据 Batch 的传输速率
Batch 结构深入
帧同步码(FSC)
FSC 是一段预定义的 32 位二进制序列,用于让寻呼机识别每个 Batch 的起始边界。一旦接收端锁定 FSC,它就能准确知道后续 8 个 Frame 的位置。
Codeword 的类型
每个 Batch 内部有两种核心 codeword 类型:
| 类型 | 首 Bit | 用途 |
|---|---|---|
| 地址码字(Address Codeword) | 0 | 包含目标寻呼机的地址信息 |
| 消息码字(Message Codeword) | 1 | 紧跟地址码字,携带实际消息内容 |
| 空闲码字(Idle Codeword) | 1 | 填充无用的 Frame 位置 |
地址码字(Address Codeword)结构
地址码字共 32 位,各字段划分如下:
| 位范围 | 1 | 2-19 | 20-21 | 22-31 | 32 |
|---|---|---|---|---|---|
| 字段 | 标志位 | 地址位 | 功能位 | BCH 校验位 | 偶校验位 |
| 说明 | 固定为 0,标识地址码字 | 寻呼机地址的高 18 位 | 消息类型标识 | 前 31 位的 BCH(31,21) 校验值 | 整个 codeword 的偶校验 |
功能位(Bit 20-21)用于区分消息的来源或类型,标准约定如下:
| Bit 20 | Bit 21 | 含义 |
|---|---|---|
| 0 | 0 | 数字消息 |
| 0 | 1 | 字母数字消息 |
| 1 | 1 | 音调提醒(仅触发报警,无消息内容) |
这里有一个关键设计:完整的 21 位 CAP Code 是如何从地址码字中还原出来的?
18 位地址(Bit 2-19)+ 3 位帧位置 = 21 位 CAP Code
3 位帧位置来自这个地址码字所在的 Frame 编号(0-7)。这 3 位是 CAP Code 的最低位(LSB),18 位是 CAP Code 的高位(MSB)。所以寻呼机不是在所有 8 个 Frame 里都找自己的地址——它只需要在 CAP Code 的最低 3 位对应的那一帧里醒来听一听。
消息码字(Message Codeword)结构
消息码字同样 32 位,与地址码字共用同一套 BCH 校验框架:
| 位范围 | 1 | 2-21 | 22-31 | 32 |
|---|---|---|---|---|
| 字段 | 标志位 | 消息数据 | BCH 校验位 | 偶校验位 |
| 说明 | 固定为 1,标识消息码字 | 实际消息载荷,20 bit | 前 31 位的 BCH(31,21) 校验值 | 整个 codeword 的偶校验 |
消息码字紧跟在地址码字之后。一条完整的寻呼消息 = 1 个地址码字(位于对应的 Frame 内)+ 0 到 n 个紧随其后的消息码字。消息码字会占用 Batch 中原本属于地址码字的位置。当接收端遇到下一个地址码字或空闲码字时,即表示当前消息结束。长消息可以跨越多个 Batch。
空闲码字(Idle Codeword)
当某个 Frame 里既没有地址码字也没有消息码字需要发送时,就用空闲码字填充。空闲码字是一个固定的保留值:
0x7A89C197 = 01111010100010011100000110010111
消息编码
POCSAG 支持两种消息格式:
- 数字消息:使用 BCD 编码,每 codeword 的 20 位消息区可承载 5 个数字(每数字 4 bit)
- 字母数字消息:使用 7-bit ASCII 编码,字符跨 codeword 边界分割,标准最大 40 字符
数字消息(BCD 编码)
POCSAG 的数字消息使用 BCD(Binary-Coded Decimal) 编码。每个 codeword 的 20 位消息区域可以塞进 5 个 BCD 数字(每数字 4 bit = 20 bit)。
除了 0-9 之外,BCD 编码还定义了 6 个特殊字符:
| 值 | 含义 |
|---|---|
0xA | 保留 |
0xB | U(紧急标记) |
0xC | 空格 |
0xD | -(连字符) |
0xE | )(右括号) |
0xF | ((左括号) |
消息不足 5 个数字时,用空格(0xC)填充。
字母数字消息(7-bit ASCII)
字母数字消息使用 7 位 ASCII 编码。每个 codeword 只有 20 位消息区域,而 3 个 7 位字符 = 21 位,所以编码时字符会在 codeword 之间跨边界分割。具体规则:
- 20 位消息区从 MSB 到 LSB 依次填入字符
- 7 位 ASCII 字符的 LSB 先传输
- 最后一个 codeword 用空字符(Null)、EOT 等不可打印字符填充
- 标准最大长度 40 个字符,扩展模式可到 80 个字符
BCH 纠错编码
POCSAG 使用 BCH(31, 21) 编码,可纠正单 codeword 内 1-2 个 bit 错误。这对单向广播系统至关重要——寻呼机没有上行信道,无法请求重传,只能在接收端自行纠错。BCH 的具体编解码实现将在后续文章单独介绍。
#技术 #POCSAG | 微信打赏 | 转载必须注明原文链接

提交中...