仿真代码如下
%% =================OFDM仿真参数说明:================
%
% 子载波数 carrier_count ---200
% 总符号数 symbol_count ---100
% IFFT长度 ifft_length ---512
% 循环前缀 CP_length ---512/4=128
% 循环后缀 CS_length ---20
% 升余弦窗系数 alpha ---7/32
% 调制方式 QAM16、QPSK 可选
% 多径幅度 mult_path_am ---[1 0.2 0.1]
% 多径时延 mutt_path_time ---[0 20 50]
% ====================仿真过程=======================
% 产生0-1随机序列 => 串并转换 => 映射 => 取共轭、过采样
% => IFFT => 加循环前缀和后缀 => 加窗 => 并串转换 =>
% 多径信道 => 加AWGN => 串并转换 => 去前缀 => FFT =>
% 下采样 => 解映射 => 求误码率
%% ==================================================
clear all;
close all;
carrier_count = 200; % 子载波数
symbol_count = 100;
ifft_length = 512;
CP_length = 128;
CS_length = 20;
rate = [];
ber_rand = [];
SNR =0:1:20;
snr_len = length(SNR);
bit_per_symbol = 4; % 调制方式决定
alpha = 1.5/32;
%% ================产生随机序列=======================
bit_length = carrier_count*symbol_count*bit_per_symbol;
bit_sequence = round(rand(1,bit_length))'; % 列向量
%% ================子载波调制方式1========================
% 1-28置零 29-228有效 229-285置零 286-485共轭 486-512置零
carrier_position = 29:228;
conj_position = 485:-1:286;
bit_moded = qammod(bit_sequence,16,'InputType','bit');
for ii = 1:snr_len
%% =================串并转换==========================
ifft_position = zeros(ifft_length,symbol_count);
bit_moded = reshape(bit_moded,carrier_count,symbol_count);
%% ===================IFFT===========================
ifft_position(carrier_position,:)=bit_moded(:,:);
ifft_position(conj_position,:)=conj(bit_moded(:,:));
signal_time = ifft(ifft_position,ifft_length);
%% ==================加循环前缀和后缀==================
signal_time_C = [signal_time(end-CP_length+1:end,:);signal_time];
signal_time_C = [signal_time_C; signal_time_C(1:CS_length,:)];
%% =======================加窗========================
signal_window = zeros(size(signal_time_C));
% 通过矩阵点乘
signal_window = signal_time_C.*repmat(rcoswindow(alpha,size(signal_time_C,1)),1,symbol_count);
%% ===================发送信号,多径信道====================
signal_Tx = reshape(signal_window,1,[]); % 变成时域一个完整信号,待传输
% ========================加AWGN==========================
signal_power_sig = var(signal_Tx); % 单径发送加窗信号功率
SNR_linear(ii) = 10^(SNR(ii)/10);
noise_power_sig(ii) = signal_power_sig/SNR_linear(ii);
noise_sig = randn(size(signal_Tx))*sqrt(noise_power_sig(ii));
Rx_data_sig = signal_Tx+noise_sig;
% =======================串并转换==========================
Rx_data_sig = reshape(Rx_data_sig,ifft_length+CS_length+CP_length,[]);
% ====================去循环前缀和后缀======================
Rx_data_sig(1:CP_length,:) = [];
Rx_data_sig(end-CS_length+1:end,:) = [];
% =========================FFT=============================
fft_sig = fft(Rx_data_sig);
% =========================降采样===========================
data_sig = fft_sig(carrier_position,:);
% =========================逆映射===========================
bit_demod_sig = reshape(qamdemod(data_sig,16,'OutputType','bit'),[],1);
% =========================误码率===========================
error_bit_sig(ii) = sum(bit_demod_sig~=bit_sequence);
error_rate_sig(ii) = error_bit_sig(ii)/bit_length;
rate = [rate; error_rate_sig(ii)]
ber_rand = [ber_rand; error_rate_sig(ii)];
end
%% ==========画图=================
figure()
semilogy(SNR,ber_rand,'-r*','Linewidth',2);
xlabel('SNR(dB)');
ylabel('Ber');
grid on
title('16QAM-OFDM-rand');
save('OFDM-16QAM-rand','SNR','ber_rand');
% ==========================================================
% ==========================================================
function window=rcoswindow(alpha,bit_length)
warning off;
window = zeros(1,bit_length/2);
t = 1:bit_length/2;
T = bit_length/(2*(1+alpha));
window(t) = 0.5*(1 - sin(pi/(2*alpha*T)*(t-T)));
window(1:(1-alpha)*T) = 1;
window=[fliplr(window) window]';
end
参考:https://blog.csdn.net/qq_43157190/article/details/103383431