第1章:BPSK调制解调器

陈老湿·通信MATLAB仿真 专栏收录该内容
13 篇文章 62 订阅

一、从BPSK调制解调器说起

BPSK是二进制相移键控,是最基本的调制方式。本科时有一个经典的实验便是比较不同调制方式下的误码率曲线,并且与理论误码率曲线进行作比较。其实要完成这个实验,网上随随便便都可以查到理论的仿真代码,不需要信道编码、捕获、同步、匹配滤波、多普勒频偏等考量,但是一个仿真要越接近实际系统,便需要考虑的因素越多,代码难度便越大。

因此,本章从BPSK的调制解调器开始,熟悉一下通信从发端到收端的整个过程,作为之后通信仿真的基础。

img

典 型 数 字 通 信 系 统 的 方 框 图 典型数字通信系统的方框图

二、代码规范

我以前写代码是没有写注释习惯的,一是不知道怎么写才比较好看,二是写的比较少,觉得自己反正看得懂,也没别人想看我的代码,就是这么真实,哈哈哈哈哈。上研究生后,有团队之间的交流,真真切切体会到写代码注释的重要性。虽然在写的时候好像挺费事,这无疑为交流代码,以及日后自己的翻阅省下大量时间,慢慢写着写着就习惯写注释了。

除此之外,总结文档也是少不了的,可以记录仿真过程中常见的一些问题以及待解决的问题。就比如我写了几个通信MATLAB仿真,以为自己都懂了一样,其实就没有完全搞懂,在写总结或者给别人讲的过程中,我便可以发现自己理解是否透彻。因此我将自己的总结写到这里来,也是自己理清思路的过程。“代码+总结”,提升快一些。

结合通信从发端到收端的一个过程,给出一个简单模块化代码注释规范:

%%%%%%%%%%%%%%%%%%%%%  调制解调器仿真 %%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%  BPSK_modem_sim1.m %%%%%%%%%
%%%%% data:2020年6月6日  author:大将军 %%%%%%

%%%%%程序说明
%完成BPSK调制解调器的仿真
%具体的通信方式如下
%调制方式:BPSK 编码:无
%滚降因子:0.5  解码:无
%噪声类型:线性高斯白噪声
%解调方式:采用相干解调

%%%%%仿真环境
% 软件版本:MATLAB2019a

%%%%%%%%%%%%%%%%%%%%%  程序主体 %%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%  参数设定 %%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%  信源 %%%%%%%%%
%%%%%%调制器
%%%%%%%%%%%%%%%%%%%%%  信道 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
%%%%%%%%%接收机 %%%%%%%%%
%%%%%%%%%%解调器
%%%%%%%%%%%%%%%%%%%%%  信宿 %%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%  仿真结果 %%%%%%%%%

三、仿真正确性如何保证?

在仿真的过程中,我怎么知道我仿真是不是正确结果呢?发现了错误,怎么查找和纠正呢?

(1)靠理论知识分析,比如画误码率曲线,你一不小心就比理论误码率曲线还好的话,此时你就要静下心来分析是哪里出问题了;

(2)结合波形图来判断,比如信号的时域波形、频域波形、眼图、功率谱密度等等;

具体到实践中,有没有什么小技巧来保证算法正确性的?

当然是有的。

(1)从特殊到一般

还是以仿真BPSK的误码率曲线为例,横坐标是 E b / N 0 {E_b}/{N_0} Eb/N0 ,纵坐标是误码率。那刚开始仿真的时候,我们便先取一个非常非常大的 E b / N 0 {E_b}/{N_0} Eb/N0 ,此时误码率肯定也极小,基本没有误码,来验证你仿真代码中的其他部分是否有误。

确认无误后,调整不同的 E b / N 0 {E_b}/{N_0} Eb/N0 进行仿真,即可画出想要的误码率曲线。

(2)测试每个模块的正确后,再加入到大程序仿真中

比如在写BPSK调制解调器仿真中,会涉及升余弦滚降滤波器、低通滤波器、awgn加噪声等函数的使用,在测试与确认这些模块函数是正确时,再加入主程序中,便可增加程序成功的概率,若出问题,也方便后续做检查。

(3)在MATLAB中,,多在命令行使用“help”!!!“help”是真的好用呀!!

四、理论知识讲解与代码实现

在正式仿真之前,时间停顿几分钟,请你花时间思考以下问题:

(1)为什么要调制?(开始抢答!!!)

(2)基带成型的目的是为了什么?怎么MATLAB代码实现?滚降因子会对误码率有影响吗?为什么基带成型之前要进行上采样?内插和抽取的概念有木有呀?(本科的数字信号处理课程讲过内插和抽取。)

