HDB3 的编码与译码 ①(MATLAB 实现)2021-9-11


前言

本篇文章主要介绍了HDB3码的基本规则,相关的解码、编码方法,以及用MATLAB实现。最终的目的是使用Verilog语言完成一个HDB3的编码器和译码器。


一、HDB3 码是什么?

HDB3全称(High Density Bipolar of order 3 code,三阶高密度双极性码)在学习通信原理这门课的时候有了解到这样的编码方式,但时间久远,我甚至连名字都记不起来了。我们可以简单的看一下HDB3码的百度百科。可以看到HDB3码是对AMI码的一个进阶。下面就了解一下编码规则以及机器实现的简便方法。

1.编码规则

了解编码规则之前,先了解一下其中的关键名词。

  1. V:破坏脉冲。
  2. B:调节脉冲。
  3. B00V:取代节、破坏节。
    再了解随后的编码步骤:
    第一步:连0的个数不超过3时,规则与AMI相同,即0不变,1变为-1、+1交替;
    第二步:若连0的个数超过3,则将每4个0看作一小节,定义为B00V,B可以是-1、0、+1,V可以是-1、+1;
    第三步:B和V具体值满足以下条件:V和前面相邻非0符号极性相同;不看V时极性交替;V与V之间极性交替;
    第三步:一般第一个B取0,第一个非0符取-1;
    为什么第一个B总是0那?这里可以根据B和V的含义来理解。V(破坏脉冲)的出现将1的交替打乱,并且V的极性也要交替正负。有时这两个条件不能同时满足,就需要B了。B(调节脉冲)应该和1的极性看成一组,保证极性交替正负。而第一个V的极性保持和上一个1的极性相同,不需要B的调节。
    再举一个例子,就能更加清楚地明白了。
    消息代码:1 0 0 0 0 1 0 0 0 01 1 0 0 0 0 1 1
    AMI码: -1 0 0 0 0 +1 0 0 0 0 -1 +1 0 0 0 0 -1 +1
    HDB3码:-1 0 0 0 -V +1 0 0 0 +V -1 +1 -B 0 0 -V +1 -1

2.总结经验方法

了解了基本的编码规则,手算的方法有很多, 细心总能得到最后的结果。但是对于机器而言,应该有一种比较简单的方法,下面就介绍一下适合机器的编码方法。
1、源码是1时,暂时不变;
2、连0不超过3个时不变,有4个或以上连0时把每4个0换为取代节,即B00V;
3、确定B是0还是±1:第一个B一般取0,若两个取代节之间1的个数为偶,易推得后者的B一定是±1,此时B和1遵循的规则完全相同,可以直接记为1,即100V;为奇则一定是0,记为0,即000V。
4、统一确定极性:第一个非0符一般取-1,之后,根据前一个非0符极性,V取同,1取反;

二、MATLAB 实现HDB3编码和解码

1.实现HDB3的编码

我是按照这个步骤自己一步一步写的,效率比较低,网上有很多效率很高的代码,大家也可以去学习。
准备工作

%给出一个源码
Sn = [ 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 1 ];
n = length(sn);

codeSn = Sn;

第一步:找出源码中的取代节 V用2表示 B用3表示

count = 0; %用来记录 连0 的个数

for i = 1:n
    if(codeSn(i) == 1)
        count = 0; %遇到10的计数器清零
    else
        count = count + 1;
        if count == 4  % 0000 转成 取代节
            codeSn(i) = 2;
            codeSn(i-3) = 3;
            count = 0;  %计数清零
        end
    end
end

结果:

Sn = [ 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 1 ];
codeSn = [1 3 0 0 2 1 3 0 0 2 1 1 3 0 0 2 1 1];

可以看到四个连0 全部变成了取代节 3002 也就等价于 B00V。
第二步:处理取代节中B的值

flagB = 1;
count_1 = 0;
pV = 0;
pB = 0;

for i = 1:n
    if (codeSn(i) == 3) && (flagB == 1) %将第一个B 置 0
        codeSn(i) = 0;
        flagB = 0;
    end
    
    if codeSn(i) == 2 %找到前一个取代节的V
        pV = i;
    else if codeSn(i) == 3 %找到后一个取代节的B
            pB = i;
        end
    end
    
    if(pB > pV)
        for j = pV+1 : pB-1   %不要将B 和 V的值包含进去
            count_1 = count_1 + codeSn(j); %计算两个之间 1 的个数
        end
        
        if mod(count_1 , 2) == 1 %奇数个
            codeSn(pB) = 0;
        else
            codeSn(pB) = 1; %偶数个
        end
        %将变量归零,等待下一次找两个取代节的成功
        pV = 0;
        pB = 0;
        count_1 = 0;
    end
