一、实验题目
利用Matlab仿真ASK、FSK、PSK和QAM信号的调制与解调过程。
二、实验原理
1、数字带通传输系统原理
设有随机信号
s(t)=∑nang(t−nTs)
s(t)=\sum_n a_n g(t-nT_s)
s(t)=n∑ang(t−nTs)
其中an为二进制随机序列
2ASK
e2ASK=s(t)cosωct e_{2ASK}=s(t)cos\omega_ct e2ASK=s(t)cosωct
即调制过程为随机信号与载波直接相乘,实现流程图如下:
本实验的2ASK的解调过程采用相干解调,具体框图如下:
2FSK
e2FSK=s1(t)cosω1t+s2(t)cosω2t e_{2FSK}=s_1(t)cos\omega_1t+s_2(t)cos\omega_2t e2FSK=s1(t)cosω1t+s2(t)cosω2t
其中
s1(t)=s(t)
s_1(t)=s(t)
s1(t)=s(t)
s2(t)=1−s(t) s_2(t)=1-s(t) s2(t)=1−s(t)
即原码乘一个频率的载波,反码乘另一个频率的载波,最后相加。
解调即分别乘各自载波最后经过低通滤波器,再经过抽样判决恢复出原始信号。框图如下
2PSK
Cannot read properties of undefined (reading 'type')
s(t)=∑nang(t−nTs) s(t)=\sum_n a_n g(t-nT_s) s(t)=n∑ang(t−nTs)
e2PSK=s(t)cosωct e_{2PSK}=s(t)cos\omega_ct e2PSK=s(t)cosωct
解调与2ASK相干解调相似,如下图所示:
QAM
调制过程:
(1)首先,一串二进制序列进入串/并变换中,进行4比特划分后再进行2比特划分成一组,按照奇数送同相路,偶数送入正交路。
(2)进入2/L电平变换,就是说二进制数变成4个十进制数,而4个十进制数是由自己的星座图设定的,即00,01,11,10分别对应于-3,-1,1,3。
(3)送入低通后滤除较小的抖动波。
(4)进入相乘器,载波cosωct与同相路波SI(t)相乘变为SI(t) cosωct, 载波cosωct经过相位移动90°与正交路波SQ(t)相乘变为-SQ(t) sinωct。
(5)两路波形经过相乘器后,进行相加,变为
eQAM=SI(t)cosωct−SQ(t)sinωct。
e_{QAM}=S_I(t)cosω_ct- S_Q(t)sinω_ct。
eQAM=SI(t)cosωct−SQ(t)sinωct。
实现框图为
解调过程
(1)经过调制后的波形再分别与相乘器相乘,通过载波cosωct和载波cosωct经过相位移动90°后各自提取出同相分量和正交分量。
(2)进入低通形成包络波形。
(3)再进入采样判决器,选取采样点形成原始的二进制矩形波形。
4)最后进入并/串变换,按照原先的奇偶原则形成完成的原始二进制信号。
2、GUI程序实现设计思路
前端:使用MATLAB自带的APP设计工具设计
GUI核心回调函数 refreshplot
根据下拉框返回的结果利用生成的数据更新图像
后端数据:用各模块生成各种调制解调的数据,输入前端。
文件结构
digitalBandPassTransSystem.m------communicationData.mat
|
|-----test.mlx--------ask2.m
|-------fsk2.m
|-------psk2.m
|-------gen_random_signal.m
|-------T2F.m
|-------F2T.m
三、实验成果展示
1、各模块展示
2ASK
2FSK
2PSK
16QAM
2、GUI展示
2FSK已调信号
2ASK已调信号
2PSK解调信号
四、源代码
1、GUI
classdef digitalBandPassTransSystem < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
PatientsDisplayUIFigure matlab.ui.Figure
GridLayout matlab.ui.container.GridLayout
LeftPanel matlab.ui.container.Panel
Panel2_4 matlab.ui.container.Panel
DropDownLabel matlab.ui.control.Label
DropDown matlab.ui.control.DropDown
Label matlab.ui.control.Label
Panel2_5 matlab.ui.container.Panel
DropDown_2Label matlab.ui.control.Label
DropDown_2 matlab.ui.control.DropDown
RightPanel matlab.ui.container.Panel
TabGroup matlab.ui.container.TabGroup
PlotTab matlab.ui.container.Tab
UIAxes matlab.ui.control.UIAxes
end
% Properties that correspond to apps with auto-reflow
properties (Access = private)
onePanelWidth = 576;
end
% The app displays the data by using the scatter plot, histogram, and table.
% It makes use of tabs to separate the ploting options output from the table display of the data.
% There are several graphical elements used such as checkboxes, slider, switch, dropdown, and radiobutton group.
% The data used in the app is shipped with the product.
properties (Access = private)
% Declare properties of the PatientsDisplay class.
Data
SelectedModMethods
SelectedPlots
end
methods (Access = private)
function annotateScatterPlot(app)
% Update X and Y Labels
app.UIAxes.XLabel.String = 'Time';
app.UIAxes.YLabel.String = 'Amplitude';
end
end
% Callbacks that handle component events
methods (Access = public)
% Code that executes after component creation
function startupFcn(app)
% Load the data.
load('communicationData.mat',"t","signal_delay","signal_psk2","signal_fsk2","signal_ask2","msgmod2","signal_ask_reconstruction","signal_psk_reconstruction","signal_fsk_reconstruction","y2");
% Store the data in a table and display it in one of the App's tabs.
app.Data = table(t, signal_delay, signal_ask2, signal_fsk2, signal_psk2, msgmod2, signal_ask_reconstruction, signal_fsk_reconstruction, signal_psk_reconstruction, y2);
% Update the axes with the corresponding data.
refreshplot(app)
end
% Changes arrangement of the app based on UIFigure width
function updateAppLayout(app, event)
currentFigureWidth = app.PatientsDisplayUIFigure.Position(3);
if(currentFigureWidth <= app.onePanelWidth)
% Change to a 2x1 grid
app.GridLayout.RowHeight = {472, 472};
app.GridLayout.ColumnWidth = {'1x'};
app.RightPanel.Layout.Row = 2;
app.RightPanel.Layout.Column = 1;
else
% Change to a 1x2 grid
app.GridLayout.RowHeight = {'1x'};
app.GridLayout.ColumnWidth = {282, '1x'};
app.RightPanel.Layout.Row = 1;
app.RightPanel.Layout.Column = 2;
end
end
% Callback function
function refreshplot(app, event)
ModMethods = app.SelectedModMethods;
Plots = app.SelectedPlots;
% Start with a fresh plot
cla(app.UIAxes)
hold(app.UIAxes,'on')
% Select relevant segment of data
xdata = app.Data.t;
% Filter the data according to the controls
% filterData(app);
% Create either a scatter plot or histogram, based on selection
switch app.DropDown.Value
case '2ASK'
switch app.DropDown_2.Value
case '调制信号'
plot(app.UIAxes,xdata,app.Data.signal_delay);
annotateScatterPlot(app)
case '已调信号'
plot(app.UIAxes,xdata,app.Data.signal_ask2);
annotateScatterPlot(app)
case '解调信号'
plot(app.UIAxes,xdata,app.Data.signal_ask_reconstruction);
annotateScatterPlot(app)
end
case '2FSK'
switch app.DropDown_2.Value
case '调制信号'
plot(app.UIAxes,xdata,app.Data.signal_delay);
annotateScatterPlot(app)
case '已调信号'
plot(app.UIAxes,xdata,app.Data.signal_fsk2);
annotateScatterPlot(app)
case '解调信号'
plot(app.UIAxes,xdata,app.Data.signal_fsk_reconstruction);
annotateScatterPlot(app)
end
case '2PSK'
switch app.DropDown_2.Value
case '调制信号'
plot(app.UIAxes,xdata,app.Data.signal_delay);
annotateScatterPlot(app)
case '已调信号'
plot(app.UIAxes,xdata,app.Data.signal_psk2);
annotateScatterPlot(app)
case '解调信号'
plot(app.UIAxes,xdata,app.Data.signal_psk_reconstruction);
annotateScatterPlot(app)
end
case '2QAM'
switch app.DropDown_2.Value
case '调制信号'
plot(app.UIAxes,xdata,app.Data.signal_delay);
annotateScatterPlot(app)
case '已调信号'
plot(app.UIAxes,xdata,app.Data.msgmod2);
annotateScatterPlot(app)
case '解调信号'
plot(app.UIAxes,xdata,app.Data.y2);
annotateScatterPlot(app)
end
end
drawnow;
end
end
% Component initialization
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Create PatientsDisplayUIFigure and hide until all components are created
app.PatientsDisplayUIFigure = uifigure('Visible', 'off');
app.PatientsDisplayUIFigure.AutoResizeChildren = 'off';
app.PatientsDisplayUIFigure.Position = [100 100 703 400];
app.PatientsDisplayUIFigure.Name = 'Patients Display';
app.PatientsDisplayUIFigure.SizeChangedFcn = createCallbackFcn(app, @updateAppLayout, true);
% Create GridLayout
app.GridLayout = uigridlayout(app.PatientsDisplayUIFigure);
app.GridLayout.ColumnWidth = {282, '1x'};
app.GridLayout.RowHeight = {'1x'};
app.GridLayout.ColumnSpacing = 0;
app.GridLayout.RowSpacing = 0;
app.GridLayout.Padding = [0 0 0 0];
app.GridLayout.Scrollable = 'on';
% Create LeftPanel
app.LeftPanel = uipanel(app.GridLayout);
app.LeftPanel.Layout.Row = 1;
app.LeftPanel.Layout.Column = 1;
app.LeftPanel.Scrollable = 'on';
% Create Panel2_4
app.Panel2_4 = uipanel(app.LeftPanel);
app.Panel2_4.AutoResizeChildren = 'off';
app.Panel2_4.Title = '调制方式';
app.Panel2_4.Position = [7 216 269 97];
% Create DropDownLabel
app.DropDownLabel = uilabel(app.Panel2_4);
app.DropDownLabel.HorizontalAlignment = 'right';
app.DropDownLabel.Position = [51 25 41 22];
app.DropDownLabel.Text = '请选择';
% Create DropDown
app.DropDown = uidropdown(app.Panel2_4);
app.DropDown.Items = {'2ASK', '2FSK', '2PSK', '2QAM'};
app.DropDown.ValueChangedFcn = createCallbackFcn(app, @refreshplot, true);
app.DropDown.Position = [107 25 153 22];
app.DropDown.Value = '2ASK';
% Create Label
app.Label = uilabel(app.LeftPanel);
app.Label.HorizontalAlignment = 'center';
app.Label.FontSize = 15;
app.Label.FontWeight = 'bold';
app.Label.Position = [9 356 267 22];
app.Label.Text = '二进制数字带通传输系统展示';
% Create Panel2_5
app.Panel2_5 = uipanel(app.LeftPanel);
app.Panel2_5.AutoResizeChildren = 'off';
app.Panel2_5.Title = '展示结果';
app.Panel2_5.Position = [7 102 269 97];
% Create DropDown_2Label
app.DropDown_2Label = uilabel(app.Panel2_5);
app.DropDown_2Label.HorizontalAlignment = 'right';
app.DropDown.ValueChangedFcn = createCallbackFcn(app, @refreshplot, true);
app.DropDown_2Label.Position = [51 25 41 22];
app.DropDown_2Label.Text = '请选择';
% Create DropDown_2
app.DropDown_2 = uidropdown(app.Panel2_5);
app.DropDown_2.Items = {'调制信号', '已调信号', '解调信号'};
app.DropDown_2.Position = [107 25 153 22];
app.DropDown_2.Value = '解调信号';
% Create RightPanel
app.RightPanel = uipanel(app.GridLayout);
app.RightPanel.Layout.Row = 1;
app.RightPanel.Layout.Column = 2;
app.RightPanel.Scrollable = 'on';
% Create TabGroup
app.TabGroup = uitabgroup(app.RightPanel);
app.TabGroup.Position = [7 6 408 387];
% Create PlotTab
app.PlotTab = uitab(app.TabGroup);
app.PlotTab.Title = 'Plot';
% Create UIAxes
app.UIAxes = uiaxes(app.PlotTab);
xlabel(app.UIAxes, 'time')
ylabel(app.UIAxes, 'Amplitude')
app.UIAxes.GridAlpha = 0.15;
app.UIAxes.MinorGridAlpha = 0.25;
app.UIAxes.Box = 'on';
app.UIAxes.Position = [19 89 376 234];
% Show the figure after all components are created
app.PatientsDisplayUIFigure.Visible = 'on';
end
end
% App creation and deletion
methods (Access = public)
% Construct app
function app = digitalBandPassTransSystem
% Create UIFigure and components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.PatientsDisplayUIFigure)
% Execute the startup function
runStartupFcn(app, @startupFcn)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.PatientsDisplayUIFigure)
end
end
end
2、test.mlx
% test
clc
clear
gen_num = 10;
signal = gen_random_signal(gen_num);
meta_num = 16384;
signal_delay = delaySignal(signal, meta_num);
plot(1/(meta_num):1/(meta_num):gen_num, signal_delay)
%%%%%%%%%%%%%%%%%%%%%%% 2ASK调制 %%%%%%%%%%%%%%%%%%%%%%%%
fc = 1024;
fs = gen_num * meta_num;
A = 1;
snr = 30;
t = 1/fs:gen_num/fs:gen_num;
signal_ask2 = ask2(signal_delay, fc, fs, A, snr);
plot(t, signal_ask2);
carry_wave = cos(2*pi*fc*t);
plot(t, carry_wave);
title("载波信号");
signal_ask2_temp = signal_ask2 .* carry_wave;
plot(t, signal_ask2_temp)
title("与载波相乘后的信号")
[f, sf] = T2F(t, signal_ask2_temp);
[t, st] = lpf(f, sf, 10);
plot(t, st>0.25);
title("2ASK 相干解调")
signal_ask_reconstruction = nonCoherentDemodulation_2ask(signal_ask2, fc, fs);
plot(t, signal_ask_reconstruction);
title("2ASK 非相干解调")
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%% 2FSK调制 %%%%%%%%%%%%%%%%%%%%%%%%
fc = [20, 100];
A = 1;
snr = 30;
signal_fsk2 = fsk2(signal, fc, fs, meta_num, A, snr);
plot(t, signal_fsk2);
carry_wave_1 = cos(2 * pi * fc(1) * t);
carry_wave_2 = cos(2 * pi * fc(2) * t);
signal_fsk2_temp = signal_fsk2 .* carry_wave_1;
plot(t, signal_fsk2_temp);
[f_fsk, sf_fsk] = T2F(t, signal_fsk2_temp);
[t_fsk, st_fsk] = lpf(f_fsk, sf_fsk, 10);
signal_fsk_reconstruction = st_fsk > mean(st_fsk);
plot(t_fsk, signal_fsk_reconstruction);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%% 2PSK调制 %%%%%%%%%%%%%%%%%%%%%%%%
fc = 16;
A = 1;
snr = 30;
signal_psk2 = psk2(signal, fc, fs, meta_num, A, snr);
plot(t, signal_psk2);
carry_wave_psk = cos(2 * pi * fc * t);
signal_psk2_temp = carry_wave_psk .* signal_psk2;
plot(t, signal_psk2_temp);
[f_psk, sf_psk] = T2F(t, signal_psk2_temp);
[t_psk, st_psk] = lpf(f_psk, sf_psk, 5);
signal_psk_reconstruction = st_psk>mean(st_psk);
plot(t_psk, signal_psk_reconstruction);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%% QAM调制 %%%%%%%%%%%%%%%%%%%%%%%%
M = 2;
msg=signal_delay;
graycode=[0 1 3 2 4 5 7 6 12 13 15 14 8 9 11 10]; % 格雷码表
EsN0=5:20;
snr1=10.^(EsN0/10); % 噪声容限
msg1=graycode(msg+1);
msgmod2=qammod(msg1,M);
scatterplot(msgmod2);
spow=norm(msgmod2).^ 2/length(msg);
for i=1:length(EsN0)
sigma=sqrt(spow/(2*snr1(i)));
rx=msgmod2+sigma*(randn(1,length(msgmod2))+1i*randn(1,length(msgmod2)));
y2=qamdemod(rx,M);
decmsg=graycode(y2+1);
[err1,ber(i)]= biterr(msg,decmsg,log2(M));
[err2,ser(i)]=symerr(msg,decmsg);
end
subplot(311)
plot(t, msg)
subplot(312)
plot(t, abs(msgmod2))
subplot(313)
plot(t, y2)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%% QAM16调制 %%%%%%%%%%%%%%%%%%%%%%%%
% 使用内置函数qammod qamdemod进行调制解调
M = 16;
msg_length = 100;
msg=randi([0,M-1],1,msg_length);
graycode=[0 1 3 2 4 5 7 6 12 13 15 14 8 9 11 10]; % 格雷码表
EsN0=5:20;
snr1=10.^(EsN0/10); % 噪声容限
msg1=graycode(msg+1);
msgmod=qammod(msg1,M);
scatterplot(msgmod);
spow=norm(msgmod).^ 2/length(msg);
for i=1:length(EsN0)
sigma=sqrt(spow/(2*snr1(i)));
rx=msgmod+sigma*(randn(1,length(msgmod))+1i*randn(1,length(msgmod)));
y=qamdemod(rx,M);
decmsg=graycode(y+1);
[err1,ber(i)]= biterr(msg,decmsg,log2(M));
[err2,ser(i)]=symerr(msg,decmsg);
end
subplot(311)
plot(msg)
subplot(312)
plot(abs(msgmod))
subplot(313)
plot(y)
p4=2*(1-1/sqrt(M))*qfunc(sqrt(3*snr1/(M-1)));
ser1=1-(1-p4).^2;
ber1=1/log2(M)*ser1;
figure()
semilogy(EsN0,ber,'o',EsN0,ser,'*' ,EsN0,ser1, EsN0,ber1,'-');
title('64QAM-AWGN')
xlabel('Es/N0');ylabel('SER AND BER');
legend('ber simulation' ,'ser simulation','ser theory' ,'ber theory');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
save("communicationData.mat","t","signal_delay","signal_psk2","signal_fsk2","signal_ask2","msgmod2","signal_ask_reconstruction","signal_psk_reconstruction","signal_fsk_reconstruction","y2");
3、2ASK
%% 2ASK函数
% 功能:进行2ASK 含有加性高斯白噪声
% 输入:调制信号signal_delay; 载波频率fc; 采样频率fs; 调幅A; 信噪比snr
% 输出:已调信号signal_ask2
% 日期:2021/6/4
function signal_ask2 = ask2(signal_delay, fc, fs, A, snr)
t = linspace(0, 10, fs);
carry_wave = A * cos(2 * pi * fc * t);
signal_ask2 = carry_wave .* signal_delay;
signal_ask2 = awgn(signal_ask2, snr);
end
4、2FSK
%% 2FSK函数
% 功能:进行2FSK 含有加性高斯白噪声
% 输入:调制信号signal; 载波频率fc(1*2); 每个码元的长度meta_num; 调幅A; 信噪比snr
% 输出:已调信号signal_fsk2
% 日期:2021/6/4
function signal_fsk2 = fsk2(signal, fc, fs, meta_num, A, snr)
t = linspace(0, 1, fs/10);
carry_wave_1 = A * cos(2 * pi * fc(1) * t);
carry_wave_2 = A * cos(2 * pi * fc(2) * t);
signal_delay = [];
carry_wave = [];
for i = 1:length(signal)
if signal(i) == 1
signal_delay_temp = ones(1, meta_num);
carry_wave_temp = carry_wave_1;
else
signal_delay_temp = ones(1, meta_num);
carry_wave_temp = carry_wave_2;
end
signal_delay = [signal_delay, signal_delay_temp];
carry_wave = [carry_wave, carry_wave_temp];
end
signal_fsk2 = carry_wave .* signal_delay;
signal_fsk2 = awgn(signal_fsk2, snr);
end
5、PSK
%% 2PSK函数
% 功能:进行2PSK 含有加性高斯白噪声
% 输入:调制信号signal; 载波频率fc; 每个码元的长度meta_num; 调幅A; 信噪比snr
% 输出:已调信号signal_psk2
% 日期:2021/6/4
function signal_psk2 = psk2(signal, fc, fs, meta_num, A, snr)
t = linspace(0, 1, fs/10);
carry_wave_1 = A * cos(2 * pi * fc * t);
carry_wave_2 = -A * cos(2 * pi * fc * t);
signal_delay = [];
carry_wave = [];
for i = 1:length(signal)
if signal(i) == 1
signal_delay_temp = ones(1, meta_num);
carry_wave_temp = carry_wave_1;
else
signal_delay_temp = ones(1, meta_num);
carry_wave_temp = carry_wave_2;
end
signal_delay = [signal_delay, signal_delay_temp];
carry_wave = [carry_wave, carry_wave_temp];
end
signal_psk2 = carry_wave .* signal_delay;
signal_psk2 = awgn(signal_psk2, snr);
end
五、参考资料
1、QAM原理解释:https://blog.youkuaiyun.com/Time_book/article/details/107125791
2、GUI参考 https://ww2.mathworks.cn/products/matlab/app-designer.html