diff --git a/UAV_DCTF/DPLPP.mat b/UAV_DCTF/DPLPP.mat new file mode 100644 index 0000000000000000000000000000000000000000..5fc5648acb81e8e930140b62a847ee31c257fe88 Binary files /dev/null and b/UAV_DCTF/DPLPP.mat differ diff --git a/UAV_DCTF/F_Channel_Process.m b/UAV_DCTF/F_Channel_Process.m new file mode 100644 index 0000000000000000000000000000000000000000..fdbf3ac66dc7f815a93c9cd84b1f88495f87bfb7 --- /dev/null +++ b/UAV_DCTF/F_Channel_Process.m @@ -0,0 +1,5 @@ +function [Data_Process_Out] = F_Channel_Process(Data_Process_In,Channel_Mode,SNR_Sim) +% Data_Process_Out = filter(Channel_Mode,Data_Process_In); + Data_Process_Out = awgn(Data_Process_In,SNR_Sim,'measured'); +return; + diff --git a/UAV_DCTF/F_Generate_Nonlinear_Model.m b/UAV_DCTF/F_Generate_Nonlinear_Model.m new file mode 100644 index 0000000000000000000000000000000000000000..405589ff4d0279d4a21d806004b5c40c28642b0f --- /dev/null +++ b/UAV_DCTF/F_Generate_Nonlinear_Model.m @@ -0,0 +1,41 @@ +function [Nonlinear_Output_Sim] = F_Generate_Nonlinear_Model(Nonlinear_Points,Nonlinear_ThresPoint,Nonlinear_Max,Nonlinear_Order) + Nonlinear_Input = zeros(2*Nonlinear_Points+1,1); + Nonlinear_Output = zeros(2*Nonlinear_Points+1,1); + Nonlinear_Output_Sim = zeros(2*Nonlinear_Points+1,1); + + Nonlinear_Scale = Nonlinear_Max/Nonlinear_Points; + for n = Nonlinear_Points+1:2*Nonlinear_Points+1 + Nonlinear_Input(n,1) = Nonlinear_Scale*(n-Nonlinear_Points); + Nonlinear_Output(n,1) = Nonlinear_Input(n,1); + end + for n = 1:Nonlinear_Points + Nonlinear_Input(Nonlinear_Points+1-n,1) = -Nonlinear_Scale*n; + Nonlinear_Output(Nonlinear_Points+1-n,1) = Nonlinear_Input(Nonlinear_Points+1-n,1); + end + + for n = 2*Nonlinear_Points+1-Nonlinear_ThresPoint:2*Nonlinear_Points+1 + Nonlinear_Output(n,1) = Nonlinear_Output(2*Nonlinear_Points+1-Nonlinear_ThresPoint,1); + end + for n = 1:Nonlinear_ThresPoint + Nonlinear_Output(n,1) = Nonlinear_Output(Nonlinear_ThresPoint,1); + end + + Nonlinear_Parameter = polyfit(Nonlinear_Input,Nonlinear_Output,Nonlinear_Order); + for n = 1:2*Nonlinear_Points+1 + for m = 1:(Nonlinear_Order+1) + Nonlinear_Output_Sim(n,1) = Nonlinear_Output_Sim(n,1) + Nonlinear_Parameter(1,m)*(Nonlinear_Input(n,1)^(Nonlinear_Order+1-m)); + end + end + for n = Nonlinear_Points+1:2*Nonlinear_Points+1 + if(Nonlinear_Output_Sim(n,1)Nonlinear_Output_Sim(Nonlinear_Points-n+1,1)) + Nonlinear_Output_Sim(Nonlinear_Points-n,1)=Nonlinear_Output_Sim(Nonlinear_Points-n+1,1); + end + end +return; + + diff --git a/UAV_DCTF/F_Tx_Distortion_Process.m b/UAV_DCTF/F_Tx_Distortion_Process.m new file mode 100644 index 0000000000000000000000000000000000000000..a8016e2bf0942fe8fa56b4f2ad45d2d03be3edec --- /dev/null +++ b/UAV_DCTF/F_Tx_Distortion_Process.m @@ -0,0 +1,75 @@ +function [Data_Process_Out] = F_Tx_Distortion_Process(Data_Process_In,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original) +% Data_Process_In = S_BPSK; + + global Offset_Interval_I + global Tx_Frequencuy_Variation + global Tx_Frequencuy_Offset + global Tx_Filter_I + global Tx_Filter_Q + global I_DC_Offset % DC offset + global Q_DC_Offset + global I_Channel_Phase + global Q_Channel_Phase + global I_Channel_Gain + global Q_Channel_Gain + global Nonlinear_Coeff + global Phase_Noise_Var + global Nonlinear_Scale + global Nonlinear_Output_Sim + global Nonlinear_Points + Frequency_Offset_Trans = Tx_Frequencuy_Offset + Tx_Frequencuy_Variation*(rand-0.5); + Frequency_Modulation_Ratio = 0; %符号时钟偏差 + Frequency_Modulation_Ratio = (Modulation_Frequency_Rate+Frequency_Offset_Trans)/Sampling_Rate;% (Modulation_Frequency_Rate+Frequency_Offset_Trans)/Sampling_Rate; + + % 仿真采样率偏差 + Data_Symbol_Length = floor(length(Data_Process_In)/Sampling_Original*Sampling_Target)-Offset_Interval_I; + Data_Process_Out = resample(Data_Process_In,Sampling_Target,Sampling_Original); +% Data_Process_Out = Data_Process_In; + + % DC直流偏置,I/Q增益误差,I/Q相位偏差 + for n = 1:length(Data_Process_In) + Data_Process_Out(n,1) = I_Channel_Gain*(real(Data_Process_Out(n,1))+I_DC_Offset) * cos(Frequency_Modulation_Ratio*n*2*pi + I_Channel_Phase) - Q_Channel_Gain*(imag(Data_Process_Out(n,1))+ Q_DC_Offset) * sin(Frequency_Modulation_Ratio*n*2*pi+Q_Channel_Phase)... + + 1j*(I_Channel_Gain*(real(Data_Process_Out(n,1))+I_DC_Offset) * sin(Frequency_Modulation_Ratio*n*2*pi + I_Channel_Phase) + Q_Channel_Gain*(imag(Data_Process_Out(n,1))+ Q_DC_Offset) * cos(Frequency_Modulation_Ratio*n*2*pi+Q_Channel_Phase)); + end + + % 发送滤波器偏差 + Data_Symbol_Sample_Real = filter(Tx_Filter_I,1,real(Data_Process_Out)); + Data_Symbol_Sample_Imag = filter(Tx_Filter_Q,1,imag(Data_Process_Out)); + + Data_Process_Out = Data_Symbol_Sample_Real + 1j * Data_Symbol_Sample_Imag; + + Phase_Nosie = 0; + for i = 1:length(Data_Process_Out) +% Phase_Nosie = Phase_Nosie + (rand - 0.5)* 2 * sqrt(Phase_Noise_Var); + Phase_Nosie = (rand - 0.5)* 2 * sqrt(i*Phase_Noise_Var); + Data_Process_Out(i) = Data_Process_Out(i)*exp(1j*Phase_Nosie); + end + + % Saleh 建模 + AMAMParameters = [1 0]; + AMPMParameters = [0 0]; + saleh = comm.MemorylessNonlinearity('Method','Saleh model','AMAMParameters',AMAMParameters,'AMPMParameters',AMPMParameters); + Data_Process_Out = saleh(Data_Process_Out); + + +% % 幂级数建模 +% Data_Process_Out = Nonlinear_Coeff(1)*Data_Process_Out + Nonlinear_Coeff(2).*Data_Process_Out.*(abs(Data_Process_Out).^2) + Nonlinear_Coeff(3).*Data_Process_Out.*(abs(Data_Process_Out).^4); +% Temp_1 = sqrt(mean(abs(Data_Process_Out).^2)); +% Data_Process_Out = Data_Process_Out/Temp_1; +% +% for n = 1:Data_Symbol_Length +% Temp_1 = round(Data_Process_Out(n,1)/Nonlinear_Scale); +% Temp_1 = Temp_1 + Nonlinear_Points + 1; +% Data_Process_Out(n,1) = Nonlinear_Output_Sim(Temp_1,1); +% end +% +% Data_Process_Out = Data_Process_Out * Temp_1; + +return; + + + + + + + diff --git a/UAV_DCTF/FindPacket.m b/UAV_DCTF/FindPacket.m new file mode 100644 index 0000000000000000000000000000000000000000..f91e0ed74477dc7cd748037d9c6ce705afe11af8 --- /dev/null +++ b/UAV_DCTF/FindPacket.m @@ -0,0 +1,49 @@ +function [detected_packet,index] = FindPacket(rx_signal) + +win_size = 700; % 搜索窗大小 (理论上大于噪声长度500就行) +LTB = 16; % 每个短训练序列符号长度LTB + +% 一次性计算所有相邻符号相关性 +xcorr = rx_signal(1:win_size+2*LTB).* ... + conj(rx_signal(1*LTB+1:win_size+3*LTB)); %(732,1) +% (1:700+2*16) .* (1*16+1:700+3*16 = 1;732 .* 17:748 +%------------------------------------------------------------------------- +% 逐对计算所有相邻符号相关性mn(的分子|Cn|) +Cn_xcorr = zeros(700,1); +for i = 1:700 + recorder = 0; + for j = i : (i+2*LTB- 1) + recorder = recorder + (xcorr(j+1)); + end + Cn_xcorr(i) = abs(recorder); +end +%------------------------------------------------------------------------- +% 逐对计算所有相邻符号相关性mn(的分母Pn) +rx_pwr = abs(rx_signal(1*LTB+1 : win_size+3*LTB)).^2 ; %17-748 +Pn_xcorr = zeros(700,1); +for i = 1:700 + recorder = 0; + for j = i : (i+2*LTB-1) + recorder = recorder + rx_pwr(j+1); + end + Pn_xcorr(i) = recorder; +end +%------------------------------------------------------------------------- + +% 一次性计算所有相邻符号相关性mn=|Cn|/Pn +x_len = length(Cn_xcorr); % 700*1 +mn = Cn_xcorr(1:x_len)./Pn_xcorr(1:x_len); +% plot(mn) % 绘图 + +% 判断有无检测到包 +threshold = 0.75; % 判决门限值 +thres_idx = find(mn > threshold); % 查询满足条件(相关性大于门限值)元素的id +if isempty(thres_idx) + thres_idx = 1; +else + thres_idx = thres_idx(1); % 若有多个id满足条件,则取首个作为检测到包的起点 +end + +% 根据id取出数据包 +detected_packet = rx_signal(thres_idx:length(rx_signal)); +index=thres_idx; \ No newline at end of file diff --git a/UAV_DCTF/Findstart.m b/UAV_DCTF/Findstart.m new file mode 100644 index 0000000000000000000000000000000000000000..1f6bd8515517eb9e5e15bb37b92813c18ad30b31 --- /dev/null +++ b/UAV_DCTF/Findstart.m @@ -0,0 +1,36 @@ +function detected_packet = Findstart(rx_signal) %%貌似没用到 +idex=1; +ShortTrain = sqrt(13/6) * [0 0 1+j 0 0 0 -1-j 0 0 0 1+j 0 0 0 -1-j ... + 0 0 0 -1-j 0 0 0 1+j 0 0 0 0 0 0 -1-j 0 0 0 ... + -1-j 0 0 0 1+j 0 0 0 1+j 0 0 0 1+j 0 0 0 1+j 0 0].'; +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +%------------------------------------------------------------------------- +for i=1:4000 + li=0; + for jj=1:10 + y=short_train_blk.*conj(rx_signal((i+16*(jj-1)):(i+16*jj-1))) + abs(y) + threshold = 0.00075; % 判决门限值 + if abs(y)>=threshold + li=li+1; + end + end + if length(li)==6 + idex=i; + end + break; +end + +% % 判断有无检测到包 +% threshold = 0.8; % 判决门限值 +% thres_idx = find(mn > threshold); % 查询满足条件(相关性大于门限值)元素的id +% if isempty(thres_idx) +% thres_idx = 1; +% else +% thres_idx = thres_idx(1); % 若有多个id满足条件,则取首个作为检测到包的起点 +% end +% thres_idx +% 根据id取出数据包 +idex +detected_packet = rx_signal(idex:length(rx_signal)); diff --git a/UAV_DCTF/Global_Definition_dev1.m b/UAV_DCTF/Global_Definition_dev1.m new file mode 100644 index 0000000000000000000000000000000000000000..59565aef24cdab7328f93d9cdc51ff7afc34c891 --- /dev/null +++ b/UAV_DCTF/Global_Definition_dev1.m @@ -0,0 +1,99 @@ + +%% Distortion Parameters 失真参数 + +global Offset_Interval_I +global Tx_Frequencuy_Variation % 射频振荡器引入的相偏误差 +global Tx_Frequencuy_Offset % 射频振荡器引入的频偏误差 +global Tx_Filter_I % I路低通滤波器偏差 +global Tx_Filter_Q % Q路低通滤波器偏差 +global I_DC_Offset % I路直流偏置 +global Q_DC_Offset % Q路直流偏置 +global I_Channel_Phase %I路相位失配 +global Q_Channel_Phase %Q路相位失配 +global I_Channel_Gain %I路增益 +global Q_Channel_Gain %Q路增益 +global Nonlinear_Coeff %功放非线性 +global Modulation_Frequency_Rate +global Phase_Noise_Var %相位噪声 +global Nonlinear_Scale +global Nonlinear_Output_Sim +global Nonlinear_Points +global Channel_Rician %莱斯信道参数 +global Channel_Model +global Channel_Rayleigh +Offset_Interval_I = 0; +% Phase_Noise_Var = 0; +% Tx_Filter_I = [1 0.1 -0.1 0.06 0.04]; +Tx_Frequencuy_Offset = 0; +Tx_Frequencuy_Variation = 0; + + +I_DC_Offset = 0.18;%I/Q直流偏置 D1 +Q_DC_Offset =0.16; +varespilon = 0.10;%I/Q增益 +varphi = 0.02;%相位偏移误差 +Tx_Filter_I = [1 -0.1578];% I路h0 h1 +Tx_Filter_Q = [1 -0.1438];% Q路h0 h1 +Phase_Noise_Var =2.871*10^(-5); %振荡器相位噪声 +Nonlinear_Coeff = [0.125-0.011j 0.340-0.02j -0.2569-0.051j];%主要定义了一次项、二次项和三次项 + +Sampling_Original = 10000; %10000次仿真 +% Sampling_Target = 10001; +Sampling_Target = 10000; +% +% I_Channel_Gain = 0.95; +% Q_Channel_Gain = 1; +% I_DC_Offset = -0.05; +% Q_DC_Offset = 0.03; +% I_Channel_Phase = 0.01; +% Q_Channel_Phase = -0.02; + +I_Channel_Gain = 1 + varespilon; +Q_Channel_Gain = 1 - varespilon; + +I_Channel_Phase = -varphi; +Q_Channel_Phase = varphi; +% % +% Nonlinear_Coeff = [1 0 0 ]; +Nonlinear_Points = 4000; +% Nonlinear_ThresPoint = 0; +Nonlinear_ThresPoint = 1500; +Nonlinear_Max = 1; +Nonlinear_Order = 3; + +%% Channel Parameters +SNR_Sim = 30; +%Setup RF +Carrier_Frequency_Up = 2400; % MHz 载频 +Used_Bandwith = 20; % MHz +Sampling_Rate = 20e6; % MHz 之前是10e6,改成20e6(lisl) +Simulation_Sample = 1/Sampling_Rate; %采样间隔 +%Setup Channel +% Channel_Tau_Up = [0 310 710 1090 1730 2510]; % ns +% Channel_Gain_Up = [0 -1 -9 -10 -15 -20]; % dB +Channel_Tau_Up = [0]; % ns 各径的延时 +Channel_Gain_Up = [0]; % dB 各径的功率 +Rician_KFactor = 3; +Moving_Speed = 0.36; % Km/Hour + +Modulation_Frequency_Rate = 0; +%% Generate Non Linear Model 生成非线性模型 + +Nonlinear_Output_Sim = F_Generate_Nonlinear_Model(Nonlinear_Points,Nonlinear_ThresPoint,Nonlinear_Max,Nonlinear_Order); +Nonlinear_Scale = Nonlinear_Max/Nonlinear_Points; +% Channel Parameters +Doppler_Fd_Up = Moving_Speed*1000/3600*Carrier_Frequency_Up/300; %频偏 +Channel_Tau_Up = Channel_Tau_Up*1e-9; +Channel_Rician = comm.RicianChannel('SampleRate', Simulation_Sample, 'PathDelays', Channel_Tau_Up, 'AveragePathGains', Channel_Gain_Up, 'KFactor', Rician_KFactor, 'MaximumDopplerShift', Doppler_Fd_Up); +Channel_Rayleigh = comm.RayleighChannel('SampleRate', Simulation_Sample, 'PathDelays', Channel_Tau_Up, 'AveragePathGains', Channel_Gain_Up, 'MaximumDopplerShift', Doppler_Fd_Up); +Channel_Model = stdchan(Simulation_Sample,Doppler_Fd_Up,'Cost207RAx4'); %从一组标准化通道模型构造通道对象 + + +% 注意:需要先导入comm工具箱(如果未导入的话) +% % Channel Parameters +% Doppler_Fd_Up = Moving_Speed*1000/3600*Carrier_Frequency_Up/300; %频偏 +% Channel_Tau_Up = Channel_Tau_Up*1e-9; +% % Channel_Rician = ricianchan(Simulation_Sample,Doppler_Fd_Up,Rician_KFactor); %莱斯信道 +% % Channel_Rayleigh = rayleighchan(Simulation_Sample,Doppler_Fd_Up,Channel_Tau_Up,Channel_Gain_Up); %rayleighchan实现瑞利多径衰落信道 +% % Channel_Model = stdchan(Simulation_Sample,Doppler_Fd_Up,'cost207RAx4'); %从一组标准化通道模型构造通道对象 + diff --git a/UAV_DCTF/KEMLB.mat b/UAV_DCTF/KEMLB.mat new file mode 100644 index 0000000000000000000000000000000000000000..91a842bd81cd6288556dce7e1036e67b30ccacff Binary files /dev/null and b/UAV_DCTF/KEMLB.mat differ diff --git a/UAV_DCTF/RFF_Speed_KalmenSync.m b/UAV_DCTF/RFF_Speed_KalmenSync.m new file mode 100644 index 0000000000000000000000000000000000000000..b841c57ec27304143ac0ebed205a3b49b6026ec0 --- /dev/null +++ b/UAV_DCTF/RFF_Speed_KalmenSync.m @@ -0,0 +1,215 @@ +clear all; +clc; +Global_Definition_dev10;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +KEMLV_Array=KEMLV_Array_0.y2; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=30; +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + fd_2 = -KEMLV_Array(index); % 多普勒频偏为100Hz以内 + t2 = 0:1/fs:(length(rx_signal)-1)/fs; % 时间序列 + rx_signal = rx_signal .* exp(2*pi*1j*fd_2*t2(:)); % 添加多普勒频偏 + %rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_kem_device\dev10\dev10_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + diff --git a/UAV_DCTF/RFF_Speed_Unsync.m b/UAV_DCTF/RFF_Speed_Unsync.m new file mode 100644 index 0000000000000000000000000000000000000000..a7ece9c4d73e2c4630bfda9a0fbff9401c47a0a5 --- /dev/null +++ b/UAV_DCTF/RFF_Speed_Unsync.m @@ -0,0 +1,3228 @@ + %% dev1 +clear all; +clc; +Global_Definition_dev1;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + +%% 导入多普勒频偏 +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +% KEMLV_Array=KEMLV_Array.y2; + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; + + +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_unsync_device\dev1\dev1_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + +%% dev2 +clear all; +clc; +Global_Definition_dev2;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + +%% 导入多普勒频偏 +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +% KEMLV_Array=KEMLV_Array.y2; + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; + + +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_unsync_device\dev2\dev2_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + +%% dev3 +clear all; +clc; +Global_Definition_dev3;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + +%% 导入多普勒频偏 +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +% KEMLV_Array=KEMLV_Array.y2; + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; + + +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_unsync_device\dev3\dev3_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + +%% dev4 +clear all; +clc; +Global_Definition_dev4;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + +%% 导入多普勒频偏 +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +% KEMLV_Array=KEMLV_Array.y2; + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; + + +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_unsync_device\dev4\dev4_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + +%% dev5 +clear all; +clc; +Global_Definition_dev5;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + +%% 导入多普勒频偏 +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +% KEMLV_Array=KEMLV_Array.y2; + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; + + +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_unsync_device\dev5\dev5_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + +%% dev6 +clear all; +clc; +Global_Definition_dev6;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + +%% 导入多普勒频偏 +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +% KEMLV_Array=KEMLV_Array.y2; + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; + + +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_unsync_device\dev6\dev6_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + +%% dev7 +clear all; +clc; +Global_Definition_dev7;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + +%% 导入多普勒频偏 +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +% KEMLV_Array=KEMLV_Array.y2; + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; + + +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_unsync_device\dev7\dev7_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + +%% dev8 +clear all; +clc; +Global_Definition_dev8;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + +%% 导入多普勒频偏 +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +% KEMLV_Array=KEMLV_Array.y2; + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; + + +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_unsync_device\dev8\dev8_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + +%% dev9 +clear all; +clc; +Global_Definition_dev9;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + +%% 导入多普勒频偏 +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +% KEMLV_Array=KEMLV_Array.y2; + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; + + +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_unsync_device\dev9\dev9_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + +%% dev10 +clear all; +clc; +Global_Definition_dev10;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + +%% 导入多普勒频偏 +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +% KEMLV_Array=KEMLV_Array.y2; + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; + + +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_unsync_device\dev10\dev10_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + +%% dev11 +clear all; +clc; +Global_Definition_dev11;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + +%% 导入多普勒频偏 +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +% KEMLV_Array=KEMLV_Array.y2; + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; + + +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_unsync_device\dev11\dev11_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + +%% dev12 +clear all; +clc; +Global_Definition_dev12;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + +%% 导入多普勒频偏 +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +% KEMLV_Array=KEMLV_Array.y2; + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; + + +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_unsync_device\dev12\dev12_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + +%% dev13 +clear all; +clc; +Global_Definition_dev13;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + +%% 导入多普勒频偏 +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +% KEMLV_Array=KEMLV_Array.y2; + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; + + +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_unsync_device\dev13\dev13_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + + +%% dev14 +clear all; +clc; +Global_Definition_dev14;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + +%% 导入多普勒频偏 +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +% KEMLV_Array=KEMLV_Array.y2; + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; + + +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_unsync_device\dev14\dev14_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + +%% dev15 +clear all; +clc; +Global_Definition_dev15;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + +%% 导入多普勒频偏 +DPLPP_Array_0=load('DPLPP.mat'); +DPLPP_Array=DPLPP_Array_0.y1; + +KEMLV_Array_0=load('KEMLB.mat'); +% KEMLV_Array=KEMLV_Array.y2; + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; + + +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + % 加多普勒频偏 + fd = DPLPP_Array(index); % 多普勒频偏为100Hz以内 + t = 0:1/fs:(length(FadedSignal)-1)/fs; % 时间序列 + FadedSignal = FadedSignal .* exp(2*pi*1j*fd*t(:)); % 添加多普勒频偏 + + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_speed_unsync_device\dev15\dev15_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + + + diff --git a/UAV_DCTF/RFF_Static.m b/UAV_DCTF/RFF_Static.m new file mode 100644 index 0000000000000000000000000000000000000000..b6ea6415a5d8bd8aba19c6c7349d2585852af23a --- /dev/null +++ b/UAV_DCTF/RFF_Static.m @@ -0,0 +1,201 @@ +clear all; +clc; +Global_Definition_dev15;%下面目录也要改 +% 系统参数 +fs = 20e6; % 抽样频率 +ml = 2; % 调制阶数 = 2 —— QPSK调制 +NormFactor = sqrt(2/3*(ml.^2-1)); +gi = 1/4; % 保护间隔比例 = 1/4 +fftlen = 64; % FFT长度 = 64 points/chips +gilen = gi*fftlen; % 保护间隔/循环前缀长度 = 16 points/chips +blocklen = fftlen + gilen; % OFDM符号长度 = 80 points/chips +fig=0; + +% 子载波标号 +DataSubcPatt = [1:5 7:19 21:26 27:32 34:46 48:52]'; % 数据子载波位置标号 +PilotSubcPatt = [6 20 33 47]; % 导频子载波位置标号 +UsedSubcIdx = [7:32 34:59]; % 共用52个子载波 + + +% 信道编码参数 +trellis = poly2trellis(7,[133 171]); % 卷积码 +tb = 7*5; +ConvCodeRate = 1/2; % 码率 = 1/2 + + +% 训练序列 +% 短训练序列 (NumSymbols = 52) +ShortTrain = sqrt(13/6) * [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i ... + 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 0 0 0 -1-1i 0 0 0 ... + -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0].'; +NumShortTrainBlks = 10; % 短训练序列符号数 = 10 +NumShortComBlks = 16*NumShortTrainBlks/blocklen; % 160/80=2 +%plot(abs(ShortTrain)) +% 长训练序列 (NumSymbols = 52) +LongTrain = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 ... + 1 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1].'; +NumLongTrainBlks = 2; % 长训练序列符号数 = 2 + + +short_train = tx_freqd_to_timed(ShortTrain); % 把短训练序列从频域转换到时域 + +%plot(abs(ShortTrain)); +%title("短导码频谱") +short_train_blk = short_train(1:16); % 每个短训练序列长度16 +% plot(abs(short_train_blk)) +% title("短导码时域") +% 共10个短训练序列 -- 总长度为10*16=160 +short_train_blks = repmat(short_train_blk,NumShortTrainBlks,1); + +long_train = tx_freqd_to_timed(LongTrain); % 把长训练序列从频域转换到时域 +long_train_syms = [long_train(fftlen-2*gilen+1:fftlen,:); % 加循环前缀 + long_train; long_train]; +% plot(abs(long_train)) +% title("前导码频谱") +% 构成前导训练序列 +preamble = [short_train_blks; long_train_syms]; +% plot(abs(preamble)) +% title("前导训练序列时序波形") +% 包信息 +NumBitsPerBlk = 48*ml*ConvCodeRate; +% 每个OFDM符号信息量=48个*2(调制阶数,每个数2bit信息)*卷积码效率 +NumBlksPerPkt = 50; % 每个包OFDM符号数50 +NumBitsPerPkt = NumBitsPerBlk*NumBlksPerPkt; % 每个包信息量位50*48 +NumPkts = 600; % 总包数 + +% 信道与频偏参数 +h = zeros(gilen,1); % 定义多径信道 +h(1) = 1; h(3) = 0.5; h(5) = 0.2; % 3径 +h = h/norm(h); + + +% 定时参数 +ExtraNoiseSamples = 500; % 包前加额外500长度的噪声 +snr=20; +for index=1:NumPkts + + %% ***************************** Transmitter ******************************** + % 生成信息序列 + inf_bits = randn(1,NumBitsPerPkt)>0; % 生成48*50个信息比特 + + CodedSeq = convenc(inf_bits,trellis); % 卷积编码 + + % 调制 + CodedSeq= reshape(CodedSeq,2,[])'; + txData=bi2de(CodedSeq); + qpskModulator = comm.QPSKModulator; + ModedSeq = qpskModulator(txData); +% paradata = reshape(CodedSeq,length(CodedSeq)/ml,ml); % 分为两路: +% ModedSeq = qammod(bi2de(paradata),2^ml)/NormFactor; % 4QAM调制 +% ModedSeq=F_Tx_Distortion_Process(ModedSeq,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + mod_ofdm_syms = zeros(52, NumBlksPerPkt); + mod_ofdm_syms(DataSubcPatt,:) = reshape(ModedSeq,48,NumBlksPerPkt); + %调制后信号48行50列对应子载波id [1:5 7:19 21:26 27:32 34:46 48:52]'; + mod_ofdm_syms(PilotSubcPatt,:) = 1; % 加导频 + + % 对OFDM符号做Mapping及IFFT(输出64行50列) + tx_blks = tx_freqd_to_timed(mod_ofdm_syms); + + % 加循环前缀 + % 每个OFDM符号后16位重复放在前面做cp + tx_frames = [tx_blks(fftlen-gilen+1:fftlen,:); tx_blks]; %;表示换行 + + % 并串转换 + tx_seq = reshape(tx_frames,NumBlksPerPkt*blocklen,1); % 50*80 + tx = [preamble;tx_seq]; % 在50个OFDM符号前加前导序列,构成一个包 + tx=F_Tx_Distortion_Process(tx,Modulation_Frequency_Rate,Sampling_Rate,Sampling_Target,Sampling_Original); + %% ****************************** Channel ********************************* + FadedSignal = filter(h,1,tx); % 包通过多径信道 + len = length(FadedSignal); + noise_var = 1/(10^(snr/10))/2; + noise = sqrt(noise_var) * (randn(len,1) + 1i*randn(len,1)); + % 加噪声 + signal = awgn(FadedSignal,snr); + %包前侧加500长度的噪声 + extra_noise = sqrt(noise_var) * (randn(ExtraNoiseSamples,1) + ... + 1i*randn(ExtraNoiseSamples,1)); + %包后侧加170长度的噪声 + end_noise = sqrt(noise_var) * (randn(170,1) + 1i*randn(170,1)); + + % 接收信号 + rx = [extra_noise; signal; end_noise]; + + + %% ******************************* Receiver ***************************** + % 包检测 信号采集 捕获 + [rx_signal,index1] = FindPacket(rx); + %精准的时间同步 +% i_matrix=zeros(320,1); +% j_matrix=zeros(352,1); +% for j=1:352 +% for i=1:320 %训练序列的320位 +% i_matrix(i)=rx_signal(j+i-1).*conj(preamble(i)); %接受序列与训练序列共轭相乘 +% j_matrix(j)=j_matrix(j)+i_matrix(i); %以每一个bit为起始计算出一个和 +% end +% end +% [~,b] = max(abs(j_matrix)); %求和最大的,相关程度最高 + % abs(j_matrix); +% fine_time_est = b + + fine_time_est = FineTimeSync(rx_signal, long_train); %精细时间同步 注意文末补充材料的 finetimesync.m + fine_time_est=fine_time_est-193; + %频偏校正 利用短训练序列 + + % short_receive=rx_signal(fine_time_est:fine_time_est+159); + % short_receive=reshape(short_receive,16,10);%得到10个短训练序列 + % d=zeros(1,9); + % for i=1:9 + % for j=1:16 + % d(i)=d(i)+angle(short_receive(j,i+1))-angle(short_receive(j,i)); + % d(i)=d(i)/16; + % end + % end + % a=sum(d)/9; + % f_est=a/2/pi/16*fs; + % %频偏校正得到的前导码 + % df_est=exp(-j*2*pi*f_est*[0:351]/fs).'; + % rx_signal=rx_signal(fine_time_est:fine_time_est+351).*df_est; + start=index1+fine_time_est; + rx_signal_1=rx(start:start+1600); + rx_signal=rx(start:start+351); + % rx_signal = FrequencySync(rx_signal,fs); % 利用前导码去频偏 + %取第2至第5个短导码符号作为序列STF1 + STF1=rx_signal(1*16+1:5*16); + %取第7至第10个短导码符号作为序列STF2 + STF2=rx_signal(6*16+1:10*16); + + %取第1个长导码符号作为序列LTF1 + LTF1=rx_signal(193:256); + %取第2个长导码符号作为序列LTF2 + LTF2=rx_signal(257:320); +% plot(abs(rx_signal(1:16))) + + %%短导码差分星座图绘制 + % 导入已经同步去频偏的信号 + synced_signal=rx_signal_1; + % 提取前导码 + short_preamble = synced_signal(1:160); + long_preamble = synced_signal(161:320); + + % 将前导码分组 + short_preamble_matrix = reshape(short_preamble, [], 4); + long_preamble_matrix = reshape(long_preamble, [], 4); + + % 星座图 + %qpsk_constellation = [1+1i, -1+1i, -1-1i, 1-1i]; + + % 差分星座轨迹图 + short_preamble_diff = diff(short_preamble_matrix); + % 绘制短导码的差分星座轨迹图 + fig=fig+1; + figure(fig) + plot(short_preamble_diff, '.'); + title('Scatter plot'); + xlabel('I'); ylabel('Q'); + addres='D:\NOTEBOOK\Projects\Data_Codes\Wifi_process\WIFIpic\20230404\simulation_static_device\dev15\dev15_'; + name=strcat(addres,num2str(index)); + print(gcf, '-djpeg', name); + close; + +end + diff --git a/UAV_DCTF/kalman_doppler.m b/UAV_DCTF/kalman_doppler.m new file mode 100644 index 0000000000000000000000000000000000000000..9b69d7ed08bffafa51b3a2ac3e15b5c6348712f9 --- /dev/null +++ b/UAV_DCTF/kalman_doppler.m @@ -0,0 +1,47 @@ +function doppler = kalman_doppler(x,y,z,vx,vy,vz,dt,f) +% 基于卡尔曼滤波的多普勒频偏估计算法 +% 输入: +% x - 无人机 x 坐标向量 +% y - 无人机 y 坐标向量 +% z - 无人机 z 坐标向量 +% vx - 无人机 x 方向速度向量 +% vy - 无人机 y 方向速度向量 +% vz - 无人机 z 方向速度向量 +% dt - 时间间隔 +% f - 发射信号频率 +% 输出: +% doppler - 多普勒频偏向量 + +N = length(x); % 时间步数 +doppler = zeros(1,N); % 多普勒频偏 + +% 初始化卡尔曼滤波器 +F = [1,0,0,dt,0,0;0,1,0,0,dt,0;0,0,1,0,0,dt;0,0,0,1,0,0;0,0,0,0,1,0;0,0,0,0,0,1]; % 状态转移矩阵 +H = [1, 0, 0, 0, 0, 0; + 0, 1, 0, 0, 0, 0; + 0, 0, 1, 0, 0, 0; + 0, 0, 0, 1, 0, 0]; +Q = 1e-5*eye(6); % 过程噪声协方差矩阵 +R = 10*eye(4); % 观测噪声协方差矩阵 +xhat = [x(1);y(1);z(1);vx(1);vy(1);vz(1)]; % 初始状态估计 +P = 10*eye(6); % 初始误差协方差矩阵 + +for i=2:N + % 预测步骤 + xhat = F*xhat; + P = F*P*F' + Q; + + % 更新步骤 + zhat = H*xhat; + ytilde = [x(i);y(i);z(i);vx(i)] - zhat; + S = H*P*H' + R; + K = P*H'/S; + xhat = xhat + K*ytilde; + P = (eye(6)-K*H)*P; + + % 计算多普勒频偏 + v_rel = [xhat(4),xhat(5),xhat(6)]; % 相对速度向量 + r_rel = [xhat(1),xhat(2),xhat(3)]; % 相对位置向量 + doppler(i) = f * dot(v_rel,r_rel)/norm(r_rel)/3e8; % 多普勒频偏公式 +end +end \ No newline at end of file diff --git a/UAV_DCTF/wifi_qpsk_demod.m b/UAV_DCTF/wifi_qpsk_demod.m new file mode 100644 index 0000000000000000000000000000000000000000..2b5e6cdd066cbaf218e5208077d4f155a3bf9ca0 --- /dev/null +++ b/UAV_DCTF/wifi_qpsk_demod.m @@ -0,0 +1,26 @@ +function [bits] = wifi_qpsk_demod(signal) +% WIFI_QPSK_DEMOD: Demodulates a QPSK modulated signal using the WiFi +% constellation mapping and Gray-coded bit mapping. +% +% INPUTS: +% signal: the QPSK modulated signal to be demodulated +% +% OUTPUTS: +% bits: the demodulated bit stream +% +% Author: Zhaoyang Zhang +% Date: 17th September 2018 + +% WiFi QPSK constellation mapping +constellation = [1+1i, -1+1i, -1-1i, 1-1i]; +signal = abs(signal); +symbols = constellation(signal); +% Demodulate the signal using the WiFi QPSK constellation mapping + + +% Demap the symbols to bits using Gray coding +bits = qpsk_demapping(symbols); + +end + +