(3)匹配滤波器器的作用是什么?匹配滤波器与低通滤波器、高通滤波器这类滤波器有什么区别?

(4)匹配滤波后,如何找到最佳采样点?最佳采样点的概念有没有呀,同学们?(赶紧拿出书翻一下)

(5)信噪比与 E b / N 0 {E_b}/{N_0} Eb/N0 有关系吗? E b / N 0 {E_b}/{N_0} Eb/N0 有单位吗?在什么位置开始定义 E b / N 0 {E_b}/{N_0} Eb/N0 的?为什么数字通信里面,分析误码率曲线时,横坐标是 E b / N 0 {E_b}/{N_0} Eb/N0 呢?

(6)高斯白噪声信道时,噪声怎么加到信号上去呢?复噪声和实噪声的区别?

(7)信号的频域图、眼图怎么看?

…………………………………………

类似以上的问题,我在后面将一个个进行解答,这对你理解后面的完整程序很关键。

(1)为什么要调制?

数字调制将数字符号转换成适合信道特性的波形的过程。比如天线长度约束,比如大部分信道都具有带通传输特性,而基带信号不能直接在带通传输特性的信道中传输,比如一条信道如果一条信道要传输多路信号,也可以利用调制来区分不同的信号等等。

就我的理解,其实调制编码这些过程都是为了使得信号波形更加适应信道特性,有什么样的信道条件,便采用相应的编码调制方式,这句话,你慢慢品。

(2)讲到基带成型,就要理解无码间传输串扰的条件。奈奎斯特表示他快要出场了。

img

img

以上两图中,H是指发送滤波器、传输信道和接收滤波器的联合传输特性。

img

理想的方波信号,在频域上是对应Sa函数,但是Sa函数旁瓣功率大,容易对其他频率的信号进行干扰,导致失真。

因此要对基带信号进行成型,若将信号的带宽只限定在一定范围内,相当于对信号经过一个低通滤波器,两个频域信号的相乘运算是时域信号的卷积运算,这便会带来时域信号的延长。(这句话是否理解呢?时频的对偶性将会经常用到。)

由上面奈奎斯特第一准则,理想的成型滤波器是(a),但由于其陡降特性,是物理不可实现的。从冲激响应也可以看出,在零时刻之前便有非0输出,这是一个非因果系统,也是物理不可实现的。且观察到其拖尾较长,如果没有在Ts的整数倍时间进行抽样,值便不为0 ,容易给系统带来较大的码间串扰值。

因此,仿真中最常用的升余弦滚降滤波器,其尾部衰减较快,有利于减少码间串扰和位定时的影响。通常将发送滤波器 G T ( ω ) {G_T}\left( \omega \right) GT(ω) 和接收滤波器 G R ( ω ) {G_R}\left( \omega \right) GR(ω) 都设计为平方根升余弦滚降滤波器。若不考虑信道引起的码间串扰,两个平方根升余弦滚降滤波器便可以合成升余弦形式的传输函数,这也是因为频域相乘和时域卷积是等价的

在这里插入“均衡”的概念,就是 若 H ( ω ) = G T ( ω ) C ( ω ) G R ( ω ) H(\omega ) = {G_T}\left( \omega \right)C\left( \omega \right){G_R}\left( \omega \right) H(ω)=GT(ω)C(ω)GR(ω) 不满足无码间串扰的传输条件(即上面公式的5.5-6就是条件),那此时接收端加入一个均衡滤波器 H 1 ( ω ) {H_1}(\omega ) H1(ω) 使得 H ( ω ) H 1 ( ω ) H(\omega ){H_1}(\omega ) H(ω)H1(ω) 满足无码间串扰的传输条件,这便是均衡的概念。

请你思考:当发送滤波器 G T ( ω ) {G_T}\left( \omega \right) GT(ω) 的匹配滤波器吗?请给出相应的理由

我将在第(3)个问题中的解答给出答案。

接下来直接展示平方根升余弦滚降滤波器在MATLAB中如何实现,为满足因果系统方可实现,必须对其进行截断,可用help rcosdesign先对该函数的各参数进行学习。

%%%%%%%%%%%%%%%%%%%%% rcosdesign函数使用 %%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%% test_rcosdesign    %%%%%%%%%%%%%%%%%
%%%%%%%%%%%% 日期:2020年8月4日   作者:飞蓬大将军  %%%%%%%%%%%%%%%%%

%%%%%%%%%程序说明
%%% b = rcosdesign(beta,span,sps,shape)
%%% beta:滚降因子
%%% span: 表示截断的符号范围,对滤波器取了几个Ts的长度
%%% sps:每个符号的采样数
%%% shape:可选择'normal'或者'sqrt'
%%% b:1*(sps*span)的行向量,升余弦或余弦滤波器的系数

