编程语言
首页 > 编程语言> > 很有意思的HDB3编解码!--C++实现

很有意思的HDB3编解码!--C++实现

作者:互联网

前言

​ 本周的物联网通信实验课上,需要我们编写部分HDB3编解码的c语言代码,个人觉得这个编解码的代码写得十分巧妙,还挺有意思的,故记录一下。

什么是HDB3

​ 数字传输系统中传输的数字信息是来自计算机、电传机等数据终端的各种数字信号, 或者是来自模拟信号经数字化处理后的脉冲编码(PCM)信号等。这些数字信号所占据频谱 是从零频或低频开始,通常称为数字基带(baseband)信号。

​ 在某些具有低通特性的有线信道中,特别是在传输距离不太远的情况下,基带信号可 以不经过载波调制而直接进行传输,这类系统称为数字基带传输系统。

​ 基带传输系统中,并不是所有的基带波形都适合在信道中传输,需要转换基带码型再 进行传输。HDB3 则是一种常用的基带传输码型。

HDB3编码

HDB3编码原理

HDB3 码编码规则如下:

(1)当消息码中连“0”数目小于等于 3 时,非“0”脉冲极性交替;例如:

消息码: 1 0 0 1 0 0 0 1

HDB3码: -1 0 0 +1 0 0 0 -1

(2)当消息码中连“0”数目超过 3 个时,将每 4 个连“0”化作一小节,定义为 B00V,称为 破坏节,其中 V 称为破坏脉冲,而 B 称为调节脉冲

(3)V 与其前一个的非“0”脉冲的极性相同(这破坏了极性交替的规则,所以 V 称为破坏脉冲),并且要求相邻的 V 码之间极性必须交替。V 的取值为+1 或-1。

(4)B 的取值可选 0、+1 或-1。

(5)V 码后面的传号码极性也要交替。例如:

消息码: 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1

HDB3 码: -1 0 0 0 -V +1 0 0 0 +V -1 +1 -B 0 0 -V +B 0 0 +V -1 +1

HDB3 编码代码

我们先稍微整理一下HDB3的编码规则:

(1)当连 0 个数不超过 3 时,非“0”脉冲极性交替。

(2)当连 0 个数超过 3 时,检查两个相邻的 V 码之间的 1 的个数,如果有奇数个 1 时,此四个连 0 用 000V 表示,如果有偶数个 1 时,此四个连 0 用 B00V 表示。

(3)1 与 B 一起确定极性,即相当于把 B 看做 1,1 与 B 一起极性交替。

(4)V 码的极性与前一个非 0 码(含 B 码)极性相同,之后保证 V 码 极性交替即可。

代码实现:

编写代码时我们主要需要解决两个问题:一个是非0码的极性,一个是准确区别B00V和000V两种情况。

我们先来就以下这段消息码逐个进行编码,理解一下我们的代码实现思路。

7B20A0EFE940B08B8307ED51E57B342B

我们可以看到,靠存储b和v这两个标志位,我们就能够轻松解决非0码的极性和区别B00V和000V两种情况的问题。个人觉得这个代码实现思路还是十分巧妙的!简洁且优雅地解决了一个较为复杂的问题!值得回味!

以下是我使用c++实现的HDB3编码代码:

#include<iostream>
using namespace std;

int b = 1; // 标志位,代表上一个非0码(不含v码)的极性
int v = 1; // 标志位,与标志位b配合克用于判断相邻两个v码间有奇数还是偶数个1
int i = 0;
int main()
{
    int n;
    cout << "请输入消息码长度:" << endl;
    cin >> n;
    int* in = new int[n];
    int* out = new int[n];
    cout << "请输入消息码:" << endl;
    for (; i < n; i++)
    {
        cin >> in[i];
    }
    // HDB3编码
    i = 0;
    while (i < n)
    {
        if (in[i] == 1)   //若消息码为1,交替为+1,-1
        {
            out[i] = -1 * b;
            b = out[i];
            i = i + 1;
        }
        else if (in[i + 1] == 1)   //消息码只有一个0
        {
            out[i] = 0;
            out[i + 1] = -1 * b;
            b = out[i + 1];
            i = i + 2;
        }
        else if (in[i + 2] == 1)   //消息码有两个连续0
        {
            out[i] = 0;
            out[i + 1] = 0;
            out[i + 2] = -1 * b;
            b = out[i + 2];
            i = i + 3;
        }
        else if (in[i + 3] == 1)   //消息码有三个连续0
        {
            out[i] = 0;
            out[i + 1] = 0;
            out[i + 2] = 0;
            out[i + 3] = -1 * b;
            b = out[i + 3];
            i = i + 4;
        }
        else if (b ^ v)  // b,v标志不同,即表示两个v码间间隔了奇数个1
        {
            out[i] = 0;
            out[i + 1] = 0;
            out[i + 2] = 0;
            out[i + 3] = b;
            v = b;
            i = i + 4;
        }
        else   //b,v标志相同,即表示两个v码间间隔了偶数个1
        {
            out[i] = -1 * b;
            b = out[i];
            out[i + 1] = 0;
            out[i + 2] = 0;
            out[i + 3] = -1 * v;
            v = out[i + 3];
            i = i + 4;
        }
    }
    cout << "HDB3编码为:" << endl;
    for (i = 0; i < n; i++)
    {
        cout << out[i] << " ";
    }
    cout << endl;
}

运行结果:

image-20211017140444194

HDB3解码

HDB3的编码相对比较复杂,但是HDB3的解码就简单很多了。

若HDB3码为0,那么原消息码肯定为0。

我们主要需要解决的问题就是找出HDB3码中的v码,v码前面三个码必是三个0。再将其余的-1变成+1便可得到原消息码。

以下是我用c++实现的HDB3解码:

#include<iostream>
using namespace std;

int main() {
    int cnt_0 = 0;   //记录连续0的个数
    int polarity = 0;   //记录前一个信码的极性
    int n;
    cout << "请输入HDB3码长度:" << endl;
    cin >> n;
    int* in = new int[n];
    int* out = new int[n];
    cout << "请输入HDB3码:" << endl;
    for (int i = 0; i < n; i++)
    {
        cin >> in[i];
    }
    // HDB3解码
    for (int i = 0; i < n; i++)
    {
        if (!(in[i]))   //HDB3码为0,译码结果一定是0
        {
            cnt_0++;
            out[i] = 0;
        }
        else   //HDB3码不为0
        {
            if ((in[i] == polarity) && (cnt_0 >= 2))   //当前HDB3码是+V或-V
            {
                out[i] = 0;
                if (cnt_0 == 2)   //若+V或-V前面是连续两个0,则该段HDB3码为B00V,原消息码是连续4个0,应还原前一个B码为0
                {
                    out[i - 3] = 0;
                }
            }
            else   //当前HDB3码是非0码(不包含v码)
            {
                out[i] = 1;
                // 记录前一个非0码(不包含v码)的极性
                if (in[i] == -1)
                {
                    polarity = -1;
                }
                else
                {
                    polarity = 1;
                }
            }
            cnt_0 = 0;
        }
    }
    cout << "HDB3解码为:" << endl;
    for (int i = 0; i < n; i++)
    {
        cout << out[i] << " ";
    }
    cout << endl;
}

运行结果:

image-20211017142223538

标签:编解码,极性,编码,--,C++,else,int,HDB3,out
来源: https://blog.csdn.net/qq_42887507/article/details/120810610