16QAM调制解调
用基带等效的方式仿真16-QAM在AWGN信道下的误码率和误比特率性能,并与理论值相比较。
16QAM调制代码:
% 16QAM调制
send = zeros(1,L_symbol); % 预设发送信号
send_set = [-3+3j,-1+3j,1+3j,3+3j,...
-3+1j,-1+1j,1+1j,3+1j,...
-3-1j,-1-1j,1-1j,3-1j,...
-3-3j,-1-3j,1-3j,3-3j]; % 发射端星座点
Es_avg = sum(abs(send_set).^2) / length(send_set);
N0 = Es_avg ./ EsN0;
for q = 1:L_symbol
if (data(4*q-3:4*q) == [1,0,1,1])
send(q) = send_set(1); % 1001 => -3+3j
elseif (data(4*q-3:4*q) == [1,0,0,1])
send(q) = send_set(2); % 1001 => -1+3j
elseif (data(4*q-3:4*q) == [1,1,1,0])
send(q) = send_set(3); % 1110 => +1+3j
elseif (data(4*q-3:4*q) == [1,1,1,1])
send(q) = send_set(4); % 1111 => +3+3j
elseif (data(4*q-3:4*q) == [1,0,1,0])
send(q) = send_set(5); % 1010 => -3+1j
elseif (data(4*q-3:4*q) == [1,0,0,0])
send(q) = send_set(6); % 1000 => -1+1j
elseif (data(4*q-3:4*q) == [1,1,0,0])
send(q) = send_set(7); % 1100 => +1+1j
elseif (data(4*q-3:4*q) == [1,1,0,1])
send(q) = send_set(8); % 1101 => +3+1j
elseif (data(4*q-3:4*q) == [0,0,0,1])
send(q) = send_set(9); % 0001 => -3-1j
elseif (data(4*q-3:4*q) == [0,0,0,0])
send(q) = send_set(10); % 0000 => -1-1j
elseif (data(4*q-3:4*q) == [0,1,0,0])
send(q) = send_set(11); % 0100 => +1-1j
elseif (data(4*q-3:4*q) == [0,1,1,0])
send(q) = send_set(12); % 0110 => +3-1j
elseif (data(4*q-3:4*q) == [0,0,1,1])
send(q) = send_set(13); % 0011 => -3-3j
elseif (data(4*q-3:4*q) == [0,0,1,0])
send(q) = send_set(14); % 0010 => -1-3j
elseif (data(4*q-3:4*q) == [0,1,0,1])
send(q) = send_set(15); % 0101 => +1-3j
else
send(q) = send_set(16); % 0111 => +3-3j
end
end
16QAM解调代码:
%16AQM解调
for q = 1:length(EbN0_dB)
noise = sqrt(N0(q)/2)*randn(1,L_symbol) + 1j*sqrt(N0(q)/2)*randn(1,L_symbol); % AWGN
receive = (send + noise); % 接收信号
detect = zeros(1,L_symbol); % 预置检测信号
distance = zeros(1,M); % 解调:距离检测
for t = 1:L_symbol
for w = 1:M
distance(w) = norm(receive(t) - send_set(w))^2; % 接收信号到所有星座点的距离
end
pos = find(distance == min(distance)); % 最小距离星座点的位置
detect(t) = send_set(pos); % 解调后的符号
if (detect(t) ~= send(t))
error(q) = error(q) + 1; % 统计错误符号数
end
end
ser(q) = error(q)/L_symbol; % 16QAM仿真误符号率
tser_16QAM(q) = 3*qfunc(sqrt(4/5*EbN0(q)))*(1-3/4*qfunc(sqrt(4/5*EbN0(q)))); % 16QAM理论误符号率
end
全部代码:
clc
clear
close all
% Title: 16QAM调制与解调 %
M = 16; % 调制阶数
L_data = 1000000; % 数据长度
L_symbol = L_data/log2(M); % 符号长度
data = round(rand(1,L_data)); % 原始数据
EbN0_dB = 0:14; % Eb/N0 dB形式
EbN0 = 10.^(EbN0_dB/10); % 每比特能量/噪声
EsN0 = log2(M) * EbN0; % 每符号能量/噪声
error = zeros(1,length(EbN0_dB)); % 预置错误符号个数
ser = zeros(1,length(EbN0_dB)); % 预置仿真误符号率
tser_16QAM = zeros(1,length(EbN0_dB)); % 预置16QAM理论误符号率
% 16QAM调制
send = zeros(1,L_symbol); % 预设发送信号
send_set = [-3+3j,-1+3j,1+3j,3+3j,...
-3+1j,-1+1j,1+1j,3+1j,...
-3-1j,-1-1j,1-1j,3-1j,...
-3-3j,-1-3j,1-3j,3-3j]; % 发射端星座点
Es_avg = sum(abs(send_set).^2) / length(send_set);
N0 = Es_avg ./ EsN0;
for q = 1:L_symbol
if (data(4*q-3:4*q) == [1,0,1,1])
send(q) = send_set(1); % 1001 => -3+3j
elseif (data(4*q-3:4*q) == [1,0,0,1])
send(q) = send_set(2); % 1001 => -1+3j
elseif (data(4*q-3:4*q) == [1,1,1,0])
send(q) = send_set(3); % 1110 => +1+3j
elseif (data(4*q-3:4*q) == [1,1,1,1])
send(q) = send_set(4); % 1111 => +3+3j
elseif (data(4*q-3:4*q) == [1,0,1,0])
send(q) = send_set(5); % 1010 => -3+1j
elseif (data(4*q-3:4*q) == [1,0,0,0])
send(q) = send_set(6); % 1000 => -1+1j
elseif (data(4*q-3:4*q) == [1,1,0,0])
send(q) = send_set(7); % 1100 => +1+1j
elseif (data(4*q-3:4*q) == [1,1,0,1])
send(q) = send_set(8); % 1101 => +3+1j
elseif (data(4*q-3:4*q) == [0,0,0,1])
send(q) = send_set(9); % 0001 => -3-1j
elseif (data(4*q-3:4*q) == [0,0,0,0])
send(q) = send_set(10); % 0000 => -1-1j
elseif (data(4*q-3:4*q) == [0,1,0,0])
send(q) = send_set(11); % 0100 => +1-1j
elseif (data(4*q-3:4*q) == [0,1,1,0])
send(q) = send_set(12); % 0110 => +3-1j
elseif (data(4*q-3:4*q) == [0,0,1,1])
send(q) = send_set(13); % 0011 => -3-3j
elseif (data(4*q-3:4*q) == [0,0,1,0])
send(q) = send_set(14); % 0010 => -1-3j
elseif (data(4*q-3:4*q) == [0,1,0,1])
send(q) = send_set(15); % 0101 => +1-3j
else
send(q) = send_set(16); % 0111 => +3-3j
end
end
%16AQM解调
for q = 1:length(EbN0_dB)
noise = sqrt(N0(q)/2)*randn(1,L_symbol) + 1j*sqrt(N0(q)/2)*randn(1,L_symbol); % AWGN
receive = (send + noise); % 接收信号
detect = zeros(1,L_symbol); % 预置检测信号
distance = zeros(1,M); % 解调:距离检测
for t = 1:L_symbol
for w = 1:M
distance(w) = norm(receive(t) - send_set(w))^2; % 接收信号到所有星座点的距离
end
pos = find(distance == min(distance)); % 最小距离星座点的位置
detect(t) = send_set(pos); % 解调后的符号
if (detect(t) ~= send(t))
error(q) = error(q) + 1; % 统计错误符号数
end
end
ser(q) = error(q)/L_symbol; % 16QAM仿真误符号率
tser_16QAM(q) = 3*qfunc(sqrt(4/5*EbN0(q)))*(1-3/4*qfunc(sqrt(4/5*EbN0(q)))); % 16QAM理论误符号率
end
figure
semilogy(EbN0_dB,ser,'o',EbN0_dB,tser_16QAM,'b'); % 画图
grid on; % 坐标轴开启
axis([0 14 10^-5 10^-1]) % 限制作图范围
xlabel('Eb/N0 (dB)'); % 横坐标
ylabel('SER'); % 纵坐标
legend('16QAM仿真误符号率','16QAM理论误符号率'); % 图例