%OFDM主程序
clc;
clear;
close all;
carrier_count=200;%子载波数
symbols_per_carrier=12;%每子载波含符号数
bits_per_symbol=4;%每符号含比特数,16QAM调制 K=log2M
IFFT_bin_length=512;%FFT点数
PrefixRatio=1/4;%保护间隔与OFDM数据的比例 1/6~1/4
GI=PrefixRatio*IFFT_bin_length ;%每一个OFDM符号添加的循环前缀长度为1/4*IFFT_bin_length 即保护间隔长度为128
beta=1/20;%窗函数滚降系数
GIP=beta*(IFFT_bin_length+GI);%循环后缀的长度20 B*Ts %这里要注意是整数,更改一下
SNR=15; %信噪比dB
%================================================== 信号产生%===================================================
baseband_out_length = carrier_count * symbols_per_carrier * bits_per_symbol;%所输入的比特数目 %这里不是按照输入bit速率来,因为这里不进行实时,直接指定每个子载波的符号数
carriers = (1:carrier_count) + (floor(IFFT_bin_length/4) - floor(carrier_count/2));%共轭对称子载波映射 复数数据对应的IFFT点坐标
conjugate_carriers = IFFT_bin_length - carriers + 2;%共轭对称子载波映射 共轭复数对应的IFFT点坐标
baseband_out=round(rand(1,baseband_out_length));%输出待调制的二进制比特流,round()四舍五入
%==============16QAM调制====================================
complex_carrier_matrix=qam16(baseband_out);%列向量 qam16()函数,出来的矩阵大小是(length(baseband_out)/4,1)
complex_carrier_matrix=reshape(complex_carrier_matrix',carrier_count,symbols_per_carrier)';%symbols_per_carrier*carrier_count 矩阵
figure(1);
plot(complex_carrier_matrix,'*r')%16QAM调制后星座图
title('16QAM调制后星座图')
axis([-4, 4, -4, 4]);
grid on
%=================IFFT===========================
IFFT_modulation=zeros(symbols_per_carrier,IFFT_bin_length);%添0组成IFFT_bin_length IFFT 运算
IFFT_modulation(:,carriers ) = complex_carrier_matrix ;%未添加导频信号 ,子载波映射在此处
IFFT_modulation(:,conjugate_carriers ) = conj(complex_carrier_matrix);%共轭复数映射 以上的操作都是为了ifft后变成实数,在基带上传输
%=================================================================
signal_after_IFFT=ifft(IFFT_modulation,IFFT_bin_length,2);%OFDM调制 即IFFT变换 ,ifft出来是实数
time_wave_matrix =signal_after_IFFT;%时域波形矩阵,行为每载波所含符号数,列ITTF点数,N个子载波映射在其内,每一行即为一个OFDM符号
%===========================================================添加循环前缀与后 缀 %=========================================================
XX=zeros(symbols_per_carrier,IFFT_bin_length+GI+GIP);
for k=1:symbols_per_carrier;
for i=1:IFFT_bin_length;
XX(k,i+GI)=signal_after_IFFT(k,i); %GI=128为循环前缀,把(12,512)IFFT实数放入到循环前缀后面的数据部分
end
for i=1:GI;
XX(k,i)=signal_after_IFFT(k,i+IFFT_bin_length-GI);%添加循环前缀 ,把signal_after_IFFT中后面部分GI个数据放到前面作为GI前缀
end
for j=1:GIP;
XX(k,IFFT_bin_length+GI+j)=signal_after_IFFT(k,j);%添加循环后缀, 把signal_after_IFFT中后前面部分的GIP个数据放到后面作为GI后缀
end
end
time_wave_matrix_cp=XX;%添加了循环前缀与后缀的时域信号矩阵,此时一个OFDM符号长度为IFFT_bin_length+GI+GIP=660
%==============OFDM符号加窗==========================================
windowed_time_wave_matrix_cp=zeros(symbols_per_carrier,IFFT_bin_length+GI+GIP); %
for i = 1:symbols_per_carrier
windowed_time_wave_matrix_cp(i,:) = real(time_wave_matrix_cp(i,:)).*rcoswindow(beta,IFFT_bin_length+GI)';%加窗 升余弦窗 rcoswindow()加窗函数
% %% 自个写
% a=rcoswindow(beta,IFFT_bin_length+GI);%查看一下窗函数的波形
% plot(1:660,a');
% axis=[0 800 0 2];
% grid on;
end
%======================== 生 成 发 送 信 号 , 并 串 变 换 ==================================================
windowed_Tx_data=zeros(1,symbols_per_carrier*(IFFT_bin_length+GI)+GIP);
windowed_Tx_data(1:IFFT_bin_length+GI+GIP)=windowed_time_wave_matrix_cp(1,:);
for i = 1:symbols_per_carrier-1
windowed_Tx_data((IFFT_bin_length+GI)*i+1:(IFFT_bin_length+GI)*(i+1)+GIP)=windowed_time_wave_matrix_cp(i+1,:);%并串转换,循环后缀与循环前缀相叠加
end
%=======================================================
Tx_data=reshape(windowed_time_wave_matrix_cp',(symbols_per_carrier)*(IFFT_bin_length+GI+GIP),1)';%加窗后 循环前缀与后缀不叠加 的串行信号
%=================================================================
temp_time1 = (symbols_per_carrier)*(IFFT_bin_length+GI+GIP);%加窗后 循环前缀与后缀不叠加 发送总位数
figure (2)
subplot(2,1,1);
plot(0:temp_time1-1,Tx_data )%循环前缀与后缀不叠加 发送的信号波形
grid on;
ylabel('Amplitude (volts)');
xlabel('Time (samples)');
title('循环前后缀不叠加的OFDM Time Signal')
temp_time2 =symbols_per_carrier*(IFFT_bin_length+GI)+GIP;
subplot(2,1,2);
plot(0:temp_time2-1,windowed_Tx_data)%循环后缀与循环前缀相叠加 发送信号波形
grid on;
ylabel('Amplitude (volts)');
xlabel('Time (samples)');
title('循环前后缀叠加的OFDM Time Signal');
%===============加窗的发送信号频谱=================================
symbols_per_average = ceil(symbols_per_carrier/5);%符号数的1/5,10行 ceil(x)返回不小于x的最小整数值,然后转化为doubl型
avg_temp_time = (IFFT_bin_length+GI+GIP)*symbols_per_average;%点数,10行数据,10个符号 660*3=1980
averages = floor(temp_time1/avg_temp_time);%floor(7920/1980)=4
average_fft(1:avg_temp_time) = 0;%分成5段
for a = 0:(averages-1)
subset_ofdm = Tx_data(((a*avg_temp_time)+1):((a+1)*avg_temp_time));%利用循环前缀后缀未叠加的串行加窗信号计算频谱
subset_ofdm_f = abs(fft(subset_ofdm));%分段求频谱
average_fft = average_fft + (subset_ofdm_f/averages);%总共的数据分为5段,分段进行FFT,平均相加
end
average_fft_log = 20*log10(average_fft);
figure (3)
% subplot(2,1,2)
plot((0:(avg_temp_time-1))/avg_temp_time, average_fft_log) %归一化 0/avg_temp_time : (avg_temp_time-1)/avg_temp_time
hold on;
plot(0:1/IFFT_bin_length:1, -35, 'rd')
grid on ;
axis([0 0.5 -40 max(average_fft_log)]);
ylabel('Magnitude (dB)');
xlabel('Normalized Frequency (0.5 = fs/2)');
title('加窗的发送信号频谱');
%====================添加噪声=================================
Tx_signal_power = var(windowed_Tx_data);%发送信号功率
linear_SNR=10^(SNR/10);%线性信噪比
noise_sigma=Tx_signal_power/linear_SNR;
noise_scale_factor = sqrt(noise_sigma);%标准差sigma
noise=randn(1,((symbols_per_carrier)*(IFFT_bin_length+GI))+GIP)*noise_scale_factor;%产生正态分布噪声序列
% figure(4)
% plot(0:length(noise)-1,20*log10(abs(noise)));
Rx_data=windowed_Tx_data +noise;%接收到的信号加噪声
%=====================接收信号 串/并变换 去除前缀与后缀==========================================
Rx_data_matrix=zeros(symbols_per_carrier,IFFT_bin_length+GI+GIP);
for i=1:symbols_per_carrier;
Rx_data_matrix(i,:)=Rx_data(1,(i-1)*(IFFT_bin_length+GI)+1:i*(IFFT_bin_length+GI)+GIP);%串并变换
end
Rx_data_complex_matrix=Rx_data_matrix(:,GI+1:IFFT_bin_length+GI);%去除循环前缀与循环后缀,得到有用信号矩阵
%==============================================================
% OFDM解码 16QAM解码
%=================FFT变换=================================
Y1=fft(Rx_data_complex_matrix,IFFT_bin_length,2);%OFDM解码 即FFT变换
Rx_carriers=Y1(:,carriers);%除去IFFT/FFT变换添加的0,选出映射的子载波
Rx_phase =angle(Rx_carriers);%接收信号的相位
Rx_mag = abs(Rx_carriers);%接收信号的幅度
figure(4);
polar(Rx_phase, Rx_mag,'bd')%极坐标坐标下画出接收信号的星座图
title('极坐标下的接收信号的星座图')
%======================================================================
[M, N]=pol2cart(Rx_phase, Rx_mag); %M,N分别是极坐标下对应的x,y,也就是一开始数据的实部与虚部大小
Rx_complex_carrier_matrix = complex(M, N);
figure(5);
plot(Rx_complex_carrier_matrix,'*r') %XY坐标接收信号的星座图
title('XY坐标接收信号的星座图');
axis([-4, 4, -4, 4]);
grid on;
%====================16qam解调=======================================
Rx_serial_complex_symbols=reshape(Rx_complex_carrier_matrix',size(Rx_complex_carrier_matrix, 1)*size(Rx_complex_carrier_matrix,2),1)';
Rx_decoded_binary_symbols=demoduqam16(Rx_serial_com
评论0
最新资源