前言
GPS信号捕获的实现,给了我极大的信心,证明方案可行,使我看到了成功希望。下一步则是最重要的跟踪,我一直以为捕获跟踪完成之后,剩下的就是数学计算的问题了。实际上从捕获到真正的跟踪花费的时间是最多的。
在验证捕获过程的时候我想了一个巧妙地办法,模拟一路卫星的为随机信号,对于跟踪如法炮制,让产生的伪随机信号每隔20ms翻转一次,这样就有了0、1不断交替的数据位,当然帧同步可定是不行的,不过对于单纯的跟踪来说够用了。
这一步的实现并没有费多大力气,把中断信号的跟踪分支释放出来,六路相关峰值很快就出现了,因为是同一个时钟源,相关性特别好,同相支路峰值在3000左右,相关支路在两位数以内。但这只能表明软件功能跑起来了,当我把信号改成真正的天上的信号的时候,则遇到了极大的困难,环路根本无法锁定,偶尔锁定之后载波频率字很快便飞起来。
有人说是晶振的原因,MAX2769我当时用的默认配置,只能用16.368M的时钟,我的系统工作时钟为50M。于是我又中心做了一块底板,预留了外部时钟接口,本身也放了一个焊盘,但结果并不理想……再加上其他事情要忙进展便耽搁下来了……直到今年六月份,不甘心的我决定继续折腾起来,把买最后一片2769吹上去,16.368M的晶振也用完了,就把手头上的40M压控温补晶振贴上去,再次尝试用SPI配置,居然成功了,采样时钟设置为20M,倍频到50M的工作时钟,竟然一举解决了跟踪问题。
信号跟踪原理
前面说了那么多,只是吐槽了下过程。下面大致说下跟踪的基本原理。
GPS信号是一种扩频调制信号,通过C/A码进行捕获并获得测量信息,要想获得C/A码就需要对载波进行剥离,由于卫星到用户的相对运动,存在多普勒频移,因此载波在不断地发生变化。信号的跟踪则是为了适应这种变化而进行不断地调整。
码环通过其内部的码发生器尽量复制出一个与接收信号中的C/A码相一致的C/A码,然后让两者做相关运算,以剥离GPS接收信号中的C/A码,这同时也提高了原本淹没在噪声中的GPS信号的信噪比。基于C/A码的良好自相关特性,码环接着检测其复制的C/A码与接收C/A码之间的一致性程度,从而调整复制的C/A码的相位,使得它在下一时刻仍与接收的C/A码的相位相一致。尽管不同卫星同时播发中心频率相同的载波信号,但是由于不同卫星信号被不同的C/A码所调制,因而当接收机的某一信号通道决定跟踪某一颗被指定的卫星时,它只需要复制这颗卫星的C/A码,并使其与接收信号做相关运算,那么该通道在C/A码良好自相关性的机制作用下,可将这一卫星信号提取出来,同时又在接近于正交的互相关性机制作用下,将其他卫星信号成分压制成接近于零的噪声。为了最大限度地将所希望跟踪的那个卫星信号通过C/A自相关性机制提取出来,复制C/A码的相位必须与接收信号中的C/A码相位一致。当它们两者之间的相位一致时,自相关值会达到最大,而相关运算后的结果信号的功率也达到最强;否则,当两者相位不一致时,它们之间的自相关值会很小,相关结果信号的功率会很低,该卫星信号也就很难被码环所跟踪。
作为另一个跟踪环路,载波环的目的是尽力使其所复制的载波信号与接收到的卫星载波信号保持一致,从而通过混频机制彻底地剥离卫星信号中的载波。若复制载波与接收载波不一致,则接收信号中的载波就不能被彻底剥离,也就是说接收信号不能被下变频到真正的基带。不仅如此,若复制载波与接收载波不一致,则码环所得的C/A码自相关幅值也会受到削弱。我们知道,接收机射频前端已经将接收到的卫星信号从射频下变频到中频。因此,在基带数字信号处理部分,我们所讲的接收信号的载波频率,有时实际上是指射频前端输出的数字中频信号()IFs n的载波频率,而这两个频率之间的差异为一个值固定的射频前端本机振荡频率。
载波跟踪用到是是锁相环,是一个反馈控制的过程,组成如下图所示
接收机的跟踪环由载波环和码环组成,本地产生E,P,L三种码共形成6路相关值作为环路的输入量,经过计算之后产生频率字调整本地码和载波的速率,结构如下
作为输入的数字中频信号sIF(n)首先与载波环所复制的载波混频相乘,其中在I支路上与正弦复制载波相乘,在Q支路上与余弦复制载波相乘;然后,在I支路和Q支路上的混频结果信号i和q又分别与码环所复制的超前、即时和滞后三份C/A码做相关运算;接着,相关结果iE, iP, iL, qE, qP和qL经积分-清除器后分别输出相干积分值IE, IP, IL, QE, QP和QL;再后,即时支路上的相干积分值IP和QP被当做载波环鉴别器的输入,而其他两条相关支路上的相干积分值则时常作为码环鉴别器的输入;最后,载波环和码环分别对它们的鉴别器输出值φe(或者fe)和δcp进行滤波,并将滤波结果用来调节各自的载波数控振荡器和C/A码数控振荡器的输出相位和频率等状态,使载波环所复制的载波与接收载波保持一致,同时又使码环所复制的C/A即时码与接收C/A码保持一致,以保证下一时刻接收信号中的载波和C/A码在跟踪环路中仍被彻底剥离。在这一跟踪环路的运行过程中,载波环根据其所复制的载波信号状态输出多普勒频移、积分多普勒和载波相位测量值,同时码环根据其所复制的C/A码信号状态输出码相位和伪距测量值,而载波环鉴别器还可以额外地解调出卫星信号上的导航电文数据比特。
跟踪的实现
上图中,虚线左边为FPGA实现,右边CPU实现,FPGA每隔505us产生一个中断,上报相关值,CPU判断相关结果完成标志,如果完成则读取相关值进行环路计算。码环和锁相环的代码如下
//一阶码环
void DLL(ChannelType *pChannel)
{
float temp=0;
float ts = 0.001;
temp = 0.5 * (pChannel->power[0] - pChannel->power[2]) / (pChannel->power[1]);
if(pChannel->state==TRACK)
{
pChannel->DLL_Y = pChannel->DLL_Y + DLL2_A * temp * ts;
pChannel->DLL_X = pChannel->DLL_Y + DLL2_B * temp;
if(1==pChannel->satFreq)
{
temp = pChannel->DLL_X * CARRIER_WORD_STEP * 10 + pChannel->PLL_X*1.1;//*CARRIER_WORD_STEP/;
}
}
else
{
pChannel->DLL_Y = pChannel->DLL_Y + DLL2_A * temp * ts;
pChannel->DLL_X = pChannel->DLL_Y + DLL2_B * temp;
if(1==pChannel->satFreq)
{
temp = pChannel->DLL_X * CARRIER_WORD_STEP * 10;//
}
}
pChannel->codeFreq = pChannel->codeFreqBase +(s32)(temp);
}
锁相环
void PLL(ChannelType *pChannel)
{
float dphase=0;
float temp=0;
float ts = 0.001;
if (pChannel->power[1]!=0)
dphase = (pChannel->iCorr[1] * pChannel->qCorr[1]) / (pChannel->power[1]);
else
dphase = 0;
if(pChannel->PllLock >0.9)//
{
pChannel->PLL_Z = pChannel->PLL_Z + PLL3_A2 * dphase* ts;
pChannel->PLL_Y = pChannel->PLL_Y + (pChannel->PLL_Z + PLL3_B2 * dphase)*ts;
pChannel->PLL_X = pChannel->PLL_Y + PLL3_C2 * dphase;
}
else//
{
pChannel->PLL_Z = pChannel->PLL_Z + PLL3_A * dphase* ts;
pChannel->PLL_Y = pChannel->PLL_Y + (pChannel->PLL_Z + PLL3_B * dphase)*ts;
pChannel->PLL_X = pChannel->PLL_Y + PLL3_C * dphase;
}
temp = pChannel->PLL_X * CARRIER_WORD_STEP;
pChannel->carrierFreq = pChannel->carrierFreqBase+ (s32)(temp);
//锁相环锁定判据
temp = (pChannel->iCorr[1] * pChannel->iCorr[1]
- pChannel->qCorr[1] * pChannel->qCorr[1]) / (pChannel->power[1]);
pChannel->PllLock = 0.01 * temp + 0.99 * pChannel->PllLock;
} //void PLL
我懒得贴结果,总之稳定的跟踪是实现了,我在阳台上可以同时跟踪七八颗卫星的信号,我没有打印相关结果,从环路锁定判据来看没有跑飞。
总结
从捕获到跟踪花了整整一年的时间,大部分时间卡在时钟上面,准备工作到位了自然水到渠成。