通信原理 —— HDB3 码的编码规则及实现
参考教材为樊昌信主编的《通信原理(第 7 版)》
课本摘句
HDB3 码全称为三阶高密度双极性码(High Density Bipolar 3)。它是 AMI 码的一种改进,保持了 AMI 码没有直流成分且高、低频
分量少、能量集中的优点外克服了其缺点,使连续 “0” 的个数小于等于 3。其编码规则如下:
- 先检查消息码的连 “0” 个数。当连 “0” 数目小于等于 3 时,则与 AMI 码的编码规则一样。
- 当连 “0” 数目超过 3 个时,则将每 4 个连 “0” 化作一小节,用 “000V” 替代。“V” 取值为 “+1”、“-1”,与其前一个相邻的非 “0” 脉冲的极性相同。因为这破坏了极性交替的规则,所以 “V” 称为破坏脉冲。
- 相邻的 “V” 码的极性必须交替。当 “V” 码取值能满足 2. 中的要求但是不能满足此要求时,则将 “0000” 用 “B00V” 替代。 “B” 的取值与后面的 “V” 脉冲抑制,用于解决此问题。因此,“B” 称为调节脉冲。
- “V” 码后面的传号码极性也要交替。
编码规则
虽然课本给出了一个详尽的编码规则,但是这个描述对我来说还是太抽象了,并且这个描述的代码实现很困难:因为你可能要不停地更改已经编码过的值以解决规则中的冲突。所以,在这里我想从另一个角度描述 HDB3 的编码规则,具体地说就是:
- 依次读取消息码中的符号序列,“1” 的处理与 AMI 编码规则一致。
- 当连续 “0” 数目超过 3 个时,则将每 4 个连 “0” 化作一小节,用 “000V” 或 “B00V” 替代。具体替代的类型取决于该小节前非 “0” 脉冲的个数(“1” “B” “V” 都是非 “0” 脉冲):如果非零脉冲的个数为奇数,则用 “000V” 替代;否则用 “B00V”。
- “V” 的极性与前一个非 “0” 脉冲相同,“B” 的极性与前一个非 “0” 脉冲相反。
上述规则给出了一个在代码实现上更简单的 HDB3 编码方法,至于它是否与课本中的规则一致我没法给出严格的证明,但是 “it works”。此外,我认为上述对 “V” “B” 极性的判断能更好地解释其符号的由来(Violation & Bipolar)。
代码实现
以下是 HDB3 编码的 rust 实现(r 门!),因为 rust 的模式匹配非常适合这种输入输出有限取值的模型。
// 原始输入符号
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum InputBit {
Zero, // 0
One, // 1
}
// HDB3 编码后的符号
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum HDB3Symbol {
PosB, // +B
NegB, // -B
PosV, // +V
NegV, // -V
PosOne, // +1
NegOne, // -1
Zero // 0
}
/// HDB3 编码函数
/// input 为 InputBit 数组的切片
/// pos_bias 决定第一个非零脉冲的编码是否为 +1
pub fn encode(input: &[InputBit], pos_bias: bool) -> Vec<HDB3Symbol> {
use HDB3Symbol::*;
let mut output: Vec<HDB3Symbol> = Vec::with_capacity(input.len());
let mut zero_count = 0;
// 上一个脉冲的极性
let mut pos_pulse = !pos_bias;
let mut pulse_count = 0;
for &bit in input {
match bit {
InputBit::One => {
// clear zero_count
while zero_count > 0 {
output.push(Zero);
zero_count -= 1;
}
let value = if pos_pulse { NegOne } else { PosOne };
output.push(value);
pulse_count += 1;
pos_pulse = !pos_pulse;
},
InputBit::Zero => {
zero_count += 1;
if zero_count == 4 {
// 奇数脉冲,000V模式
if pulse_count & 1 == 1 {
output.append(&mut [Zero].repeat(3));
}
// 偶数脉冲,B00V模式
else {
// bipolar pulse
let insert_b = if pos_pulse { NegB } else { PosB };
output.push(insert_b);
pulse_count += 1;
pos_pulse = !pos_pulse;
output.append(&mut [Zero].repeat(2));
}
// violation pulse
let insert_v = if pos_pulse { PosV } else { NegV };
output.push(insert_v);
pulse_count += 1;
zero_count = 0;
}
}
}
}
output
}

浙公网安备 33010602011771号