通信原理 —— HDB3 码的编码规则及实现

参考教材为樊昌信主编的《通信原理(第 7 版)》

课本摘句

HDB3 码全称为三阶高密度双极性码(High Density Bipolar 3)。它是 AMI 码的一种改进,保持了 AMI 码没有直流成分且高、低频
分量少、能量集中的优点外克服了其缺点,使连续 “0” 的个数小于等于 3。其编码规则如下:

  1. 先检查消息码的连 “0” 个数。当连 “0” 数目小于等于 3 时,则与 AMI 码的编码规则一样。
  2. 当连 “0” 数目超过 3 个时,则将每 4 个连 “0” 化作一小节,用 “000V” 替代。“V” 取值为 “+1”、“-1”,与其前一个相邻的非 “0” 脉冲的极性相同。因为这破坏了极性交替的规则,所以 “V” 称为破坏脉冲。
  3. 相邻的 “V” 码的极性必须交替。当 “V” 码取值能满足 2. 中的要求但是不能满足此要求时,则将 “0000” 用 “B00V” 替代。 “B” 的取值与后面的 “V” 脉冲抑制,用于解决此问题。因此,“B” 称为调节脉冲。
  4. “V” 码后面的传号码极性也要交替。

编码规则

虽然课本给出了一个详尽的编码规则,但是这个描述对我来说还是太抽象了,并且这个描述的代码实现很困难:因为你可能要不停地更改已经编码过的值以解决规则中的冲突。所以,在这里我想从另一个角度描述 HDB3 的编码规则,具体地说就是:

  1. 依次读取消息码中的符号序列,“1” 的处理与 AMI 编码规则一致。
  2. 当连续 “0” 数目超过 3 个时,则将每 4 个连 “0” 化作一小节,用 “000V” 或 “B00V” 替代。具体替代的类型取决于该小节前非 “0” 脉冲的个数(“1” “B” “V” 都是非 “0” 脉冲):如果非零脉冲的个数为奇数,则用 “000V” 替代;否则用 “B00V”。
  3. “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
}
posted @ 2025-11-14 15:20  浩瀚之志zz  阅读(161)  评论(0)    收藏  举报