matlab仿真 信道编码和交织(上)

(内容源自详解MATLAB/SIMULINK 通信系统建模与仿真   刘学勇编著第八章内容,有兴趣的读者请阅读原书) 

​ 

​ 

clear all
N=10;%信息比特的行数
n=7;%hamming码组长度n=2^m-1
m=3;%监督位长度
[H,G]=hammgen(m);%产生(n,n-m)hamming码的效验矩阵和生成矩阵
x=randi([0 1],N,n-m);%产生比特数据
y=mod(x*G,2);%hamming编码
y1=mod(y+randerr(N,n),2);%在每个编码码组中引入一个随机比特错误
mat1=eye(n);%生成n*n的单位矩阵,其中每一行的1代表错误比特位置
errvec=mat1*H.';%校验结果对应的所有错误矢量
y2=mod(y1*H.',2);%译码
%根据译码结果对应的错误矢量找出错误比特的位置,并纠错
for indx=1:N
    for indx1=1:n
        if(y2(indx,:)==errvec(indx1,:))
            y1(indx,:)=mod(y1(indx,:)+mat1(indx1,:),2);
        end
    end
end
x_dec=y1(:,m+1:end);%恢复原始信息比特
s=find(x~=x_dec)%纠错后的信息比特与原始信息比特对比

   首先,(7,4)汉明码是指7个码元中携带了4个有效信息,还有三个是冗余位,是用奇偶校验留下来的检错信息。

先从最简单的情况开始,假设我们需要传递的信息为[0 1 0 1],

以偶校验的1,3,4位为例,这三位的数据分别为0 0 1,为了确保加上校验位后有偶数个1,所以校验位为1,后面的1 2 3位,2 3 4位同理。

有了这三个校验位,当四个信息位出现错误的时候,我们可以根据校验位判断错误在什么地方。

可以看到,1,3,4位和1,2,3位中的交集有错,而2,3,4位没错,所以错误只可能出现在1号位

这里我们利用三个校验位的情况,成功的锁定了错误码元的所在位置。

(这里没有讨论出现偶数个码元错误的情况,和校验位错误的情况)

现在回到代码

x是我们产生的数据,其中的每一行可以称其为一组,一组有4个信息码元。

y是编码后的结果,我们一行一行看,绿色区域是每一组的校验位,红色区域是每一组的信息位(红色就是x)

​ 

y=mod(x*G,2);

 这里的代码意思是x*G得到的矩阵每个元素对2取余,其实就是异或,也就是我们之前在进行校验位的计算时使用的方式

G就是生成矩阵,把之前的我们从4个信息位编码成7个码元的过程用矩阵乘法进行表示

红色部分就是单位矩阵,用来将信息部分原封不动的传进

黄色部分就是产生校验位的部分,信息码元与它进行矩阵乘法再异或后就能得到上述的校验位。

这样就解释了为什么x*G再取异或后就能实现编码过程。

接下来来看解码过程,解码需要用到校验矩阵H

y2=mod(y1*H.',2);%译码

 可以发现,由于在编码过程中的设计,在乘上H’之后,如果没有错误的情况下,得到的矩阵中元素全都为0

现在我们假设信息码元中出现了一位错误。在解码之后得到的矩阵元素不全为0,证明有错误,我们需要用我们得到的 [0 ,1,1]找到错误出现的位置

总结:译码的结果并不是原始数据,而是表示错误情况的向量(矩阵)(y2),如果矩阵(y2)全为0 ,证明没有错误,如果不全为0,证明有错误,我们通过逐行比较译码结果(y2)和所有的错误情况(errvec),观察每一行的译码结果与哪一行的errvec相同,得到的errvec的行数,就是y1中出现错误的位数

现在也可以解释为什么说errvec是校验结果对应的所有错误矢量,因为errvec包含了所有含有非0元素(错误的)情况,比对就能得到错误位数

如果译码得到的是0 0 0,自然在errvec中没有对应的情况,也表示y1这一行没有错误,不需要修改。

clear all
N=1000000; %信息比特长度
M=4;%QPSK调制
n=7;%汉明码编码码组长度
m=3;%汉明吗监督位长度
graycode=[0 1 3 2];

msg=randi([0 1],N,n-m);%信息比特
msg1=reshape(msg.',log2(M),N*(n-m)/log2(M)).';
msg1_de=bi2de(msg1,'left-msb');%信息比特转化为10进制(1)
msg1=graycode(msg1_de+1);%格雷编码
msg1=pskmod(msg1,M);%qpsk调制
Eb1=norm(msg1).^2/(N*(n-m));%计算比特能量
msg2=encode(msg,n,n-m);%汉明编码(2)
msg2=reshape(msg2.',log2(M),N*n/log2(M)).';
msg2=bi2de(msg2,'left-msb');
msg2=graycode(msg2+1);%汉明编码后的比特序列转化为十进制形式
msg2=pskmod(msg2,M);%汉明码数据进行qpsk调制
Eb2=norm(msg2).^2/(N*(n-m));%计算比特能量
EbNo=0:10;%信噪比
EbNo_lin=10.^(EbNo/10);%信噪比的线性值
for indx=1:length(EbNo_lin)
    sigma1=sqrt(Eb1/(2*EbNo_lin(indx)));%未编码的噪声标准差
    rx1=msg1+sigma1*(randn(1,length(msg1))+j*randn(1,length(msg1)));%加入高斯白噪声
    y1=pskdemod(rx1,M);%未编码QPSK解调
    y1_de=graycode(y1+1);%未编码的格雷逆映射
    [err ber1(indx)]=biterr(msg1_de.',y1_de,log2(M));%未编码的误比特率
    
    sigma2=sqrt(Eb2/(2*EbNo_lin(indx)));%编码的噪声标准差
    rx2=msg2+sigma2*(randn(1,length(msg2))+j*randn(1,length(msg2)));%加入高斯白噪声
    y2=pskdemod(rx2,M);%编码qpsk解调
     y2=graycode(y2+1);%编码格雷逆映射
     y2=de2bi(y2,'left-msb');%转换为二进制形式
     y2=reshape(y2.',n,N).';
     y2=decode(y2,n,n-m);%译码
     [err ber2(indx)]=biterr(msg,y2);%编码的误比特率
    
end

 semilogy(EbNo,ber1,'-ko',EbNo,ber2,'-k*');
 legend('未编码','Hamming(7,4)编码')
 title('未编码和hamming(7,4)编码的QPSK在AWGN下的性能')
 xlabel('Eb/N0');ylabel('误比特率')

 (1):这里的转化为10进制是为了将二进制的信号转化为0-3的4进制情况,这样就可以进行格雷编码,进而qpsk调制

(2) encode和decode编译码本质上就是例8.1中的过程,这里使用现成的函数可以直接实现编译码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值