本帖最后由 Haiwen 于 2023-6-22 21:52 编辑
端到端的OAM-OFDM在本篇文章中,我们将通过UCA天线发送不同拓扑荷的OAM-OFDM信号。为切实感受一下一个端到端的OAM-OFDM通信系统,本文仿真中详细包含了OAM-OFDM的各个环节,包括 基带数据生成、信道编码、OFDM调制、上变频(加载波)、多拓扑荷OAM信号、下变频(去载波)、解OFDM、信道译码等部分。 首先初始化OFDM的各项参数,本文使用256QAM调制。 - f_sc = 250 * 10^3; %子载波间隔
- f_c = 1.6e9;
- N_sample= 4; % 对载波的采样
- N_sc=52; %系统子载波
- N_fft=64; % FFT 长度
- sample_rate = f_sc * N_fft;
- N_cp=16; % 循环前缀长度
- N_symbo=N_fft+N_cp; % 1个完整的OFDM长度
- N_c=53; % 包含直流载波的子载波数
- M=256; % 256QAM调制
- SNR=20:5:30; %仿真信噪比
- N_frm=20; % 仿真的帧数
- Nd=6; % 每帧OFDM符号
- P_f_inter=6; %导频间隔
- data_station=[]; %导频位置
- L=7; %卷积码长度
- tblen=6*L; %Viterbi译码深度?
- stage = 3; % m序列的阶数
- ptap1 = [1 3]; % m序列的寄存器连接方式
- regi1 = [1 1 1]; % m序列寄存器初始值
- 接下来生成基带信号,并进行OFDM调制:
- %% 基带数据生成
- P_data=randi([0 1],1,N_sc*Nd*N_frm);
- %% 信道编码(卷积码、或交织器)
- %卷积码:前向纠错非线性码
- %交织:使突发错误最大限度的分散化
- trellis = poly2trellis(7,[133 171]);
- code_data=convenc(P_data,trellis);
- %% 256QAM调制
- data_temp1= reshape(code_data,log2(M),[])';
- data_temp2= bi2de(data_temp1);
- %modu_data=pskmod(data_temp2,M,pi/M); % 复数
- modu_data=qammod(data_temp2,M,"bin");
- %figure(1);
- scatterplot(modu_data);
- %% 插入导频
- P_f=3+3*1i; %Pilot frequency
- P_f_station=[1:P_f_inter:N_fft];%导频位置,P_f_inter 导频间隔,为6。
- pilot_num=length(P_f_station);%导频数量
- for img=1:N_fft %数据位置
- if mod(img,P_f_inter)~=1 %mod(a,b)就是求的是a除以b的余数
- data_station=[data_station,img];
- end
- end
- %data_station 是存放数据的位置,表示了数据位置的index
- data_row=length(data_station);
- data_col=ceil(length(modu_data)/data_row);
- pilot_seq=ones(pilot_num,data_col)*P_f;%将导频放入矩阵
- data=zeros(N_fft,data_col);%预设整个矩阵
- data(P_f_station(1:end),:)=pilot_seq; %对pilot_seq按行取, 对应的行全是导频数据
- if data_row*data_col>length(modu_data)
- data2=[modu_data;zeros(data_row*data_col-length(modu_data),1)];%将数据矩阵补齐,补0是虚载频~
- end
- %% 串并转换
- data_seq=reshape(data2,data_row,data_col);
- data(data_station(1:end),:)=data_seq;%将导频与数据合并
- %% IFFT
- ifft_data=ifft(data);
- %% 插入保护间隔、循环前缀
- Tx_cd=[ifft_data(N_fft-N_cp+1:end,:);ifft_data];%把ifft的末尾N_cp个数补充到最前面
- plot(abs(Tx_cd(:,1)));
- %% 并串转换
- Tx_data=reshape(Tx_cd,[],1);%由于传输需要
- Txdata中的数据即为调制后的时域数据,接下来需要做的事情就是把Tx_data调制到载波上,并通过UCA天线发送出去。
- for mode =1:7 % 在同一个UCA天线上发送不同的模式
- for jj=1:length(SNR) %% 经过信道
- disp(sprintf('Running in Mode=%d, SNR=%d',mode, SNR(jj)));
- N = f_c /sample_rate * N_sample; % 每个符号对应载波的采样点数;
- i_data = zeros(1, length(Tx_data * N));
- q_data = zeros(1, length(Tx_data * N));
-
- %% 发送端8跟天线
- freq = f_c;
- c = 3e8;
- lamda = c/freq;
- bias = [0,45,90,135];
- x = zeros(8,3);
- x(1,:)=[0.269375, 0,0];
- x(2,:) = [0.190477, 0.190477,0];
- x(3,:) = [0, 0.269375,0];
- x(4,:) = [-0.190477, 0.190477,0];
- x(5,:) = [-0.269375, 0,0];
- x(6,:) = [-0.190477, -0.190477,0];
- x(7,:) = [0, -0.269375,0];
- x(8,:) = [0.190477, -0.190477,0];
- phase_in_mode = [0:pi/4:7*pi/4; 0:2*pi/4:7*2*pi/4; 0:3*pi/4:3*7*pi/4; 0:4*pi/4:4*7*pi/4; 0:5*pi/4:7*5*pi/4; 0:6*pi/4:7*6*pi/4; 0:7*pi/4:7*7*pi/4];
- %% 接收端8根天线
- ant_dix = zeros(8,3);
- target = [0 0 5];
- for i =1:8
- ant_dix(i,:) = 3*x(i,:)+target;
- end
- tx_channel_data = zeros(8,8,length(Tx_data)*N);
-
- for m = 1:8% 8个接收天线
- for n = 1:8 % 对应8个发送天线
- dist = norm(ant_dix(m,:)-x(n,:));
- N = f_c /sample_rate * N_sample; % 每个符号对应载波的采样点数;
- i_data = zeros(1, length(Tx_data * N));
- q_data = zeros(1, length(Tx_data * N));
-
- for i = 1:length(Tx_data)
- j = 1: N;
- % 把7中拓扑荷的数据叠加在一起;
- i_data(N * (i-1)+j) =sum((cos(phase_in_mode(1:7,n)) * real( Tx_data(i))) * cos ( 2* pi * j /N_sample + dist/c * 2*pi*freq));
- q_data(N * (i-1)+j) =sum((-1*cos(phase_in_mode(1:7,n)) *imag( Tx_data(i))) * sin ( 2* pi * j /N_sample+ dist/c * 2*pi*freq));
- end
- tx_channel_data(m,n,:) = awgn((i_data + q_data),SNR(jj),'measured');
- end
- end
- oam_rx_channel_data = squeeze(sum(tx_channel_data,2));
- oam_rx_channel_data即为信道中发送的带有多种拓扑荷的数据,接下来使用UCA天线完成各拓扑荷数据的接收解调。
- %% 接收端
- rx_i_data = zeros(length(Tx_data),1);
- rx_q_data = zeros(length(Tx_data),1);
- rx_channel = zeros(length(Tx_data),8);
- for rx_idx=1:8 % 分别取出8个天线上的数据
- for i = 1:length(Tx_data)
- j = 1: N;
- I_temp(j) = oam_rx_channel_data(rx_idx,N * (i-1)+j) .* cos ( 2* pi * j /N_sample);
- Q_temp(j) = -1* oam_rx_channel_data(rx_idx,N * (i-1)+j) .* sin ( 2* pi * j /N_sample);
- rx_i_data(i) = cos(phase_in_mode(mode,rx_idx)) * sum(I_temp);
- rx_q_data(i) = cos(phase_in_mode(mode,rx_idx)) * sum(Q_temp);
- end
- rx_channel(:,rx_idx) = rx_i_data + rx_q_data * 1i;
- end
- % 将接收到的信号叠加(积分),非目标拓扑荷数据将为0。
- sumed_rx_channel = sum(rx_channel,2);
- %% 串并转换
- Rx_data1=reshape(sumed_rx_channel,N_fft+N_cp,[]);
-
- %% 去掉保护间隔、循环前缀
- Rx_data2=Rx_data1(N_cp+1:end,:);
- %% FFT
- fft_data=fft(Rx_data2);
-
- %% 信道估计与插值(均衡)
- data3=fft_data(1:N_fft,:);
- Rx_pilot=data3(P_f_station(1:end),:); %接收到的导频
- h=Rx_pilot./pilot_seq;
- H=interp1( P_f_station(1:end)',h,data_station(1:end)','linear','extrap');%分段线性插值:插值点处函数值由连接其最邻近的两侧点的线性函数预测。对超出已知点集的插值点用指定插值方法计算函数值
- %% 信道校正
- data_aftereq=data3(data_station(1:end),:)./H;
- %% 并串转换
- data_aftereq=reshape(data_aftereq,[],1);
- data_aftereq=data_aftereq(1:length(modu_data));
- data_aftereq=reshape(data_aftereq,N_sc,length(data_aftereq)/N_sc);
-
- %% 没有使用解扩,直接赋值过来了
- demspread_data = data_aftereq;
-
- %% 256QAM
- demodulation_data=qamdemod(demspread_data,M,"bin");
- De_data1 = reshape(demodulation_data,[],1);
- De_data2 = de2bi(De_data1);
- De_Bit = reshape(De_data2',1,[]);
- %% (解交织)
- %% 信道译码(维特比译码)
- trellis = poly2trellis(7,[133 171]);
- rx_c_de = vitdec(De_Bit,trellis,tblen,'trunc','hard');
- %% 计算误码率
- [err,Ber2(jj)] = biterr(De_Bit(1:length(code_data)),code_data);
- [err, Ber(mode,jj)] = biterr(rx_c_de(1:length(P_data)),P_data);
- end % 对应for jj=1:length(SNR) , 每个拓扑荷计算在不同SNR的误码率
- end % 对应 for mode =1:7,不同模式遍历一遍
- 做出误码率图:
- semilogy(SNR,Ber(1,:),'b-s');
- hold on;
- semilogy(SNR,Ber(2,:),'k-o');
- hold on;
- semilogy(SNR,Ber(3,:),'r-*');
- hold on;
- semilogy(SNR,Ber(4,:),'b-o');
- hold on;
- semilogy(SNR,Ber(5,:),'k-s');
- hold on;
- semilogy(SNR,Ber(6,:),'r-o');
- hold on;
- semilogy(SNR,Ber(7,:),'r-+');
- hold on;
- legend('M=1','M=2','M=3','M=4','M=5','M=6','M=7');
- hold on;
- xlabel('SNR');
- ylabel('BER');
- title('AWGN信道下不同拓扑荷误比特率')
复制代码
误码率对比图如下,可以看到拓扑荷Mode=4时误码率较高,近乎达到了50%,Mode=1和Mode=7时误码率最低,Mode=2和6误码率接近,Mode=3和Mode=5误码率接近。提升SNR或降低调制阶数,误码率会有明显改善。
|