%****************************  程序主体 ****************%
clear all;
h1 = rcosdesign(0.25,1,6,'sqrt');
fvtool(h1,'Analysis','impulse'); %将脉冲响应可视化

%****************************  仿真结论 ***************%
%%%%%成型滤波器的使用

可以得到滤波器的传输特性图如下:

img

有了h1这个冲击响应参数后,怎么来表示信号经过滤波器这个过程呢?

我介绍两种不同的使用习惯,有的人喜欢用卷积函数、有的人喜欢用滤波函数。下面给出了信号经过两种方式下,滤波后的信号,读者可自行观察滤波前后的时域波形和频域波形图对这两种方式进行对比。

%%%%%%%%%%%%%%%%%%%%% 比较不同的滚降成型函数使用 %%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%        test_compare_rcos.m    %%%%%%%%%%%%%%%%%
%%%%%%%%%%%%      日期:2020年9月6日   作者:飞蓬大将军  %%%%%%%%%%%%%%%%%

%%%%%%%%%程序说明
%%% b = rcosdesign(beta,span,sps,shape)
%%% beta:滚降因子
%%% span: 表示截断的符号范围,对滤波器取了几个Ts的长度
%%% sps:每个符号的采样数
%%% shape:可选择'normal'或者'sqrt'
%%% b:1*(sps*span)的行向量,升余弦或余弦滤波器的系数

%****************************  程序主体 *************
%%%%%%%%%%%%%%%%%  参数设定   %%%%%%%%%%%%%%
bit_rate = 1000;% 比特率
symbol_rate = 1000;%符号率
sps = 16;%每个符号的采样点数
fc = 2000; %载波频率
fs = 16000; %采样频率

%%%%%%%%%%%%%%%%%   信源   %%%%%%%%%%%%%%%%%%%
%%%%随机信号
source_number = 352;
msg_source = randi([0 1],1,source_number);
%给出标志性的帧头,方便调试

frame_pre = ones(1,32); %用于捕获和同步
frame_begin = [0 1 1 1 1 1 1 0]; %帧开始标志
frame_head = [frame_pre frame_begin]; %帧数据
frame_end = [0 1 1 1 1 1 1 0]; %帧结束标志

%%%%组帧
frame_msg = [frame_head msg_source frame_end];


%%%%%%%%%%%%%%%%%  发射机  %%%%%%%%%%%%%%%%%%%

aaa = 1;
%%%%%双极性变换
bipolar_msg_source = 2*frame_msg-1; %双极性信号


% %波形观察
% figure(1);
% plot(bipolar_msg_source);
% title('时域波形');
% figure(2);
% plot(abs(fft(bipolar_msg_source)));
% title('频域波形');
% t1 = abs(fft(bipolar_msg_source));

