2.HDB3码的编译码原理
HDB3码是AMI码的一种改进型,其目的是为保持AMI码的优点而克服其缺点,使连“0”个数不超过3个。其编码规则如下:
(1)当信码的连“0”个数不超过3时,仍按AMI码的规则编,即传号极性交替;
(2)当连“0”个数超过3个时,则将第的4个“0”改为非“0”脉冲,记为+V或—V称之为破坏脉冲。相邻V码的极性必须交替出现,以确保编好的码中无直流;
(3) 为了便于识别,V码的极性应与前一非“0”码的极性相同,否则,将四连“0”的第一个“0” 更改为与该破坏脉冲相同极性的脉冲,并记为“+B”或“-B”;
破坏脉冲码之后 的传号极性码也要交替。
2.通过仿真验证HDB3码的原理
![](https://pic1.zhimg.com/80/v2-48f65b52169d8279ec805fc3c61c6cc0_720w.jpg)
随机生成一组只包含01的数据(50个数),如上图所示,分别为原码型和HDB3码型,眼图。
数据:
1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 0
0 1 1 0 0 1 1 0 0 1 0 0 0 0 1 1 0 1 1 1
0 1 1 1 1 1 1 0 0 0
3.分析HDB3码的优缺点
虽然HDB3编码规则比较复杂,但译码却比较简单。从上述原理看出,每一个破坏符号V总是与前一个非“0”符号同样的极性(包括B在内)。这也就是说,从收到的符号序列中可以容易地找到破坏点V,于是也断定V符号及其前面的3 个符号必是连“0”的符号,从而恢复4个连“0”码,再将所有-1变成+1后便等到原信息代码。HDB3码保持了AMI码的优点外还将连“0”码限制在3 个以内,故有利于定时信号的提取。
==========================================
HDB3码的编码和译码
1、实验要求:掌握HDB3码的编码规则,利用MATLAB设计并实现HDB3码的编码和译码。
2、原理简述:
例1:
例2:
消息代码: 1 0 0 0 0 1 0 0 0 0 1 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
简易编码方法:
原理:HDB3码既要包含AMI的交替特性使输出无直流特性,又要不出现四个以上的连0,因此可以先满足后者。
1)把"0000"换为取代节。
规则:先将"0000"分离开来,第一个"0000"直接变为"000V",然后数相邻两个"0000"之间"1"的个数,奇数则变为"000V",偶数则变为" B00V"。
2)更新符号。
根据教材有:B总是与其前面的1或V符号相反,V总是与前面的1或B相符号相同,1总是与前面的V或B符号相反,就可以编符号了。
例如:
消息代码:1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1
中间码: 1 0 0 0 V 1 0 0 0 V 1 1 B 0 0 V 1 1 B 0 0 V B 0 0 V 1 1 1 0 0 0 V 1
HDB3码:+10 0 0 +V -1 0 0 0 -V +1 -1 +B 0 0 + V -1 +1 -B 0 0 -V +B 0 0 +V -1 +1 -1 0 0 0 -V +1
解码规则:
1)虽然编码很复杂,但解码规则很简单,若3连“0”前后非零脉冲同极性,则将最后一个非零元素译为零,如+1000+1就应该译成“10000”;若2连 “0”前后非零脉冲极性相同,则两零前后都译为零,如-100-1,就应该译为0000.
2)再将所有的-1变换成+1后,就可以得到原消息代码。
注意:本次作业,每道题需要单独提交一个PDF文档。
作业1:HDB3码的编解码。
需要设计3个函数,其中:HDB3CODE( ),调用该函数,如hdb3=HDB3CODE(s),可以把输入的信号s(nrz码)转换为hdb3码;其中HDB3deCODE()函数,调用该函数,如HDB3deCODE(hdb3),可以把输入的hdb3码转换为nrz码;其中AMI( )函数,可以把输入的信号s转换为AMI码。并测试三个函数的性能,并把nrz,ami,hdb3,hdb3解码后的nrz码,分别画出来,效果如下图:
ps:代码框架已经写好,你需要做的,就是把HDB3deCODE()函数里面的????? 地方补上正确的代码。另外,如果对HDB3码的编解码规则还有疑惑,可以自行在百度或者b站查资料学习。
%测试AMI HDB3函数
s_nrz=[1 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1 1 ] %随机生成一个NRZ码序列s
s_ami=AMI(s_nrz) %调用AMI函数,把NRZ码变成ami码
s_hdb3=HDB3CODE(s_nrz) %调用HDB3CODE函数,把s变成HDB3码
s_hdb3_nrz=HDB3deCODE(s_hdb3) %调用HDB3deCODE函数,把HDB3变成NRZ码
subplot(2,2,1),stairs(s_nrz), grid on,ylim([-1.1 1.1]), title( 'NRZ码' ) ; %设置title
subplot(2,2,2),stairs(s_ami), grid on,ylim([-1.1 1.1]), title( 'ami码' ) ;
subplot(2,2,3),stairs(s_hdb3), grid on,ylim([-1.1 1.1]), title( 'HDB3码' ) ;
subplot(2,2,4),stairs(s_hdb3_nrz), grid on,ylim([-1.1 1.1]), title( 'HDB3解码为NRZ码' ) ;
function hdb3=HDB3CODE(s)
%GDCP,ccl, 20240603
flag=1;
L=length(s); %测量NRZ码的长度
hdb3=AMI(s); %把NRZ码通过AMI()函数转换成AMI码,给变量hdb3,注意此时变量hdb3实际上还是ami码
v=1; %初始化标识v为+1;
num_zeros=0; %num_zeros表示连0的个数
for k=1:L %遍历数组
if hdb3(k)==0 %如果数组hdb3当前元素为0,则计数器num_zeros+1
num_zeros=num_zeros+1;
else %如果数组hdb3当前元素不是0,则计数器num_zeros的值归零;
% 比方说前面已经有2个0,此时遇见了1,则计数器重新归零,为下一步计算0的个数做准备。
num_zeros=0;
end
if num_zeros==4 %如果目前计数器num_zeros已经累计了4个0
hdb3(k)=v; %则当前位置(即这连续4个0中的第4个0)由V替代
v=-1*v; %因为v的极性需要正负交替,
num_zeros=0; %计数器num_zeros归零,重新开始记录下一个4连0的情况。
try %一般情况
if hdb3(k-4)~=hdb3(k) %如果出现'1000V',而V又和最前那个1的极性不同
hdb3(k-3)=hdb3(k); %则改为'1b00v'
hdb3(k+1:end)=-1*hdb3(k+1:end); %并且从'1b00v'之后的所有正负1的极性翻转
end
catch %如果数组s的前4个元素就是0,如以'0000'开头的数组,
if k==4 %则hdb3(k-4)为hdb3(0),显然下标越界,不用写成hdb3(k-4)~=hdb3(k),直接用 if k==4
hdb3(k-3)=hdb3(k); %把'0000'改为'b00v'
hdb3(k+1:end)=-hdb3(k-3)*hdb3(k+1:end); %从'b00v'之后的所有正负1的极性翻转
end
end
end
end
end
function decode=HDB3deCODE(hdb3)
L=length(hdb3);
if L<4 %如果数组长度小于4
decode=abs(hdb3); %直接把hdb3取绝对值给decode
return;
else %如果长度大于等于4
for k=4:L %从hdb3码的第4位开始遍历数组
if ????? %如果出现'1001'或'-100-1'
????? %则直接把这这4个元素改为'0000'
elseif ????? %如果出现'10001'或'-1000-1'
????? %则直接把这这5个元素改为'10000'
end
end
decode=abs(hdb3); %最后把剩余其他码也取绝对值,就得到解码后的decode(nrz)码了
end
end
function y=AMI(s)
flag=1; %极性flag初始化为1
L=length(s);
for k=1:L %遍历数组s(nrz码)
if s(k)==1 %如果当前元素为1
s(k)=flag; %则给当前位置赋予一个极性flag
flag=-1*flag; %flag反转,以保证下一个极性和当前极性是相反的
end
end
y=s;
end
作业2:编写一个程序,对AM调制、DSB调制、FM调制进行仿真;
可以设时间为t=0:0.001:30; 要传输的信号频率为1,即s_signa=sin(t);
载波频率为10,即s_carry=sin(10*t);
直流分量a0=2;
调频指数分别设置为k1=2和k2=6,看看两种情况下FM的波形的区别。
最后再把 “信号源,载波,am波,dsb波,fm1,fm2”这6个图按照3行2列的方式绘制出来,效果如下:
作业3:编写函数prime_N求解给定整数N之内的所有素数;
要求:采用主函数与子函数的模式;
子函数is_prime(K)用来判断k是否是素数,如果是,则返回1,否则返回0;
主函数则用来遍历2-N之间的每一个整数,如果该数是素数则记录到数组prime中,并且计数器num加1,最终函数返回记录了N之内的所有素数的数组prime,以及素数的个数num。
以下为(1)的提示性代码,供参考;
function [prime,num] = prime_N(N) %主函数prime_N()
%此函数用于找出给定的N之内的所有素数
% 函数[prime,num] = prime_N(N) 中,返回的数组prime记录了N之内的所有素数,num记录了N之内的素数的总数。
num=0; %Num记录发现的素数的个数,初始值为0
%采用for循环,挨个判断2-N之间的每一个数是否为素数,如果是素数,则计数器num+1,并把该数字添加到数组prime中;
%注意,判断某个数是否为素数的任务通过调用子函数is_prime() 完成。
end
function y = is_prime(N) %子函数is_prime()
%子函数 is_prime(N) 用于判断给定的数N是否是素数
%如果给定的N是素数,则返回1,否则返回0
end
调用效果如下:
一、HDB3 码是什么?
HDB3全称(High Density Bipolar of order 3 code,三阶高密度双极性码),HDB3码是对AMI码的一个进阶。
1.编码规则
了解编码规则之前,先了解一下其中的关键名词。
V:破坏脉冲。
B:调节脉冲。
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取反;