(内容源自详解MATLAB/SIMULINK 通信系统建模与仿真 刘学勇编著第七 章内容,有兴趣的读者请阅读原书)
clear all
M=8;
msg=[1 4 3 0 7 5 2 6];
ts=0.01;
T=1;
%t=0:ts:T;
t=0:ts:T-ts;
%x=0:ts:length(msg);
x=0:ts:length(msg)-ts;
fc=1;
c=sqrt(2)*exp(j*2*pi*fc*t);
msg_qam=qammod(msg,M).';
tx_qam=real(msg_qam*c);
tx_qam=reshape(tx_qam.',1,length(msg)*length(t));
%plot(x,tx_qam(1:length(x)))
plot(x,tx_qam)
title('8QAM信号波形')
xlabel('时间t'),ylabel('载波振幅')
scatterplot(msg_qam)
title('8QAM信号星座图')
xlabel('同相分量'),ylabel('正交分量')
clear all
nsymbol=100000;
M=16;
graycode=[0 1 3 2 4 5 7 6 12 13 15 14 8 9 11 10];
EsN0=5:20;
snr1=10.^(EsN0/10);
msg=randi([0,M-1],1,nsymbol);
msg1=graycode(msg+1);
msgmod=qammod(msg1,M);
spow=norm(msgmod).^2/nsymbol;
for indx=1:length(EsN0)sigma=sqrt(spow/(2*snr1(indx)));rx=msgmod+sigma*(randn(1,length(msgmod))+j*randn(1,length(msgmod)));y=qamdemod(rx,M);decmsg=graycode(y+1);[err,ber(indx)]=biterr(msg,decmsg,log2(M));[err,ser(indx)]=symerr(msg,decmsg);
end
P4=2*(1-1/sqrt(M))*qfunc(sqrt(3*snr1/(M-1)));
ser1=1-(1-P4).^2;%理论误符号率
ber1=1/log2(M)*ser1;%理论误比特率(1)
semilogy(EsN0,ber,'-ko',EsN0,ser,'-k*',EsN0,ser1,EsN0,ber1,'-k.');
title('16QAM载波调制信号在AWGN信道下的影响')
xlabel('Es/N0');ylabel('误比特率和误符号率')
legend('误比特率','误符号率','理论误符号率','理论误比特率')
(1)在计算理论误比特率时采用的是式7-37,7-38,在计算理论误符号率时,因为这里是16qam,
换一种方式理解就是,符号中有四个比特,只要有一个比特错了整个符号都错了,所以误比特率一定是比误符号率小的。
clear all
M=4;
T=1;
deltaf=1/T; %FSK的频率间隔
fs=60;%采样频率
ts=1/fs;%采样时间间隔
t=0:ts:T;%一个符号周期的时间矢量
fc=4;%载波频率
msg=[0 1 3 2 randi([0,M-1],1,10000-M)];%消息序列
msg_mod=fskmod(msg,M,deltaf,fs,fs);%4-fsk调制
t1=0:ts:length(msg)-ts;
y=real(msg_mod.*exp(j*2*pi*fc*t1));
subplot(2,1,1)
plot(t1(1:4*fs),y(1:4*fs))%(1)时域信号波形
axis([0 4 -1.5 1.5])
title('4FSK调制的信号波形')
xlabel('时间');ylabel('振幅')
ly=length(y);
freq=[-fs/2:fs/ly:fs/2-fs/ly];
Syy=10*log10(fftshift(abs(fft(y)/fs)));%调制信号频谱
subplot(2,1,2)
plot(freq,Syy)
(1)这里的图像只画出了前4个符号的图像,我们在设定msg信号的时候就已经确定了前4个符号为0 1 3 2,之后经过fsk调制之后,每个符号采样了60个点,所以4个符号的总长度是240(FSK调制之后用60个点表示一个符号),在使用plot进行函数的绘制时,范围是从1->4*fs=240
clear all
nsymbol=10000; %每种信噪比下的发送符号数
SymbolRate=1000;%符号速率
nsamp=50;%每个符号的取样点数
fs=nsamp*SymbolRate;%取样频率
fd=100;
%chan=rayleighchan(1/fs,fd);
chan=comm.RayleighChannel('SampleRate',fs,'MaximumDopplerShift',fd);%(1)
M=4;
graycode=[0 1 3 2];
EsN0=0:2:20;
snr1=10.^(EsN0/10);
msg=randi([0,M-1],1,nsymbol);
msg1=graycode(msg+1);
x1=qammod(msg1,M);
x1=rectpulse(x1,nsamp);
x2=fskmod(msg1,M,SymbolRate,nsamp,fs);
spow1=norm(x1).^2/nsymbol;
spow2=norm(x2).^2/nsymbol;
for indx=1:length(EsN0)sigma1=sqrt(spow1/(2*snr1(indx)));sigma2=sqrt(spow2/(2*snr1(indx)));fadeSig1=chan(x1');%(3)%fadeSig1=filter(x1);%(2)%fadeSig2=filter(x2);fadeSig2=chan(x2');rx1=fadeSig1'+sigma1*(randn(1,length(x1))+j*randn(1,length(x1)))%(4);rx2=fadeSig2'+sigma2*(randn(1,length(x2))+j*randn(1,length(x2)));y1=intdump(rx1,nsamp);y1=qamdemod(y1,M);decmsg1=graycode(y1+1);[err,ber1(indx)]=biterr(msg,decmsg1,log2(M));[err,ser1(indx)]=symerr(msg,decmsg1);y2=fskdemod(rx2,M,SymbolRate,nsamp,fs);decmsg2=graycode(y2+1);[err,ber2(indx)]=biterr(msg,decmsg2,log2(M));[err,ser2(indx)]=symerr(msg,decmsg2);
end
semilogy(EsN0,ser1,'-k*',EsN0,ber1,'-ko',EsN0,ser2,'-kv',EsN0,ber2,'-k.');
title('4QAM和4FSK调制信号在瑞利衰落信道下的性能')
xlabel('Es/N0');ylabel('误比特率和误符号率')
legend('4QAM误符号率','4QAM误比特率','4FSK误符号率','4FSK误比特率')
FSK的调制方式与QAM相差不多,但是qam经过qammod函数处理之后还需要进行矩形脉冲成形r(rectpulse函数),,与此对应的还有脉冲成形的的逆过程(intdump函数),但是FSK调制不需要脉冲成形,可以在格雷映射完成之后直接调制.
此书中的瑞利信道的产生函数rayleighchan已经在新版本中无法使用了,所以采用新的函数comm.RayleighChannel产生瑞利信号,这个函数的使用方法可以参见
http://t.csdnimg.cn/wOHsA
使用方法简单来说可以是comm.RayleighChannel('属性1',属性1的值,'属性2',属性2的值......)。
但是这里如果直接采用(1)处代码会报错,报错内容为
错误使用 doppler (第 47 行)
类 'comm.RayleighChannel' 中的属性 'DopplerSpectrum' 的默认值无效:
At least 5 parameters are required
这里采取了其它人的解决方案,详见
http://t.csdnimg.cn/CU3Z2
这里我将他的方案重述一遍
首先错误原因是
comm中有2个 doppler,时频工具箱和matlab自带的一些设置冲突
所以我们需要将另一个我们需要的doppler也加入matlab的工作路径中,具体方式如下
在命令行中输入
which doppler
确认目前采用的doppler的位置,
之后
将工具箱中的comm加入路径中
我这里的路径为E:\MATLABR2021a\toolbox\comm\comm
所以在命令行输入
addpath('E:\MATLABR2021a\toolbox\comm\comm');
报错问题解决
继续代码问题,书上的滤波过程采用的函数是filter(2),会报错
错误使用 filter
输入参数的数目不足。
这是因为采用comm.RayleighChannel方法得到的信道有自己的使用方法,使用方法为(3)
注意,此处只能处理列向量,所以需要行转置列,由于在(4)处我们又要使用滤波后的行向量结果,所以再次转置(列转行)
实验结论如下: