matlab频率采样代码,有关通信的一段代码,主要用于消除采样钟频率偏差,想请教下各位...

该程序实现了基于O&M算法的并行定时恢复环路,通过频域滤波和预滤波处理串行数据,进行定时相偏校正。在并行结构下,根据mNCO输出的控制信号动态调整采样点,以适应定时误差估计。同时,利用环路滤波器和mNCO进行定时误差跟踪,输出定时误差跟踪值,并通过眼图观察解调数据质量。程序还包含了定时误差的计算模块`timingErrEst_OM_block`,用于从数据中估计定时误差。
摘要由CSDN通过智能技术生成

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

3、STR_parallel_OMwithPF_delay

%---本程序为增加频域滤波的O&M并行定时恢复环路----------------%

%---采样点的调整可以参考论文3.1.2节。

%---定时相偏校正原理:在频域匹配滤波之后乘以相应的对消旋转因子纠正----%

%---定时频偏校正原理:根据mNCO输出的控制信号进行采样点的删除或保持:

%-----需要注意的是,不仅需要对输入并行数据进行删除或保持,而且对重叠数据也需要删除或保持----%

%-----其中,skew_withPF用于控制对输入并行数据进行采样点的删除或保持,skew_withPF>0表示向后偏移,删除一个输入数据;skew_withPF<0表示向前偏移,将上一时刻最后一个数据保持一个时刻;

%-----sortInd_withPF用于控制对重叠数据进行删除或保持,若sortInd_withPF=-1,则需要删除重叠数据中的第一个数据;sortInd_withPF=1,则保持上一时刻240路重叠数据的前一个数据,dataKeep_withPF用于存储改值;

%---输入参数说明:---------------%

%---dataIn: 串行数据输入--------%

%---rxSRRC_fk: SRRC的频域系数--------%

%---preFilter_fk: 预滤波器的频域系数--------%

%---coefNum: SRRC系数个数--------%

%---prefilter_work:预滤波器是否工作------%

function [rxSTR,timingPhase_observation]= test_delay(dataIn,FFTNum,parallelNum,estLen,upSamping,rxSRRC_fk,preFilter_fk,coefNum,prefilter_work)

global g_STATE

persistent ReservedData_withPF dataKeep_withPF timingPhase_withPF;

persistent timing_err_withPF skew_withPF sortInd_withPF;

persistent delayPhase_reg delay_timingPhase delayM_reg delaySkew_reg delayM delaySkew;

persistent exp_func1 exp_func2;

persistent delay_reg1 delay_reg2 delay_reg3 delay_reg4;

persistent reg1_out reg2_out reg3_out reg4_out;

g_STATE = 0;

if g_STATE == 0

timing_err_withPF = 0; % 定时误差估计值初始化

skew_withPF = 0; % 串行数据读取偏移值,skew_withPF>0表示向后偏移一个点,skew_withPF>0表示向前偏移一个点

sortInd_withPF = 0; % 0--正常读取,1--保持一个采样点,-1--删除一个采样点

ReservedLen = FFTNum-parallelNum; % 重叠长度

ReservedData_withPF = zeros(ReservedLen,1); % 重叠保留数组初始化

dataKeep_withPF = 0; % 寄存上一时刻重叠数据的最后一个值

timingPhase_withPF = 0; % 定时相位跟踪值

STR_lpf_OMwithPF([]);

mNCO_OMwithPF([]);

% test:纠正定时相偏延迟一拍-----block

delayblock = 2;

delayPhase_reg = zeros(1,delayblock);

delayM_reg = zeros(1,delayblock);

delaySkew_reg = zeros(1,delayblock);

delay_timingPhase = 0;

delayM = 0;

delaySkew = 0;

exp_func1 = zeros(FFTNum/2,1);

exp_func2 = zeros(FFTNum/2,1);

% LPF and mNCO deay

delayClk = 6;

delay_reg1 = zeros(1,delayClk);

delay_reg2 = zeros(1,delayClk);

delay_reg3 = zeros(FFTNum/2,delayClk);

delay_reg4 = zeros(FFTNum/2,delayClk);

reg1_out = 0;

reg2_out = 0;

reg3_out = zeros(FFTNum/2,1);

reg4_out = zeros(FFTNum/2,1);

end

g_STATE = 1;

%% 参数初始化

interval = estLen/(parallelNum); % O&M算法在并行结构下进行一次估计需要的符号数

rxSTR_parallel = zeros(FFTNum,1); % 经过保持、删除或正常读取的16路并行数据

rxpreFilter = zeros(parallelNum,round(length(dataIn)/parallelNum)); % 预滤波器并行输出

for idx = 1:round(length(dataIn)/parallelNum)-10

%% 根据mNCO输出的控制信号进行采样点的删除、保持

% mod(idx,interval)的原因: O&M算法每进行一次定时误差估计需要interval个并行数据,而数据点的删除 或 保持只在跳变的第一个时刻

% sortInd_withPF用于控制对重叠数据的删除或保持

% skew_withPF用于控制对输入数据进行删除或保持

if(reg1_out == -1 && mod(idx,interval)== delayClk) %删除多余采样点,删除循环前缀的第一个,

ReservedData_withPF = [ReservedData_withPF(2:end);dataIn((idx-1)*parallelNum + reg2_out)];

elseif((reg1_out == 1 && mod(idx,interval)== delayClk))

ReservedData_withPF = [dataKeep_withPF;ReservedData_withPF(1:end-1)]; %保持保留数据的最后一个

end

% 叠加循环前缀

rxData_parallel = [ReservedData_withPF;dataIn((idx-1)*parallelNum+1+reg2_out:idx*parallelNum+reg2_out).'];

% 计算当前时刻循环前缀

dataKeep_withPF = rxData_parallel(FFTNum-parallelNum);

ReservedData_withPF = rxData_parallel(parallelNum+1:FFTNum);

% FFT变换到频域

rxData_FFT = fft(rxData_parallel,FFTNum);

%% 并行匹配滤波器

rxSRRC_parallel = rxData_FFT.*rxSRRC_fk.';

%% 频域纠正定时相偏---见论文3.1.1节中的公式

rxSTR_parallel(1:FFTNum/2) = rxSRRC_parallel(1:FFTNum/2).*reg3_out;

rxSTR_parallel(FFTNum/2+1:FFTNum) = rxSRRC_parallel(FFTNum/2+1:FFTNum).*reg4_out;

%% 频域预滤波

rxpreFilter_parallel = rxSTR_parallel.*preFilter_fk.';

%% 预滤波输出进行IFFT用于定时误差估计

rxpreFilter_parallel_tmp = ifft(rxpreFilter_parallel,FFTNum);

rxpreFilter(:,idx) = rxpreFilter_parallel_tmp(FFTNum+1-parallelNum-(coefNum-1)/2:FFTNum-(coefNum-1)/2);

%% 定时相位校正后进行IFFT得到解调数据

% STR输出

rxSTR_parallel_tmp = ifft(rxSTR_parallel,FFTNum);

rxSTR(:,idx) = rxSTR_parallel_tmp(FFTNum+1-parallelNum-(coefNum-1)/2:FFTNum-(coefNum-1)/2); % 取中间数据作为输出

%% O&M算法--每interval次估计一次

if(mod(idx,interval) == 0)

% O&M 算法用于定时误差估计

if(prefilter_work == 1)

timingErr_dataIn = rxpreFilter(:,idx-interval+1:idx); % 预滤波器输出--->估计定数误差

else

timingErr_dataIn = rxSTR(:,idx-interval+1:idx); % 无预滤波

end

% O&M算法的并行结构

timing_err_withPF = timingErrEst_OM_block(timingErr_dataIn,upSamping);

% 环路滤波器

STR_lpfOut = STR_lpf_OMwithPF(timing_err_withPF);

% mNCO

[timingPhase_withPF,skew_withPF,sortInd_withPF] = mNCO_OMwithPF(STR_lpfOut);

timingPhase_observation(idx) = timingPhase_withPF;

% delta 延迟一拍

delayPhase_reg = [delayPhase_reg(2:end) timingPhase_withPF];

delay_timingPhase = delayPhase_reg(1);

% 计算 exp 指数

exp_func1 = exp(1i*2*pi*delay_timingPhase*(0:FFTNum/2-1)/FFTNum).';

exp_func2 = exp(-1i*2*pi*delay_timingPhase*(FFTNum/2:-1:1)/FFTNum).';

% 为了保证跳点指示信号与exp指数对齐,将跳点指示信号打一拍

delayM_reg = [delayM_reg(2:end) sortInd_withPF];

delayM = delayM_reg(1);

delaySkew_reg = [delaySkew_reg(2:end) skew_withPF];

delaySkew = delaySkew_reg(1);

end

% LPF and mNCO delay : reg1->sortInd,reg2->skew_withPF,reg3->exp_func1,reg4->exp_func2

delay_reg1 = [delay_reg1(2:end) delayM];

reg1_out = delay_reg1(1);

% if(delayM == -1)

% disp('x');

% end

delay_reg2 = [delay_reg2(2:end) delaySkew];

reg2_out = delay_reg2(1);

delay_reg3 = [delay_reg3(:,2:end) exp_func1];

reg3_out = delay_reg3(:,1);

delay_reg4 = [delay_reg4(:,2:end) exp_func2];

reg4_out = delay_reg4(:,1);

end

timingPhase_observation = nonzeros(timingPhase_observation);

end

3、testbench-om

clear all;

load srrc_prefilter_coef.mat

load channel.mat

% 增加预滤波----O&M算法

FFTNum = 128; % FFT点数=128

upSamping = 4; % 上采样倍数=4

parallelNum = 8; % 并行路数,可选择

estLen = 256; % 并行O&M算法分段长度

channel_select = 1; %选择testbench的仿真信道:信道1:EsNo=100dB,ppm=20:信道2:EsNo=5dB,ppm=20;

% STR输入选择

if(channel_select == 1)

dataIn = chOut_100dB_20ppm;

else

dataIn = chOut_5dB_20ppm;

end

%% 并行STR

prefilter_work = 1; % 预滤波器工作指示:1表示预滤波工作,0表示预滤波不工作

[rxSTR_withPF,timingPhase_withPF] = STR_parallel_OMwithPF(dataIn,FFTNum,parallelNum,estLen,upSamping,srrc_fk,prefilter_fk,coefNum,prefilter_work);

%% When FPGA delay is considered

[rxSTR_withPF_delay,timingPhase_withPF_delay] = STR_parallel_OMwithPF_delay(dataIn,FFTNum,parallelNum,estLen,upSamping,srrc_fk,prefilter_fk,coefNum,prefilter_work);

%% 输出结果观测

% 输出定时误差跟踪值

figure;plot(timingPhase_withPF,'r.'); hold on; plot(timingPhase_withPF_delay,'b.');

xlabel('估计块');ylabel('定时偏差 \mu');

% 输出眼图

figure;

plot(real(rxSTR_withPF(1:4:end)),'r.');hold on;plot(real(rxSTR_withPF_delay(1:4:end)),'b.');

xlabel('并行符号数');ylabel('实部');

4、timingErrEst_OM_block

function [timing_err] = timingErrEst_OM_block(dataIn,upSamping)

% 计算模平方

[raw,line] = size(dataIn);

sqrd_data = abs(dataIn).^2;

dataTmp = sqrd_data;

dataTmp_1 = sum(sum(dataTmp(1:upSamping:raw-3,:)));

dataTmp_3 = sum(sum(dataTmp(3:upSamping:raw-1,:)));

dataTmp_2 = sum(sum(dataTmp(2:upSamping:raw-2,:)));

dataTmp_4 = sum(sum(dataTmp(4:upSamping:raw,:)));

Xm_re = dataTmp_1 - dataTmp_3;

Xm_im = dataTmp_2 - dataTmp_4;

Xm = Xm_re + 1i*Xm_im;

timing_err = (angle(Xm)/2/pi) * 4;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值