matlab实现三元码编码(AMI码,HDB3码,B6ZS码)
目录
三元码指的是用信号幅度的三种取值表示二进制码,三种幅度的取值为:+A,0,-A,或记作+1,0,-1。
下面将介绍三种三元码及其具体的matlab编码。
编码之前先定义要编码的二进制码。
clc clear % 定义二进制信码 code = [1 1 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1]; % 创建时间轴数据 t = 0:0.5:(length(code)*100-1)*0.5;
1、传号交替反转码(AMI)
在AMI码中,二进制码0用0电平表示,二进制码1交替的用+1和-1的半占空归零码表示。
%AMI码 AMI=[]; flag = 1; % 初始极性为正,即第一个1出现时用1的半占空归零码表示 for i = 1:length(code) if code(i) == 1 AMI = [AMI ones(1, 50)*flag zeros(1,50)] if flag==1 flag=-1; else flag=1; end else AMI = [AMI zeros(1,100)] end end
2、HDB3码
HDB3的编码流程可以表示为以下三个步骤:
1、找到取代节的位置,即出现4个连0码的地方
定义count_0计数连0的个数,每次遇到1或者一轮的取代节取代结束都将其归零,开启新一轮的计数。
2、确定使用哪一种类型的取代节,选择的原则是保证相邻V脉冲之间的B脉冲个数为奇数。
定义count2V_1计数相邻V脉冲之间的B脉冲个数,遇到1加1,一轮的取代节取代结束将其归零,计算下一相邻V脉冲之间的B脉冲个数。
3、确定取代节中B脉冲和V脉冲的极性,B脉冲的极性保持交替反转,V脉冲的极性跟着上一个B脉冲走。
定义count_1计算B脉冲的个数,B脉冲的个数包括二进制码中本来就包括的1以及生成的取代节中的1,所以如若取代节为B00V型,取代结束之后count_1还需加1。
未出现连4个0情况时,HDB3码与AMI码相同。
%HDB3码 HDB3=[]; flag = 1; % 初始极性为正 count_0 = 0;%记录连0个数 count2V_1 = 0;%计算两个V之间1的个数,用于确定是B00V型还是000V型 count_1 = 0; %计算总的1的个数,用于确定B的极性 for i = 1:length(code) if code(i) == 1 %当不连0时,与AMI一样 HDB3 = [HDB3 ones(1, 50)*flag zeros(1,50)] count_0 = 0; %连0个数清0,开启新一轮计数 count_1 = count_1+1;%总的1的个数加1 count2V_1 = count2V_1 + 1;%两个V之间1的个数加1 if flag==1 flag=-1; else flag=1; end else %出现了0 count_0 = count_0+1; if(count_0 < 4) %仍然和AMI码一样 HDB3 = [HDB3 zeros(1,100)] else %出现了四个连零 if mod(count2V_1 ,2 ) == 1 %奇数个,为000V类型,V的极性跟着上一个B走(10) HDB3 = [HDB3 ones(1,50) zeros(1,50)] count_0 = 0; %连零个数清零 count2V_1 = 0 %两个V之间1的个数清零,总的1的个数不清零 else %偶数个,为B00V型,V的极性跟着上一个B走(-10) if mod(count_1 ,2) == 0 %偶数个1,B的极性轮到1,V跟着B走 HDB3( (i-3)*100-99:(i-3)*100-50 ) = 1*ones(1,50) %B HDB3 = [HDB3 ones(1,50) zeros(1,50)] %V flag = -flag; count_0 = 0; %连零个数清零,开启新一轮连0计数 count2V_1 = 0 %两个V之间1的个数清零,总的1的个数不清零 count_1 = count_1 + 1; else %奇数个1,B的极性轮到-1,V跟着B走 HDB3( (i-3)*100-99:(i-3)*100-50 ) = -1*ones(1,50) %B HDB3 = [HDB3 -1*ones(1,50) zeros(1,50) ] %V flag = -flag; count_0 = 0; count2V_1 = 0; count_1 = count_1 +1; end end end end end
3、B6ZS码
与HDB3码类似,当连0为3时,取代节为0VB。B脉冲的极性保持交替反转,V脉冲的极性跟着上一个B脉冲走。
%BNZS码 BNZS = [] count_0=0; count_1=0; flag =1; for i = 1:length(code) if code(i) == 1 %当不连0时,与AMI一样 BNZS = [BNZS ones(1, 50)*flag zeros(1,50)] count_0 = 0; %连0个数清0 count_1 = count_1+1;%总的1的个数加1 if flag==1 flag=-1; else flag=1; end else %出现了0 count_0 = count_0+1; if(count_0 < 3) BNZS = [BNZS zeros(1,100)] else %出现了3个连零,用0vb,接下来判断VB的极性 if mod(count_1,2)==1 %奇数个1,V的极性跟着前一个B走,为正,00->10 BNZS( (i-1)*100-99:(i-1)*100-50 ) = 1*ones(1,50)%V BNZS = [BNZS -1*ones(1,50) zeros(1,50)] %B count_1 = count_1 +1; count_0=0; else%偶数个1 BNZS( (i-1)*100-99:(i-1)*100-50 ) = -1*ones(1,50) BNZS = [BNZS ones(1,50) zeros(1,50)] count_1 = count_1 +1; count_0=0; end end end end
4、完整代码
clc clear % 定义二进制信码 code = [1 1 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1]; % 创建时间轴数据 t = 0:0.5:(length(code)*100-1)*0.5; % 单极性非归零码:1的时候为1,0的时候为0 NRZ3 = [];%存储单极性非归零码 for i = 1:length(code) if code(i) == 1 %使用方括号拼接两个向量[] NRZ3 = [NRZ3 ones(1, 100)];%为了和t长度一样,一次的跨度也要为100 else NRZ3 = [NRZ3 zeros(1, 100)]; end end %AMI码 AMI=[]; flag = 1; % 初始极性为正 for i = 1:length(code) if code(i) == 1 AMI = [AMI ones(1, 50)*flag zeros(1,50)] if flag==1 flag=-1; else flag=1; end else AMI = [AMI zeros(1,100)] end end %HDB3码 HDB3=[]; flag = 1; % 初始极性为正 count_0 = 0;%记录连0个数 count2V_1 = 0;%计算两个V之间1的个数,用于确定是B00V型还是000V型 count_1 = 0; %计算总的1的个数,用于确定B的极性 for i = 1:length(code) if code(i) == 1 %当不连0时,与AMI一样 HDB3 = [HDB3 ones(1, 50)*flag zeros(1,50)] count_0 = 0; %连0个数清0,开启新一轮计数 count_1 = count_1+1;%总的1的个数加1 count2V_1 = count2V_1 + 1;%两个V之间1的个数加1 if flag==1 flag=-1; else flag=1; end else %出现了0 count_0 = count_0+1; if(count_0 < 4) %仍然和AMI码一样 HDB3 = [HDB3 zeros(1,100)] else %出现了四个连零 if mod(count2V_1 ,2 ) == 1 %奇数个,为000V类型,V的极性跟着上一个B走(10) HDB3 = [HDB3 ones(1,50) zeros(1,50)] count_0 = 0; %连零个数清零 count2V_1 = 0 %两个V之间1的个数清零,总的1的个数不清零 else %偶数个,为B00V型,V的极性跟着上一个B走(-10) if mod(count_1 ,2) == 0 %偶数个1,B的极性轮到1,V跟着B走 HDB3( (i-3)*100-99:(i-3)*100-50 ) = 1*ones(1,50) %B HDB3 = [HDB3 ones(1,50) zeros(1,50)] %V flag = -flag; count_0 = 0; %连零个数清零,开启新一轮连0计数 count2V_1 = 0 %两个V之间1的个数清零,总的1的个数不清零 count_1 = count_1 + 1; else %奇数个1,B的极性轮到-1,V跟着B走 HDB3( (i-3)*100-99:(i-3)*100-50 ) = -1*ones(1,50) %B HDB3 = [HDB3 -1*ones(1,50) zeros(1,50) ] %V flag = -flag; count_0 = 0; count2V_1 = 0; count_1 = count_1 +1; end end end end end %BNZS码 BNZS = [] count_0=0; count_1=0; flag =1; for i = 1:length(code) if code(i) == 1 %当不连0时,与AMI一样 BNZS = [BNZS ones(1, 50)*flag zeros(1,50)] count_0 = 0; %连0个数清0 count_1 = count_1+1;%总的1的个数加1 if flag==1 flag=-1; else flag=1; end else %出现了0 count_0 = count_0+1; if(count_0 < 3) BNZS = [BNZS zeros(1,100)] else %出现了3个连零,用0vb,接下来判断VB的极性 if mod(count_1,2)==1 %奇数个1,V的极性跟着前一个B走,为正,00->10 BNZS( (i-1)*100-99:(i-1)*100-50 ) = 1*ones(1,50)%V BNZS = [BNZS -1*ones(1,50) zeros(1,50)] %B count_1 = count_1 +1; count_0=0; else%偶数个1 BNZS( (i-1)*100-99:(i-1)*100-50 ) = -1*ones(1,50) BNZS = [BNZS ones(1,50) zeros(1,50)] count_1 = count_1 +1; count_0=0; end end end end figure(1) subplot(4,1,1) plot(t, NRZ3, 'LineWidth', 2) axis([0 (length(code)*100-1)*0.5 -1 1.5]) title('单极性非归零码') xlabel('时间') ylabel('幅度') grid on; subplot(4,1,2) plot(t, AMI, 'LineWidth', 2) axis([0 (length(code)*100-1)*0.5 -1 1.5]) title('AMI码') xlabel('时间') ylabel('幅度') grid on; subplot(4,1,3) plot(t, HDB3, 'LineWidth', 2) %stairs(0:length(HDB3)-1,HDB3); axis([0 (length(code)*100-1)*0.5 -1 1.5]) title('HDB3码') xlabel('时间') ylabel('幅度') grid on; subplot(4,1,4) plot(t, BNZS, 'LineWidth', 2) axis([0 (length(code)*100-1)*0.5 -1 1.5]) title('BNZS码') xlabel('时间') ylabel('幅度') grid on;
具体实现:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)