距离上次发文已经差不多3个月了,一是最近做实验写论文一直被拒搞得自己心情十分低落,二是最近自己又想学习CV相关的知识,所以通信方面的学习就停滞下来了,但是为了复习或者是巩固自己仅有的通信知识,还是要隔一段时间拿出来回忆一下。
在通信实验的仿真过程中,信道编码的增加不可或缺,因为信道编码的增加可以提高系统的可靠性,通信系统无非就是在可靠性和有效性两个大的方面进行优化,同时也引出了信源编码和信道编码这两个概念,信道编码主要通过增加冗余信息来提高系统的可靠性,而信源编码则是压缩信息来增加系统的传输速率,也就是提升有效性,这两个方面又是相互矛盾的,因此我们总是在寻找一个折中的方案来设计通信系统。所以,我们在不考虑传输速率的前提下,单方面考虑信道编码对系统的影响来进行仿真实验。
下面直接通过代码讲解,因为是在之前BPSK仿真的基础上添加的编码仿真,因此只解释关于增加编码的部分。此处也只是使用了比较简单的汉明码和循环码,还有许多更加优秀的编码方案例如卷积码和在5G中使用的LDPC码,这些等我后续学会了,在记录分享。
% 产生原始信息序列
signal_bit = randi([0 1],1,2000);
% 增加编码
signal_coding = encode(signal_bit,7,4,'hamming/binary'); % (7,4)汉明编码
编码的实现主要借助encode()函数,这个函数可以实现几个简单的线性分组具体的介绍以及例子可以help一下
相应的在发射端有编码在接收端就应该有解码
% 判决
de_signal_bit = demod(rcos_signal_MF_option.');
rx_signal = de_signal_bit(20+(1:length(signal_coding)),:);
% 解码
recover = decode(rx_signal,7,4,'hamming');
在解调之后增加一个解码的步骤然后再进行误码率的计算
不过值得注意的一点是,信噪比的设置,这很关键,要不然仿真出来结果是不正确的。
% 设置信噪比
ebn0 = -5:10;
snr = ebn0 + 10*log10(4/7) - 10*log10(16); % 采用bpsk调制且码率为4/7
看到了吧,一定要考虑到码率变化带来的增益,如果采用qpsk调制或者更高阶的调制方式,也要考虑阶数变化带来的增益。
以上是汉明编码的改动,下边再看一下循环码的改动。
% 增加编码
gpol = cyclpoly(a,b); % 产生循环码多项式 (a,b)为编码位数,这里采取a=7 b=4
parmat = cyclgen(a,gpol);
trt = syndtable(parmat);
signal_coding = encode(signal_bit,a,b,'cyclic/binary',gpol);
循环码相比于汉明码稍微复杂,涉及到码表的知识,具体的编码算法,我找了一篇文章,大家可以参考学习一下循环码编码方法。
相应的解码方式为
% 解码
recover = decode(rx_signal,a,b,'cyclic/binary',gpol,trt);
最后附上,两种编码方式的仿真结果。
分析以上误比特曲线图可以发现,大约在Eb/No为6dB时曲线发生相交,低于6dB时,增加编码反而会导致错误概率的增加,这主要是因为,每个编码方案都具有一定纠错能力范围,当信号畸变超出编码的纠错能力时,反而会雪上加霜,但是在纠错能力范围之内又会是锦上添花,这就是信道编码带来的效果。
最后附上一个完整的代码过程,供大家交流学习吧。
% ===============BPSK系统级仿真实验============
% 时间:2022.7.12
% 作者:华清小学生
% 环境:MATLAB 2019b
% =============================================
clear
close all
clc
% =====================参数设定================
sps = 16; % 上采样倍数
fc = 2000; % 载波频率
fs = 16000; % 采样频率
% =======================发射机================
% 产生原始信息序列
signal_bit = randi([0 1],1,2000);
% 增加编码
signal_coding = encode(signal_bit,7,4,'hamming/binary');
tx_signal = [zeros(1,20) signal_coding ones(1,20)];
% BPSK调制
% mod = comm.BPSKModulator(); % bpsk调制器
% demod = comm.BPSKDemodulator(); % bpsk解调器
mod = comm.PSKModulator('ModulationOrder',2,'PhaseOffset',pi/4);
demod = comm.PSKDemodulator('ModulationOrder',2,'PhaseOffset',pi/4);
signal_mod = mod(tx_signal.'); % 对信号转置,保证输入为列向量
% 脉冲成型
% 插值(上采样)
up16_signal_mod = upsample(signal_mod.',16);
% 滚降滤波器
r_factor = 0.5; % 滚降系数
rcos_fir = rcosdesign(r_factor,6,sps);
% 滚降滤波
rcos_signal = filter(rcos_fir,1,up16_signal_mod);
h = rcosdesign(0.5,6,8);
% stem(h)
% 载波发送
time = 1:length(up16_signal_mod);
rcos_signal_carrier = rcos_signal.*cos(2*pi*fc.*time/fs);
% ========================信道=====================
% 加噪声
% 设置信噪比
ebn0 = -5:10;
snr = ebn0 + 10*log10(4/7) - 10*log10(16);
n = 300;
err_number = zeros(n,length(snr));
bit_err_ratio = zeros(n,length(snr));
for j = 1:n
for i = 1:length(snr)
% 高斯白噪声信道
rcos_signal_carrier_noise = awgn(rcos_signal_carrier,snr(i),'measured');
%==================接收机=====================
% 载波恢复
% 相干解调
rcos_signal_noise = rcos_signal_carrier_noise.*cos(2*pi*fc.*time/fs);
% 滤波
% 低通滤波器
fir_lp = fir1(128,0.2); % 截止频率为0.2*(fs/2)
rcos_signal_lp = filter(fir_lp,1,rcos_signal_noise);
% 匹配滤波(根余弦滚降)
rcos_fir = rcosdesign(0.5,6,sps);
rcos_signal_MF = filter(rcos_fir,1,rcos_signal_lp);
% 选取最佳采样点
decision_pos = 161; % (96+128+96)/2 = 160 三个滤波器的延迟
% 每个符号选取一个点作为判决
rcos_signal_MF_option = rcos_signal_MF(decision_pos:sps:end);
% 判决
de_signal_bit = demod(rcos_signal_MF_option.');
rx_signal = de_signal_bit(20+(1:length(signal_coding)),:);
% 解码
recover = decode(rx_signal,7,4,'hamming');
% 误码性能对比
[err_number(j,i),bit_err_ratio(j,i)] = biterr(signal_bit(1:length(recover)),recover.');
end
end
err_number_mean = mean(err_number);
bit_err_mean = mean(bit_err_ratio);
% 仿真结果
ber = berawgn(ebn0,'psk',2,'nondiff');
semilogy(ebn0,bit_err_mean,'-*',ebn0,ber,'-+');
xlabel('Eb/No(dB)');
ylabel('BER');
title('不同信噪比下的误码率曲线(BPSK)');
legend('BPSK+汉明编码实验曲线','BPSK理论曲线');
grid on