很有意思的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两种情况。
我们先来就以下这段消息码逐个进行编码,理解一下我们的代码实现思路。
我们可以看到,靠存储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;
}
运行结果:
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;
}
运行结果:
标签:编解码,极性,编码,--,C++,else,int,HDB3,out 来源: https://blog.csdn.net/qq_42887507/article/details/120810610