end

这一步的过程我写的太过于复杂。这要的功能是两个。
第一个:将第一个B转成0.
第二个:找到后一个取代节和前一个取代节之间1的个数,奇数个就将B变成0,偶数个就变成 1.
结果:codeSn =[1 0 0 0 2 1 0 0 0 2 1 1 1 0 0 2 1 1]
可以看到其中第一个B转成了0,后续一个变成了0,一个变成1;
第三步:%统一确定极性

%统一确定极性
even = 0;  % 用来翻转 1 的极性
evenV = 0;% 用来翻转 V 的极性

for i = 1:n
    if codeSn(i) == 1
        codeSn(i) = -1; %第一个 1 转成 -1 
        break;
    end
end


for i = 1:n
    if codeSn(i) == 1 %1 的极性正负翻转
        if even == 0
            codeSn(i) = 1;
        else
            codeSn(i) = -1;
        end
        even = ~even;
    else if codeSn(i) == 2  %将 V 的极性正负翻转 同时变回 数值 1
            evenV = even;   %第一个V的极性与前一个非零符号相同
            if evenV == 0
                codeSn(i) = -1;
            else
                codeSn(i) = 1;
            end
            evenV = ~evenV;
        end
    end
end

通过这一步来实现极性的全部分配,B在上一步已经全部变成1了,只要将1的极性正负交替就行。V的极性也要正负交替,第一个也给他整成-1能保持,V的两个特性了:1.自身极性交替。2.与前一个非0符号的极性相同。
结果:codeSn =[-1 0 0 0 -1 1 0 0 0 1 -1 1 -1 0 0 -1 1 -1];
到这里编码已经完成。下面将源码的图像和编码后的图像,打印出来,看一看区别。
实现代码:

%绘图部分
figure(1);
subplot(2,1,1);
stairs(0:length(Sn)-1,Sn);
axis([0 length(Sn) -2 2]);
title('源码图'); grid; %打开网格

subplot(2,1,2);
stairs(0:length(codeSn)-1,codeSn);
axis([0 length(codeSn) -2 2]);
title('hdb3编码图'); grid; %打开网格

显示结果:
在这里插入图片描述

2.实现HDB3的解码


完成hdb3的编码之后,下一步就是进行解码。解码的方式根据百度百科的介绍就可以,相对于编码,解码的过程比较简单。

  1. 把原来的取代节(4个连零)找到即可,若3连“0”前后非零脉冲同极性,则将最后一个非零元素译为零,如+1000+1 就应该译成“10000”,否则不用改动;若2连 “0”前后非零脉冲极性相同,则两零前后都译为零,如-100-1,就应该译为0000,否则也不用改动.
  2. 再将所有的-1变换成+1后,就可以得到原消息码。
%hdb3 解码部分
Sn = [-1 0 0 0 -1 1 0 0 0 1 -1 1 -1 0 0 -1 1 -1 ];
dchdbn = Sn;  %定义一个输出数组
count = 0;

for j = 1 : length(Sn)  
    if Sn(j) == 0 
        count  = count + 1;
        if  count == 3  %3连“0”前后非零脉冲同极性,则将最后一个非零元素译为零
            if dchdbn(j + 1) * dchdbn(j - 3) == 1
                dchdbn(j + 1) = 0;
            end
        end
        if count == 2 %2连 “0”前后非零脉冲极性相同,则两零前后都译为零
            if dchdbn(j + 1) * dchdbn(j  - 2) == 1;
                dchdbn(j  - 2) = 0;
                dchdbn(j + 1) = 0;
            end
        end
    else
         count = 0;   
    end
end

%极性变换
for n = 1 : length(Sn) %再将所有的-1变换成+1后,就可以得到原消息代码
    if dchdbn(n) == -1
        dchdbn(n) = 1;    
    end
end

结果:dchdbn = [1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 1];
这里就不绘图展示最后的结果了。

总结

总而言之,hdb3的编码规则就是这样,具体如何实现,看自己的思路了。之前学习过matlab但是,使用的次数不多,其中有很多功能还不知道。多多练习才是最近的捷径。MATLAB的仿真就是这样下面进行FPGA中的实验。将语言的风格转变为并行风格,又需要怎么样的编程思路那?
已经根据评论做出指正(2021.11.13)。

  • 30
    点赞
  • 202
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值