📄 main.c
字号:
}
else if (RealFixFlag && InputPpsComeFlag && PpsInputSyncOutputFlag)
// PPS同步不正常,但GPS锁星正常且捕获到了新的输入PPS脉冲且当前输入输出PPS同步正常,说明GPS开始转入正常
{
for (i=(PPS_ERR_REC_BUF_SIZE-1); i>=1; i--)
{
PpsInputOutputErrCnt[i] = PpsInputOutputErrCnt[i-1];
}
PpsInputOutputErrCnt[0] = CurrInputPpsCounter - OutputPpsCounter;
OutputPpsPeriod = AveragePpsPeriod + PpsInputOutputErrCnt[0]; //此次输出的PPS周期在平均值左右
PpsSyncErrorNum = 8; //如果后几秒同步失败,能够快速将PpsSyncErrorFlagGPS置位
PpsSyncErrorFlag = 0;
ResidueAdd = 0;
}
else if (PpsSyncErrorFlag && RealFixFlag && InputPpsComeFlag)
// GPS较长时间同步错误,当前GPS的PPS输入与输出PPS不同步,说明输出PPS守时可能已有较大偏离
// GPS锁星正常且捕获到新的输入PPS
{
for (i=(PPS_ERR_REC_BUF_SIZE-1); i>=1; i--)
{
PpsInputOutputErrCnt[i] = PpsInputOutputErrCnt[i-1];
}
PpsInputOutputErrCnt[0] = CurrInputPpsCounter - OutputPpsCounter;
if (PpsInputOutputErrCnt[0] < (-20000000))
{
OutputPpsPeriod = AveragePpsPeriod + PpsInputOutputErrCnt[0];
OutputPpsPeriod += AveragePpsPeriod;
}
else
{
OutputPpsPeriod = AveragePpsPeriod + PpsInputOutputErrCnt[0];
}
ResidueAdd = 0;
}
else // GPS失锁且未捕获到新的输入PPS
{
KeepPpsOutput(); //利用存储的平均值维持PPS输出
}
OutputPpsCounter += OutputPpsPeriod; //设定虚拟PPS上升沿输出时间
InputPpsComeFlag = 0;
}
/*****end of 判断输入、输出PPS误差,校正输出PPS*****/
/*****判断并返回当前的输入PPS是否与输出PPS同步良好*****/
#pragma interrupt
int IsCurPpsInputSyncOutput(void)
{
long TempL;
TempL = CurrInputPpsCounter - OutputPpsCounter;
if (((-INPUT_OUTPUT_PPS_ERROR) < TempL) && (TempL < INPUT_OUTPUT_PPS_ERROR)) //PPS同步良好
{
return TRUE;
}
else
{
return FALSE;
}
}
/*****end of 判断并返回当前的输入PPS是否与输出PPS同步良好*****/
/*****利用GPS授时信号校准输出PPS*****/
#pragma interrupt
void AdjustPps(void)
{
unsigned int i;
long lErrorCntGPS, lErrorCorr;
for (i=(PPS_ERR_REC_BUF_SIZE-1); i>=1; i--)
{
PpsInputOutputErrCnt[i] = PpsInputOutputErrCnt[i-1];
}
PpsInputOutputErrCnt[0] = CurrInputPpsCounter - OutputPpsCounter;
if (PpsPeriodCalRecBufFullFlag)
{
OutputPpsPeriod = PpsPeriodCalSum / PPS_PERIOD_REC_BUF_SIZE;
OutputPpsResidue += PpsPeriodCalSum - OutputPpsPeriod * PPS_PERIOD_REC_BUF_SIZE;
if (OutputPpsResidue >= PPS_PERIOD_REC_BUF_SIZE)
{
OutputPpsPeriod += 1;
OutputPpsResidue -= PPS_PERIOD_REC_BUF_SIZE;
}
asm (BFSET #0x0300, SR); //禁用所有可屏蔽中断
lErrorCntGPS = (PpsInputOutputErrCnt[0] * 3 + PpsInputOutputErrCnt[1] * 2 + PpsInputOutputErrCnt[2]) / 6;
asm (BFCLR #0x0200, SR); //开启可屏蔽中断
if (lErrorCntGPS > PPS_ERROR_CNT_LEVEL / 2 || lErrorCntGPS < 5)
{
lErrorCorr = NormanizeErrCorr(lErrorCntGPS / 2);
OutputPpsPeriod += lErrorCorr;
}
else
{
asm (BFSET #0x0300, SR); //禁用所有可屏蔽中断
lErrorCorr = lErrorCntGPS * lErrorCntGPS / PPS_ERROR_CNT_LEVEL;
asm (BFCLR #0x0200, SR); //开启可屏蔽中断
lErrorCorr = (lErrorCntGPS > 0) ? lErrorCorr : (-lErrorCorr);
lErrorCorr = NormanizeErrCorr(lErrorCorr);
OutputPpsPeriod = OutputPpsPeriod + lErrorCorr;
}
}
else
{
if (((-INPUT_OUTPUT_PPS_ERROR) < PpsInputOutputErrCnt[1]) && (PpsInputOutputErrCnt[1] < INPUT_OUTPUT_PPS_ERROR))
{
OutputPpsPeriod = OutputPpsPeriod - PpsInputOutputErrCnt[1] + 2*PpsInputOutputErrCnt[0];
}
else
{
OutputPpsPeriod += PpsInputOutputErrCnt[0];
}
}
PpsSyncErrorNum = 0;
ResidueAdd = 0;
RecPpsPeriod(CurrInputPpsPeriod); //记录正常的PPS间隔
PpsLedOnFlag = TRUE; //2007.1 PPS指示灯点亮
}
/*****end of 利用GPS授时信号校准输出PPS*****/
/*****规格化误差校正值*****/
#pragma interrupt
long NormanizeErrCorr(long lErrorCorr)
{
if (lErrorCorr > 3)
{
lErrorCorr = 3;
}
else if (lErrorCorr < -3)
{
lErrorCorr = -3;
}
return lErrorCorr;
}
/*****end of 规格化误差校正值*****/
/*****记录正确的秒脉冲周期****/
#pragma interrupt
void RecPpsPeriod(unsigned long PpsPeriod)
{
*PpsPeriodRecBufPtr++ = PpsPeriod;
if (PpsPeriodRecBufPtr >= &PpsPeriodRecBuf[PPS_PERIOD_REC_BUF_SIZE])
{
PpsPeriodRecBufPtr = &PpsPeriodRecBuf[0];
PpsPeriodRecBufFullFlag = TRUE;
}
}
/*****end of 记录正确的秒脉冲周期****/
/*****利用存储的平均值维持PPS输出*****/
#pragma interrupt
void KeepPpsOutput(void)
{
OutputPpsPeriod = AveragePpsPeriod;
ResidueAdd += AveragePpsResidue; //余数补偿
if (ResidueAdd >= PPS_PERIOD_REC_BUF_SIZE)
{
OutputPpsPeriod += 1;
ResidueAdd -= PPS_PERIOD_REC_BUF_SIZE;
}
}
/*****end of 利用存储的平均值维持PPS输出*****/
/*****处理SOC时间*****/
#pragma interrupt
void DealSoc(void)
{
unsigned long *TempULPtr;
unsigned long TempUL;
unsigned int i;
if ((Time == (LastTime+1)) && RealFixFlag)
{
SocStableCounter ++;
if (SocStableCounter > 8)
{
SocStableCounter = 8;
}
}
else
{
SocStableCounter = 0;
}
LastTime = Time;
if (SocStableCounter >= 8) //时标稳定可靠
{
Soc = Time + 1; //Time是解析串口报文得到的时间,表示前一个秒脉冲对应的时刻,Soc是上送报文的GPS时标
//UploadLeapSecond = LeapSecond; 2007.1 闰秒一旦更改立即上送,不再等待整秒
}
else //对应串口报文接收中断一些时间的情况
{ //时间报文不可用,自维持SOC
if (Soc != 0) //程序初始化后Soc等于0,只有在接收到有效时标后,Soc累加才有意义
{
Soc++;
}
NoSocCounter ++;
if (NoSocCounter >= 20000) //防止溢出
{
NoSocCounter = 20000;
}
}
//2007.1
if (CPU_VERSION_LARGE >= 2)
{
if (Soc != 0)
{
UploadSoc = Soc - UploadLeapSecond; //V2.00以上版本对闰秒进行补偿
}
}
else
{
UploadSoc = Soc;
}
GpsLockErr = FixType; //GPS锁星状况
if (NoSocCounter >= 10) //超过10秒没有收到有效SOC时间
{
SocErr = 1; //GPS串口对时丢失超过10秒
}
//2007.1 增加GPS卫星失锁时间的标识
if (!RealFixFlag)
{
GpsNotFixCnt++;
}
else
{
GpsNotFixCnt = 0;
}
if (GpsNotFixCnt >=60000)
{
GpsNotFixCnt = 60000; //防止溢出
}
if (GpsNotFixCnt <= 10)
{
GpsLockStat = 0;
}
else if (GpsNotFixCnt <= 100)
{
GpsLockStat = 1;
}
else if (GpsNotFixCnt <= 1000)
{
GpsLockStat = 2;
}
else
{
GpsLockStat = 3;
}
if (++Sci1RecErrTime >= 20) //连续20秒没有收到正确的GPS时钟报文
{
Sci1RecErrTime = 20; //防止溢出
Sci1RecErrFlag = TRUE;
if (!Sci1SendFlag) //如果当前SCI1未在发送数据,重新初始化串口
{
Sci1RecErrTime = 0;
ClockRecFinishCounter = 0;
InitSci1RecVariable(); //初始化串口接收缓冲区
InitSci1TransVariable();
InitSci1Rec(); //初始化SCI1,通过串口接收GPS时间信息
if (*SCI1_SCISR & 0x0f00)
{
*SCI1_SCISR &= 0xf0ff;
asm(nop);
asm(nop);
InitSci1Rec(); //初始化SCI1,通过串口接收GPS时间信息
}
}
}
/*计算PPS周期平均值*/
if (PpsOutputFlag && RealFixFlag) //开始输出PPS且锁星正常
{
if ((Soc & 0x0000003f) == 0) //每64秒计算一次
{
TempULPtr = &PpsPeriodRecBuf[0];
if (PpsPeriodRecBufFullFlag) //只有当秒脉冲周期缓冲区存满后才开始计算
{
TempUL = 0;
for (i=0; i<PPS_PERIOD_REC_BUF_SIZE; i++)
{
TempUL += *TempULPtr++;
}
AveragePpsPeriodBak = TempUL / PPS_PERIOD_REC_BUF_SIZE;
AveragePpsResidueBak = TempUL - AveragePpsPeriod * PPS_PERIOD_REC_BUF_SIZE;
if ((MinPpsPeriod < AveragePpsPeriodBak) && (AveragePpsPeriodBak < MaxPpsPeriod)) //秒脉冲周期在限定范围内
{
AveragePpsPeriod = AveragePpsPeriodBak;
AveragePpsResidue = AveragePpsResidueBak;
}
}
}
}
/*end of 计算PPS周期平均值*/
}
/*****end of 处理SOC时间*****/
/*****1ms定时器中断,Timer D3*****/
#pragma interrupt
void TimerD3Isr(void)
{
unsigned int i;
unsigned int TempUI;
unsigned long CurrTimerCounter;
long TempL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -