clear all;
close all;
clc;
% 最近同步技术里面有很多关于costas环的帖子,很多集中讨论环路滤波的,也有自己做了程序发出来。但都没有一个完整的结论和系统的有方向性的讨论点.最近做了一个simulink仿真.个人认为现有的所谓经典方法很难被别人掌握.因此,从锁相环的原理出发,结合现成的经典方法,做了这个仿真.说明一下:
% 一个是高载频,一个是低载频的。低载频的我用的FIR代替的积分清零器,大家可以换成积分清零器件.阶数应该几阶就可以了。
%
% 1:如果是没有进行成形滤波的数据,那么信息数据率不要太高,以防止在锁定 时间内发生极性翻转,这样就锁不住了。(说简单点就是信息数据对载波的调制作用引起的载波相位的突变.)
%
% 2.积分清零的目的是滤除倍频信号,在系统采样率(系统时钟)相对中频信号频率只是几倍关系时,积分清零阶数可以很低,几阶.原理在于数字频率对模拟频率的 归一化.
%
% 3.鉴相方式非常关键.将鉴频差和相差结合起来,是一个新的发现.这样可以很好的锁定.通过调整对应的两个控制增益,便可独立的控制相位和频率的锁定速度.相差(信号点所在的位置的相位)和频差(相位点旋转的方向和快慢)可以很直观的在星座图上看出来.
%
% 4.环路滤波器的输出进行积分操作,能够很好的把反馈送入NCO.
%
% 5.环路滤波器参数设置没什么新意思.阻尼0.707.噪声带宽25
%
% 欢迎大家下回去琢磨,然后讨论!论坛空间也有限,想好了再把你的问题说出来,谢谢!
% 阅过之后,更敢无新意,我的看法如下:
% 1,costas loop在不同的应用场合(诸如,符号速率,动态应力,多谱勒,信道环境等等),其环路设计就会有非常大的差异.
% 比如,在某些情况下,环路滤波的前或后,可能要进行环滤更新操作.以匹配NCO的需要.但通常的科环并不需要这样的设计等等.
% 2,变型的科环很多,难以统一一种模式.
% 3,经典的科环理论很重要,很多变型都是根据不同的应用进行改进的.
% 切忌:想以一种仿真结论来定论所有形式的科环设计.
% 同意楼上的。掌握一个跟踪环路的本质是重要的,光Costas环就有好多种,关键看你要应用在什么场合,实现复杂度有什么要求。
% 如果楼主想对costas环有点更深入的认识,建议考虑一下低SNR环境下或者高动态环境的载波跟踪这种例子可能会更有些帮助。这种情况下每一个环节的设计考虑就都不像你所说的那样简单了。至少不会有“环路滤波器参数设置没什么新意思.阻尼0.707.噪声带宽25”。
% 楼上两位说得很有道理,确实,针对不同的应用场合,环路的参数设置,滤波器的设计,鉴相方式,都会有所变化.
% 我发这篇帖的目的,就是希望大家可以从costas环原理的角度,通过仿真,掌握各种参数,各个关键部分,对环的影响,从而真正掌握锁相环的设计方法.而不是每遇到新问题就失去了主动权,找不到北.
%
% 还希望大家够针对具体的锁相环的问题,各抒己见.不泛泛而谈,深入下去,发扬我们大家的研学精神!
% gardner定时同步算法是一种适合高速信号的
% 反馈式算法,它只需要每符号两个采样点,且载波
% 相位误差不影响算法的定时性能,鉴于以上优点,
% 该算法适合多种应用场合。
%
% 它是从平方律定时推导出的,依靠检测码元转换处的
% 过零点来定时,因此数字基带信号的归零特性很大程度
% 上影响算法的性能,一般升余弦滤波器成型的数字波形
% 在码元转换点是不归零的,使码元转换点归零,一般使用
% 模拟系统中针对平方律定时的预滤波方法,理论和实践证明
% 这种方法是有效的,几乎可以消除定时抖动。
%
% 这里分享我找到的有关gardner算法的一些文章,基本涵盖了
% 各个放面的内容,包括算法原文,算法性能分析,算法的应用
% 和改进方面的文章
% 锁相环有几个体现捕捉性能的参数:
% 对于无源滤波二阶环路
% 捕捉带=4*sqrt(K*阻尼因子*环路自然角频率)
% 快捕带= 4*阻尼因子*环路自然角频率
%%
% 对于二阶环
% 根据带宽与阻尼系数的关系
% 一般取阻尼系数为0.707
% 剩下的就是确定环路带宽了
% 当然要确定最终的k1k2,鉴相或者鉴频增益也是很重要的
% GPS的跟踪,一般采用数字锁相环的结构. 环路等效噪声带宽的设计数字环路的一个重要参数,
%该参数影响着环路的收敛速度,跟踪精度,以及环路可收敛的输入频差范围等, 反过来带宽的设计也由这些因素决定.
%
% 5楼给的数值应该分别是载波锁相环环路噪声带宽, 锁频环的噪声带宽以及码环的噪声带宽.
%通过噪声带宽可以求出环路滤波器的参数,(通常限定在3阶环路以下), 具体方法可以参考书籍:
% GPS原理及应用 第一, 二版, 还有一本是fundamentals of global positonging system receiver
% 这两本书比较适合初学者.
% 经常有师弟师妹问我怎样学习LDPC码,现在我将个人学习LDPC码的心得写在下面,以供参考。
% 1. 了解LDPC码的基本概念(主要是校验矩阵与Tanner图的关系)之后,学习LDPC码的和积译码算法。这里建议首先用概率测度推出无环图下,变量节点和校验节点消息的更新公式,透彻理解“消息”、“更新”和“传递”的含义。
% 2. 看LDPC码和积译码算法的程序。要点在双循环链表、两个消息更新的计算步骤(检验节点和变量节点运算,也叫水平步骤和垂直步骤)。(c 程序可以在网上Mackey的网站下,我这也有)。
% 3. 对LDPC码的和积译码算法充分理解之后,可以看密度进化理论及其高斯逼近算法,推倒文章中的公式是很有助于理解和积译码算法的。
% 4.经过步骤3,我们应该对什么样的LDPC码性能会好有一个初步的理解,这样我们可以试着设计 LDPC码。(高斯逼近和密度进化程序我这也有)
% 5.理解信道编码定理和Turbo原理,“码长”“随机”“迭代译码“”对于一个实用好码很重要。
% 另外,在这之前最好弄清楚信噪比,编码速率,BER和FER的含义。
%% gardner 位同步测试程序
%% M.Moeneclaey提出的数控方法
%% m(k+1)-m(k)=int[Ti/Ts+uk];
%% u(k+1)=[uk+Ti/Ts]mod1
clc;clear;format long;
fb=2e+6; %% 符号速率
fs=56e+6; %% 采样速率
ps=0;
%%%%%%%%%平方根滤波器%%%%%%%%%因为是采样率是28倍符号速率,所以采用了500阶的滤波器系数,保证通带和阻带的特性
load FIR2M;
Num=FIR2M;
i=0;q=0;
%%%%%%%%建立数据缓存区间%%%%%%%%%%%%%
dataI=zeros(1,501);
dataQ=zeros(1,501);
bufferI=zeros(1,501);
bufferQ=zeros(1,501);
bitsyninI=zeros(1,4); %% 插值滤波器的输入,每次插值需要连续四个数据
bitsyninQ=zeros(1,4);
GarI=zeros(1,3);
GarQ=zeros(1,3);
%%========环路滤波器===============
K0=fb*0.05; %% 环路的NCO增益
C2=2;
Alpha=0.5;
Kd=2*C2/((1-Alpha^2/4))*sin(pi*Alpha/2); %% 鉴相增益
K=K0*Kd; %% 环路增益
wn=0.03*fb; %% 环路滤波器的自然频率
Kesai=1/sqrt(2); %% 环路滤波器的衰减因子
%%============ 环路滤波器系数设计===========
g1=2*wn*Kesai/K;
g2=wn^2/fb/K;
g=[-g1;g1+g2];
cnt=0; %% 控制数据输出
LPF=0; %% 环路滤波输出
pre_TED=0; %% 前一鉴相值
TED=0; %% 当前鉴相值
%% NCO控制参数
deltamk=1;
deltamkcnt=0;
V=fs/fb/2;
uk=0;
t=0.014; %% 仿真时间
TimeLen=fix(t*fs);
%%-------建立存储文件-------------------------------------
if (exist('data1.txt')>0)
delete data1.txt;
end
fid1=fopen('data1.txt','a+');
if (exist('data2.txt')>0)
delete data2.txt;
end
fid2=fopen('data2.txt','a+');
if (exist('data3.txt')>0)
delete data3.txt;
end
fid3=fopen('data3.txt','a+');
disp('QPSK---------BitSync')
for k=1:TimeLen
ProcessShow(k,TimeLen,25); %%过程显示
ps=ps+fb; %%
if(ps>=fs)
ps=ps-fs;
i=randint*2-1; %% 输入随机数据 输出转化为双极性
q=randint*2-1;
end
dataI=[dataI(2:end),i]; %% 没有采用常规的插0方法,而是采用采样保持的方式
dataQ=[dataQ(2:end),q];
di=dataI*Num'; %% 成型滤波,Num为501位平方根升余弦滤波器
dq=dataQ*Num';
T_sign=(di+1j*dq); %% 发送信号
%%%%%%滑动窗存储接收信号,并完成卷积运算%%%%%%%%%%%%%
bufferI=[bufferI(2:end),real(T_sign)]; %滑动窗存储接收信号
bufferQ=[bufferQ(2:end),imag(T_sign)];
ri=bufferI*Num'; %% 匹配滤波
rq=bufferQ*Num';
fprintf(fid1,'%f,%f\n',ri,rq); %%存储匹配滤波后的波形
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
deltamkcnt=deltamkcnt+1;
bitsyninI=[bitsyninI(2:4),ri]; %%存储插值滤波前的连续4点
bitsyninQ=[bitsyninQ(2:4),rq];
if (flag)
flag=0;
C_4 = 0.5 * uk^2 - 0.5 * uk; % c_4=c(-2);其中内插系数为BS_Alpha=0.5
C_3 = -0.5 * uk^2 + ( 0.5 + 1 ) * uk; % c_3=c(-1)
C_2 = -0.5 * uk^2 + ( 0.5 - 1 ) * uk + 1; % c_2=c(0)
C_1 = 0.5 * uk^2 - 0.5 * uk; % c_1=c(1)
C=[C_1,C_2,C_3,C_4];
Inter_I=bitsyninI*C'; %插值输出
Inter_Q=bitsyninQ*C';
GarI=[GarI(2:3),Inter_I]; %用数组存放,表示I(k-2),I(k-1),I(k)
GarQ=[GarQ(2:3),Inter_Q];
cnt=mod(cnt+1,2);
if (cnt==1) %% 以数据速率完成环路滤波
I=Inter_I; %% 同步数据输出
Q=Inter_Q;
fprintf(fid2,'%f,%f\n',I,Q); %% 存储同步后的I,Q路数据
TED=GarI(2)*(GarI(3)-GarI(1))+GarQ(2)*(GarQ(3)-GarQ(1)); %Error=I(k-1)*[I(k)-I(k-2)]+Q(k-1)*[Q(k)-Q(k-2)];
LPF=[pre_TED,TED]*g+LPF; %环路滤波
pre_TED=TED;
end
end
V=V-LPF/256; %V近似等于Ti/Ts;
if (deltamkcnt==deltamk)
flag=1; %%产生插值脉冲
deltamkcnt=0; %%计数器,
deltamk=fix(uk+V); %%计算下一脉冲时刻
uk=mod(uk+V,1);
V=fs/fb/2; %%保证V是一个近似等于Ti/Ts的值
end
fprintf(fid3,'%f,%f,%f,%f\n',uk,deltamk,LPF,TED);%%%%%%%%%%%%%%%%存储观测参数
end
disp('The End!');
load data3.txt;
figure;
plot(data3(:,1))
title('小数间隔索引uk');
figure;
plot(data3(:,2))
title('整数间隔索引差M')
load data2.txt
figure;plot(data2(12000:end,1)+1j*data2(12000:end,2),'.')
title('同步后的星座图')
2022-04-28 21:51:30
9KB
科斯塔斯环
1