如题,最基础的 DCO-OFDM可见光通信matlab代码。采用QPSK调制,AWGN信道不需要均衡(如果是瑞利需要添加均衡),扩频什么的也懒得写了,需要可以自己加。
发送端有以下几个步骤:星座调制,共轭对称扩展,加DC(以上两步确保信号为正实数),IFFT,截断,加CP,D/A转换。
接收端:A/D转换,去CP,FFT(如果你的零频率用来传递信号的话需还要去DC),截取前一半(去共轭对称扩展),解调。
看别人私信问的问题补充一点:将直流偏置DC设置为最小值可要保证输出的是正信号,保证解调的时候的准确率,但是在考虑噪声的时候会增大信号功率,这样同SNR噪声也会变大,也会导致误码率增加,所以如何设置DC平衡噪声功率和解调误差造成的BER是一个问题。但是如果你不考虑噪声可忽略此点。
clc;
clear;
%% 参数设置
N=64; %一组X[k]长度
N_fft=N*2+2; % FFT 长度
N_cp=16; % 循环前缀长度、Cyclic prefix
N_symbo=N_fft+N_cp; % 1个完整OFDM符号长度
M=4; %QPSK调制
SNR=0:1:30; %信噪比(dB)
N_ofdm=100; % 每种信噪比下的OFDM符号数
DC=0:0.1:0.4; %直流偏置
%% 基带数据数据产生
base_data=randi([0 1],1,N*N_ofdm*log2(M));
%% qpsk调制
data_temp1= reshape(base_data,log2(M),[])'; %以每组2比特进行分组,M=4
data_temp2= bi2de(data_temp1); %二进制转化为十进制
mod_data=pskmod(data_temp2,M,pi/M); % 4PSK调制
% figure(1);
% scatterplot(mod_data),grid; %星座图
%% H对称
data=reshape(mod_data,N,[])';%分组
H_data=zeros(N_ofdm,N_fft);
H_data(:,2:N_fft/2)= data; %传输数据
H_data(:,N_fft/2+2:N_fft)= conj(fliplr(data));%厄米特
err=zeros(length(DC),length(SNR));
P_cutoff=zeros(1,length(DC));
for ii=1:length(DC)
%% IFFT
ifft_data=ifft(H_data,[],2);
%% 加DC
ifft_data=ifft_data+DC(ii)*ones(size(ifft_data));
%% 截断
ifft_data_temp=ifft_data;
ifft_data=0.5*(ifft_data+abs(ifft_data));
[num_cutoff,~]=size(find(ifft_data-ifft_data_temp));
P_cutoff(ii)=num_cutoff/(N_ofdm*N_fft);%截断的概率
%% 加CP
Tx_data=zeros(N_ofdm,N_fft+N_cp);
Tx_data(:,1:N_cp)=ifft_data(:,N_fft-N_cp+1:N_fft);%把ifft的末尾N_cp个数补充到最前面
Tx_data(:,1+N_cp:N_fft+N_cp)=ifft_data;
%% 信道(AWGN信道)
for jj=1:length(SNR)
%% 加噪声,AWGN
Rx_data=awgn(Tx_data,SNR(jj));%添加高斯白噪声
% sgma=10^(SNR(jj)/10).*
% Noise=
% Tx_data=Tx_data+Noise;
%% 去CP
Rx_data=Rx_data(:,1+N_cp:N_fft+N_cp);%(:,N_cp+1:N_fft+N_cp);
sum(sum(abs(Rx_data-ifft_data)))
% %% 去DC(没必要因为DC没有用,如果使用需去DC)
% ifft_data=ifft_data-0.6*ones(size(ifft_data));
%% FFT
fft_data=fft(Rx_data,[],2);
Rx_psk_data=fft_data(:,2:N_fft/2);
sum(sum(abs(Rx_psk_data-data)))
%% QPSK解调
demodulation_data=pskdemod(Rx_psk_data',M,pi/M);
demodulation_data= reshape(demodulation_data,[],1);
[err(ii,jj),~]=size(find(abs(demodulation_data-data_temp2)));
%% 误码率
[err(ii,jj),~]=size(find(abs(demodulation_data-data_temp2)));
end
end
BER=err/(N*N_ofdm);
figure;
hold on;
for a=1:length(DC)
semilogy(SNR,BER(a,:));
end
legend('DC=0','DC=0.1','DC=0.2','DC=0.3','DC=0.4');
xlabel('SNR(dB)');
ylabel('BER');
title('AWGN信道下误比特率曲线');
figure;
semilogy(SNR,BER(5,:));
xlabel('SNR(dB)');
ylabel('BER');
title('DC=0.4时AWGN信道下误比特率曲线');