%%%上采样
bipolar_msg_source_temp = [bipolar_msg_source',zeros(size(bipolar_msg_source,2),sps-1)]; 
length_x = size(bipolar_msg_source_temp,1);
length_y = size(bipolar_msg_source_temp,2);
up16_bipolar_msg_source = reshape(bipolar_msg_source_temp',1,length_x * length_y);


% %波形观察
% figure(3);
% plot(up16_bipolar_msg_source);
% title('时域波形');
% figure(4);
% plot(abs(fft(up16_bipolar_msg_source)));
% title('频域波形');
% 
% t2 = abs(fft(up16_bipolar_msg_source));



%%%%%%%滤波器
%%%%滚降滤波
%rcos_msg_source1= rcosflt(bipolar_msg_source,1000,16000);
% rolloff_factor默认为0.5

%%%滚降滤波器
rollof_factor = 0.5; %滚降因子,可调整
rcos_fir = rcosdesign(rollof_factor,6,sps);

%%%%滚降滤波
rcos_msg_source1 = filter(rcos_fir,1,up16_bipolar_msg_source);

rcos_msg_source2_temp = conv(up16_bipolar_msg_source,rcos_fir);
filter_start = (length(rcos_fir)-1)/2;
rcos_msg_source2 = rcos_msg_source2_temp(1,filter_start+1:length(rcos_msg_source2_temp)- filter_start);


aaa = 1; 
%波形观察
figure(1);
plot(rcos_msg_source1);
title('时域波形');
figure(2);
plot(abs(fft(rcos_msg_source1)));
title('频域波形');


%波形观察
figure(3);
plot(rcos_msg_source2);
title('时域波形');
figure(4);
plot(abs(fft(rcos_msg_source2)));
title('频域波形');

上面给出用filter函数和conv函数实现基带成型的过程,当然接收端也对应使用filter函数和conv函数进行匹配滤波便是

细心的同学或者已经运行过代码的同学可能已经发现了,在基带成型之前有一个“内插0”的过程,这是为什么呢?

这个问题可以说,我是想了非常久。

观察采样频率和符号速率的关系,fs与symbol_rate的比值便是我们决定一个符号采几个点,也叫过采样率,当然前提肯定是要满足奈奎斯特采样定理。比如上面代码设置的sps是16,即在一个符号里面采样16个点。

采用filter函数实行基带成型时,我们可以认为滤波器进入到正常工作或者说滤波本身是需要时间的,因此有一个延时,要将延时的这段时间数据进行截断掉

采用卷积运算来实现基带成型时,假设数据是一个长度为N的序列a,滤波器是长度为M的序列b,卷积出来的结果长度是N+M-1。我们要截断出和数据长度N相等的一个长度数据,可使用conv(a,b,‘same’)即可实现。(至于怎么理解是为什么是截断前面的一部分、后面一部分,我还没想清楚,不妨先记住?所以相比之下,我更喜欢用fliter函数,哈哈哈哈哈哈,我还是觉得发送和接收对应上就好。

有了beta滚降因子这个值后,后续的仿真,也可以通过改变beta该观察不同beta对误码率的影响。

那我们回过头再想一下,为什么一定要费这么大力气来消除码间串扰呢?思考几秒钟?

这便要分析数字系统差错性能降低的两个主要来源,一是由于接收信号能量的降低或者噪声(干扰信号)能量的增加导致比特信噪比 E b / N 0 {E_b}/{N_0} Eb/N0 的降低,从而使得系统性能下降;二是由于信号失真,比如由码间串扰引起的失真。详细见《数字通信——基础与应用》中的内容,如下图:

img

(3)匹配滤波器

在数字信号接收中,滤波器的作用是使得滤波器输出的有用信号尽可能的强,抑制信号带外噪声,使得滤波器输出的噪声成分尽可能的小,以方便后面的信号判决。

匹配滤波器是使得滤波器的输出信噪比在某一个特定时刻达到最大。这句话怎么理解呢?

这就要说到数字通信的特点了。判决器对信号做出判决的时候,只关心该抽样时刻信号的瞬时功率和噪声平均功率的比值。因此我们要选择滤波器来使得判决时刻的输出信噪比尽可能大,其他时刻的信噪比怎么样,判决器是不管的。

r ( t ) = s ( t ) + n ( t ) r(t) = s\left( t \right) + n(t) r(t)=s(t)+n(t)

s ( t ) s\left( t \right) s(t) 是数字信号,频谱函数是 S ( ω ) S\left( \omega \right) S(ω) n ( t ) n(t) n(t) 为功率谱密度是 n 0 / 2 {n_0}/2 n0/2 的高斯白噪声。

这里便有一个问题,高斯白噪声的功率谱密度什么时候为 N 0 2 {\frac{{{N_0}}}{2}} 2N0 ?什么时候为 N 0 {{N_0}} N0 呢?

试着思考几秒钟?我在后面会解释。

接着匹配滤波器内容,随便找一本通信原理的教材,经过一大堆的公式推理就可以得到匹配滤波器的频谱函数:

H ( ω ) = K S ∗ ( ω ) e − j ω t 0 H\left( \omega \right) = K{S^*}\left( \omega \right){e^{ - j\omega {t_0}}} H(ω)=KS(ω)ejωt0

转化到时域,则冲激响应为:

h ( t ) = k s ( t 0 − t ) h\left( t \right) = ks\left( {{t_0} - t} \right) h(t)=ks(t0t)

怎么从物理上直观的去理解匹配滤波器呢,这个问题我也思考了很久

直到我看到了《匹配滤波器的物理解释》:

“一方面,从幅频特性来看,匹配滤波器和输入信号的幅频特性完全一样。这也就是说,在信号越强的频率点,滤波器的放大倍数也越大;在信号越弱的频率点,滤波器的放大倍数也越小。这就是信号处理中的“马太效应”。也就是说,匹配滤波器是让信号尽可能通过,而不管噪声的特性。因为匹配滤波器的一个前提是白噪声,也即是噪声的功率谱是平坦的,在各个频率点都一样。因此,这种情况下,让信号尽可能通过,实际上也隐含着尽量减少噪声的通过。这不正是使得输出的信噪比最大吗?

另外一方面,从相频特性上看,匹配滤波器的相频特性和输入信号正好完全相反。这样,通过匹配滤波器后,信号的相位为0,正好能实现信号时域上的相干叠加。而噪声的相位是随机的,只能实现非相干叠加。这样在时域上保证了输出信噪比的最大

实际上,在信号与系统的幅频特性与相频特性中,幅频特性更多地表征了频率特性,而相频特性更多地表征了时间特性。匹配滤波器无论是从时域还是从频域,都充分保证了信号尽可能大地通过,噪声尽可能小地通过,因此能获得最大信噪比的输出。

匹配滤波器由其命名即可知道其鲜明的特点,那就是这个滤波器是匹配输入信号的。一旦输入信号发生了变化,原来的匹配滤波器就再也不能称为匹配滤波器了。由此,我们很容易联想到相关这个概念,相关的物理意义就是比较两个信号的相似程度。如果两个信号完全一样,不就是匹配了吗?事实上,匹配滤波器的另外一个名字就是相关接收,两者表征的意义是完全一样的。只是匹配滤波器着重在频域的表述,而相关接收则着重在时域的表述。”

这个解释不错,可以用作参考,但其没有考虑到 H ( ω ) = K S ∗ ( ω ) e − j ω t 0 H\left( \omega \right) = K{S^*}\left( \omega \right){e^{ - j\omega {t_0}}} H(ω)=KS(ω)ejωt0 中的 e − j ω t 0 {e^{ - j\omega {t_0}}} ejωt0 的影响,因此我总觉得还缺点什么,当然也有可能是我没理解透,扎心了。

哈哈哈哈哈哈,如果读者有更好理解的直观解释可以留言告诉我,欢迎交流。

除此之外,上面的解释中还提到了“相干叠加”和“非相干叠加”概念,非常有用的概念,这个我以后再讲。

接下来说说匹配滤波器和一般滤波器的区别,再次看到《数字通信——基础与应用》的内容:

img

回答第(2)中的一个问题,结合(2)中的图,若在理想信道情况下,要求 G R ( ω ) = G T ∗ ( ω ) {G_R}\left( \omega \right) = {G_T}^*\left( \omega \right) GR(ω)=GT(ω) 即是匹配滤波。

当发送滤波器 G T ( ω ) {G_T}\left( \omega \right) GT(ω) 和接收滤波器 G R ( ω ) {G_R}\left( \omega \right) GR(ω) 都设计为平方根升余弦滚降滤波器,即都有 ∣ G R ( ω ) ∣ 2 = ∣ G T ( ω ) ∣ 2 {\left| {{G_R}\left( \omega \right)} \right|^2} = {\left| {{G_T}\left( \omega \right)} \right|^2} GR(ω)2=GT(ω)2 =升余弦滚降滤波器。所以接收滤波器 G R ( ω ) {G_R}\left( \omega \right) GR(ω) 是发送端 G T ( ω ) {G_T}\left( \omega \right) GT(ω) 的匹配滤波器。

举个不是很恰当,仅做理解的例子。假设发送端是3+4j,模值平方后是25,接收端是3-4j,模值平方后为25。3-4j是3+4j的共轭。

(4)最佳采样点的信噪比条件是最好的,因此在最佳采样点进行采样和判决。相比于不在最佳采样点采样和判决,最佳采样点的判决可以使得误码率更接近理论误码率性能。

在本章的寻找最佳采样点主要是根据滤波器的延时,来初步估计最佳采样点的位置,由于噪声的影响,因此真实的最佳采样点会和根据滤波器延时估计出的最佳采样点有一定的偏差。在仿真的代码中,读者也可改变最佳采样点的位置来观察采样点对误码率性能的影响来深刻理解“采样”的重要性。

根据滤波器延时来初步估计最佳采样点的位置,其实也是位同步的过程。假设我们知道了sps为16,即16个点表示一个比特,但我们并不知道这16个点的起始位置在哪里?结束位置在哪里。

比如你认为第15到第30个点表示的是发送端的一个比特,怎么判断出来是15的呢?为什么不是16到第31个点对应的是发送端的一个比特呢?

因此,如何找到最佳采样点,以及实际采样点相比最佳采样点采偏了有什么影响?我后面的实验结果截图有所体现。

(5)信噪比与 E b / N 0 {E_b}/{N_0} Eb/N0 有关系吗? E b / N 0 {E_b}/{N_0} Eb/N0 这个量有单位吗?在什么位置开始定义 E b / N 0 {E_b}/{N_0} Eb/N0 的?为什么数字通信,分析误码率曲线时,横坐标是 E b / N 0 {E_b}/{N_0} Eb/N0 呢?

img

img

我们知道, S N = E s R s N 0 W \frac{S}{N} = \frac{{{E_s}{R_s}}}{{{N_0}W}} NS=N0WEsRs 。在仿真过程中,W一般用采样频率 f s {f_s} fs进行代替,由于是高斯白噪声信道,可以认为采样频率以下的噪声都被采进来了。 f s = 1 T s a m p l e {f_s} = \frac{1}{{{T_{sample}}}} fs=Tsample1 R s = 1 T s y m {R_s} = \frac{1}{{{T_{sym}}}} Rs=Tsym1 ,其中 T s y m {{T_{sym}}} Tsym 为符号周期。

E s Es Es E b {{E_b}} Eb 的关系要联合考虑,编码和调制的影响:

img

举个例子来说,(7,4)汉明码+BPSK调制,1个符号是1个信道比特,而1个信道比特有4/7个是信息比特,所以 k = 4 7 log ⁡ 2 2 k = \frac{4}{7}{\log _2}2 k=74log22

若是(7,4)汉明码+QPSK调制,1个符号是2个信道比特,1个信道比特,有4/7个是信息比特,所以 k = 4 7 log ⁡ 2 4 k = \frac{4}{7}{\log _2}4 k=74log24

信道比特是指信息比特经过信道编码后的比特,信道编码产生的校验比特是不带信息量的。

因此 E b N 0 \frac{{{E_b}}}{{{N_0}}} N0Eb E b {{E_b}} Eb 是信息比特的能量,后面章节加入信道编码的仿真更可以理解这一点。

尤其是上面Note框里面的话,要注意相对于实信号来说,高斯白噪声的功率谱密度是 N 0 2 \frac{{{N_0}}}{2} 2N0,复信号来说,高斯白噪声的功率谱密度是 N 0 {{N_0}} N0,在后面完整版代码中snr与 E b N 0 \frac{{{E_b}}}{{{N_0}}} N0Eb 换算中可看到这步的实现。

即对于复信号, S N = E s ⋅ T s a m p l e N 0 ⋅ T s y m \frac{S}{N} = \frac{{{E_s} \cdot {T_{sample}}}}{{{N_0} \cdot {T_{sym}}}} NS=N0TsymEsTsample ,对于实信号, S N = E s ⋅ T s a m p l e N 0 2 ⋅ T s y m \frac{S}{N} = \frac{{{E_s} \cdot {T_{sample}}}}{{\frac{{{N_0}}}{2} \cdot {T_{sym}}}} NS=2N0TsymEsTsample

接下来一个问题: E b N 0 \frac{{{E_b}}}{{{N_0}}} N0Eb 在系统的什么位置定义的?

说实话,以前我从没想过这个问题,问我 E b N 0 \frac{{{E_b}}}{{{N_0}}} N0Eb 在什么位置定义的。还是继续看《数字通信——基础与应用》的内容:

img

img

(6)高斯白噪声信道时,白噪声怎么加到信号上去呢?

这里介绍两种方法,一种采用awgn函数,具体用法help awgn学习一下就知道;第二种方法对信号加上一个等长度、设定方差的高斯分布随机序列。

%%%%%%%%%%%%%%%%%%%%%     加噪声函数使用    %%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%    test_addnoise.m    %%%%%%%%%%%%%%%%%
%%%%%%%%%%%% 日期:2020年8月4日   作者:飞蓬大将军  %%%%%%%%%%%%%%%%%

%%%%%%%%%程序说明
%%%判断两种方式下的加噪声方式是否一致

%*********************  程序主体    ****************%

% N = 1000000;
% x = cos(0:pi/N:6*pi);
% figure (1);
% plot(x);
% y = awgn(x,10,'measured');
% figure (2);
% plot(y);
% 
% sigPower  = sum(abs(x.^2)/length(x));
% noisePower = sum(abs((y-x).^2)/length(y));
% SNR_dB = 10*log10(sigPower/noisePower);

%%%%%%%%结论
%%%%计算可知SNR_dB约等于10dB,当信号长度N越长,SNR_dB越接近10dB,因此可认为两种加噪声方式在统计意义上一致的


%%%%%方式一:用awgn函数
x = cos(0:pi/1000000:6*pi);
figure (1);
plot(x);
snr = 10; %单位是dB
y1 = awgn(x,snr,'measured');
figure (2);
plot(y1);

%%%%%方式二:加随机序列
% x = cos(0:pi/1000000:6*pi);
sigPower =  sum(abs(x.^2)/length(x));
noisePower = sigPower /10^(snr/10);
a = sqrt(noisePower);   
y2 = x + a*randn(1,length(x));
figure (3);
plot(y2);

%%%%%%%%%%%结论
%%%%两种加噪声方式都可以,按照个人习惯选择即可
%%%%当存在I路、Q路信号时,噪声功率在I路和Q路上是各占一半功率

需要注意的是,由于写BPSK调制解调时,没有I路、Q路的概念,因此在后续写QPSK、16QAM等程序,加噪声时,采用方式2需要注意分两路添加噪声

(7)信号的频域图、眼图怎么看?

%波形观察
figure(1);
plot(rcos_msg_source);
title('时域波形');
figure(2);
plot(abs(fft(rcos_msg_source)));
title('频域波形');

eyediagram(rcos_msg_source(49:end),sps);
title('眼图');

注意眼图看的是已经经过基带成型之后的信号。如果要画出功率谱函数,由维纳-辛钦定理可知,功率谱密度和自相关函数成傅里叶变换对,则先对信号做自相关运算,然后fft即可。

img

五、完整可运行代码附上:

%%%%%%%%%%%%%%%%%%%%%  BPSK调制解调器仿真 %%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%  BPSK_modem_sim1_1_13.m  %%%%%%%%%
%%%%% data:2020年6月10日  原创:算法工匠    改动:飞蓬大将军 %%%%%%%%%%
 
%%%%%程序说明
%%完成了BPSK调制解调仿真,比较不同信噪比下的误码率性能
%通信体制具体内容如下:
%调制方式:BPSK   编码方式:无
%滚降因子:0.5
%解调方式:相干解调  译码方式:无
%噪声:线性高斯白噪声

%%%%    仿真环境
%软件版本:MATLAB R2019a

%%%    sim系列说明
%1_7:明确了Es/N0(dB)=10log10(0.5Tsym/Tsamp)+SNR(dB) for real input signals

clear all;
close all;
format long;
tic;


%********************** 程序主体 ************%

%%%%%%%%%%%%%%%%%  参数设定   %%%%%%%%%%%%%%
bit_rate =1000;% 比特率
symbol_rate = 1000;%符号率
sps =16;%每个符号的采样点数
fc =2000; %载波频率
fs =16000; %采样频率

%%%%%%%%%%%%%%%%%   信源   %%%%%%%%%%%%%%%%%%%
%%%%随机信号
msg_source = [ones(1,20) zeros(1,20) randi([0 1],1,99960)];
%给出标志性的帧头,方便调试

%%%%%%%%%%%%%%%%%  发射机  %%%%%%%%%%%%%%%%%%%
%%%%%%%%调制器
%%%%%双极性变换
bipolar_msg_source = 2*msg_source-1; %双极性信号

%%%滚降滤波器
rollof_factor = 0.5; %滚降因子,可调整
rcos_fir = rcosdesign(rollof_factor,6,sps);

%%%插值
bipolar_msg_source_temp = [bipolar_msg_source',zeros(size(bipolar_msg_source,2),sps-1)]; 
length_x = size(bipolar_msg_source_temp,1);
length_y = size(bipolar_msg_source_temp,2);
up16_bipolar_msg_source = reshape(bipolar_msg_source_temp',1,length_x * length_y);

%%%%滚降滤波
rcos_msg_source = filter(rcos_fir,1,up16_bipolar_msg_source);

% %波形观察
% figure(1);
% plot(rcos_msg_source);
% title('时域波形');
% figure(2);
% plot(abs(fft(rcos_msg_source)));
% title('频域波形');
% 
% eyediagram(rcos_msg_source(49:end),sps);
% title('眼图');

%%%%%载波发送
time = [1:length(rcos_msg_source)];
rcos_msg_source_carrier = rcos_msg_source.*cos(2*pi*fc.*time/fs);
%%%%%%后续考虑直接用复数载波信号实现,更加方便

% %波形观察
% figure(3);
% plot(rcos_msg_source_carrier);
% title('时域波形');
% figure(4);
% plot(abs(fft(rcos_msg_source_carrier)));
% title('频域波形');

%%%%%%%%%%%%%%%%%  信道    %%%%%%%%%%%%%%%%%%%
%设置信噪比,单位dB
ebn0 =[-6:8];
snr = ebn0 - 10*log10(0.5*16);

for i =1:length(snr)

%%%线性高斯白噪声信道
rcos_msg_source_carrier_addnoise = awgn(rcos_msg_source_carrier,snr(i),'measured');

% %波形观察
% figure(5);
% plot(rcos_msg_source_carrier_addnoise);
% title('时域波形');
% figure(6);
% plot(abs(fft(rcos_msg_source_carrier_addnoise)));
% title('频域波形');

%%%%%%%%%%%%%%%%%  接收机  %%%%%%%%%%%%%%%%%%%
%%%%%%载波恢复
%%%相干解调
rcos_msg_source_addnoise =rcos_msg_source_carrier_addnoise.*cos(2*pi*fc.*time/fs);

% %波形观察
% figure(7);
% plot(rcos_msg_source_addnoise);
% title('时域波形');
% figure(8);
% plot(abs(fft(rcos_msg_source_addnoise)));
% title('频域波形');

%%%%%%%滤波
%%%%低通滤波
fir_lp =fir1(128,0.2); %截止频率为0.2*(fs/2)
rcos_msg_source_lp = filter(fir_lp,1,rcos_msg_source_addnoise);
%延迟64个采样点输出

% %波形观察
% figure(9);
% plot(rcos_msg_source_lp);
% title('时域波形');
% figure(10);
% plot(abs(fft(rcos_msg_source_lp)));
% title('频域波形');

%%%%%%匹配滤波
%生成匹配滤波器
rollof_factor =0.5;
rcos_fir = rcosdesign(rollof_factor,6,sps);
%滤波
rcos_msg_source_MF = filter(rcos_fir,1,rcos_msg_source_lp);

% %波形观察
% figure(11);
% plot(rcos_msg_source_MF);
% title('时域波形');
% figure(12);
% plot(abs(fft(rcos_msg_source_MF)));
% title('频域波形');

%%%%%最佳采样
%%%选取最佳采样点
decision_site = 160; %(96+128+96)/2 =160 三个滤波器的延迟 96 128 96


%每个符号选取一个点作为判决
rcos_msg_source_MF_option = rcos_msg_source_MF(decision_site:sps:end);
%涉及到三个滤波器,固含有滤波器延迟累加


%%%判决
msg_source_MF_option_sign= sign(rcos_msg_source_MF_option);

% %波形观察
% figure(13);
% plot(msg_source_MF_option,'-*');
% title('判决结果');
% 
% eyediagram(rcos_msg_source,sps);
% title('发射端眼图');
% eyediagram(rcos_msg_source_MF,sps);
% title('接收端眼图');
% 
% scatterplot(rcos_msg_source(48+1:16:end-48));
% title('BPSK星座图');


%%%%%%%%%%%%%%%%%   信宿    %%%%%%%%%%%%%%%%%%%%
%%%误码率性能比对
%[err_number,bit_err_ratio]=biterr(x,y)
[err_number(i),bit_err_ratio(i)]=biterr(msg_source(1:length(rcos_msg_source_MF_option)),(msg_source_MF_option_sign+1)/2);

end %for i
toc;
%%%%%%%%%%%%%%%%%   仿真结果    %%%%%%%%%%%%%%%%%%%%
ber = berawgn(ebn0,'psk',2,'nondiff');
semilogy(ebn0,bit_err_ratio,'-*',ebn0,ber,'-+');
xlabel('比特信噪比');
ylabel('误码率');
title('不同信噪比下误码率仿真曲线');
legend('实验曲线','理论曲线');
grid on;
%bit_err_ratio = [0.244582012381114   0.213429208628777   0.187996919722775   0.163494714524307
%0.131351821663950   0.105409486853817   0.081767359062316   0.05948535368183
%0.039983598523867   0.025562300607055   0.014161274514706   0.007020631856867
%0.003290296126651   0.000920082807453   0.000360032402916 ]
%%%%%%%%%%%%%%%%%   结论    %%%%%%%%%%%%%%%%%%%%

%完成了BPSK调制解调器的仿真
%没有包含编译码内容
%2020-6-10

有了以上的代码后,便可画出未编码时的误码率曲线,并和理论误码率曲线进行对比。

img

改变不同的采样点位置(对应上述变量decision_cite)和滚降因子Beta可观察其对误码率的影响,得到下面两图:

img
不 同 滚 降 因 子 下 的 误 码 率 仿 真 曲 线 不同滚降因子下的误码率仿真曲线 仿线
img
不 同 采 样 点 下 的 误 码 率 仿 真 曲 线 不同采样点下的误码率仿真曲线 仿线

有了信道编码之后的曲线图会是如何呢?在相同的误码率情况下,有信道编码所需的 E b N 0 \frac{{{E_b}}}{{{N_0}}} N0Eb 就一定比未信道编码的 E b N 0 \frac{{{E_b}}}{{{N_0}}} N0Eb 小吗?小多少?这就涉及编码增益的概念了。

img

img

六、致谢

感谢机缘巧合知道微信公众号“通信工程师专辑”,上面有特别多MATLAB代码参考,以及该公众号作者蔡博士对我的答疑。通信工程、通信工程,始终还是工程,需要“理论+实践”的不断结合。

对于我自己来说,其实是“理论指导实践,实践又印证理论”的过程。这样学知识,便扎实了些。本次总结+代码仅作为“总结知识、学习交流、传播知识”之用,不做商用。本人能力有限,不足甚至错误之处,欢迎你批评指正,也欢迎读者朋友就相关技术问题与我交流,一起学习,共同进步。请你也别忘了把这篇文章分享给你身边正在学习通信专业的同学们,也许能够帮到Ta。这是《陈老湿·通信MATLAB》仿真的第1章,期待下次更新见!

评论 2 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:数字20 设计师:CSDN官方博客 返回首页

打赏作者

通信陈老湿

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值