📄 main.c
字号:
//IntFlag |= 0x8000; //for test!!!
TempUI = *TMRD0_CNTR;
CurrTimerCounter = *TMRD1_HOLD;
CurrTimerCounter <<= 16;
CurrTimerCounter += TempUI;
*TMRD3_SCR &= 0x7fff; //允许再次触发Compare中断
//在此处清除而不是在程序出口处清除中断申请标志的原因是:如果此次中断程序的处理时间过长,在处理过程中又产生了一次新的中断申请,
//则中断申请标志会再次置位,完成中断后会保证再次进入TD3中断,1秒内的TD3中断次数仍为1000次
*IPR = 0x0200; //只允许6级中断(PLR设置为7的中断)
asm (BFCLR #$0200,SR); //允许可屏蔽中断
if (++CurrTD3IntCounter >= 1000)
{
CurrTD3IntCounter = 0;
}
RecTd3OverflowCounter(CurrTimerCounter); //记录TD3溢出时刻,用于测试
if (CurrTD3IntCounter == 0) //调整TD3溢出时间与PPS上升沿同步
{
//RecOutputPpsCounter(CurrTimerCounter); //记录输出PPS上升沿计数器值,用于测试
RecOutputPpsCounter(OutputPpsCounter); //记录输出PPS上升沿计数器值,用于测试OutputPpsCounter
TempL = CurrTimerCounter - OutputPpsCounter;
if ((TempL > -12000) && (TempL < 12000))
//同步误差在300us以内时,调整1ms中断溢出时间与PPS上升沿同步
{
*TMRD3_CMP1 = 40000 - TempL;
}
else
//同步误差大于300us时,重启系统
{
asm (BFSET #0x0300, SR); //禁用所有可屏蔽中断
for(;;)
{
for (i=0; i<0xffff; i++)
{
asm(nop); //令系统重启
}
asm(BFCHG #0x0020, X:$13e1); //ALERT1指示灯闪烁
}
}
DealSoc(); //DealSoc
E.OneSecondTrigTimes = 0;
U.OneSecondTrigTimes = 0;
if (FirstOutputPpsFlag) //在第2秒起始时刻清除首个PPS输出标志
{
FirstOutputPpsFlag = 0;
}
}
else if (CurrTD3IntCounter == 1) //PPS到来后1ms
{
*TMRD3_CMP1 = 40000; //恢复TD3定时中断计数为标准值
CalPeriodCounterQueue(); //计算当前一秒内工频整周期时刻对应的计数值
}
else if (CurrTD3IntCounter == 3) //PPS到来后3ms
{
if (!FirstOutputPpsFlag)
{
AdjustPpsOutput(); //调整虚拟PPS输出时间
}
}
else if (CurrTD3IntCounter == 10) //PPS到来后10ms
{
LedOutput(); //判断装置状态,驱动指示灯
}
else if (CurrTD3IntCounter == 30) //PPS到来后30ms
{
if (E.ErrFlag) //键相脉冲输入不可用
{
EnableECapture(); //允许捕捉键相脉冲中断
}
}
else if (CurrTD3IntCounter == 50) //PPS到来后50ms
{
if (U.ErrFlag) //键相脉冲输入不可用
{
EnableUCapture(); //允许捕捉电压脉冲中断
}
}
else if (CurrTD3IntCounter == 350) //PPS到来后350ms
{
//熄灭所有状态正常指示灯
PULSE_LED_TURN_OFF;
UIN_LED_TURN_OFF;
CLOCK_LED_TURN_OFF;
PPS_LED_TURN_OFF;
}
else if (CurrTD3IntCounter == 450) //PPS到来后450ms
{
if (++Sci0RecErrCounter >= 5) //连续5秒未收到RCM3200的串口应答报文,认为串口通信出错
{
Sci0ErrFlag = 1;
}
else
{
Sci0ErrFlag = 0;
}
WriteRcm3200PatrolRpt(); //填写RCM3200串口巡检报文缓冲区
}
else if (CurrTD3IntCounter == 979) //PPS到来后979ms
{
JudgeUStat(); //判断U的输入状态是否正确
}
else if (CurrTD3IntCounter == 980) //PPS到来后980ms
{
JudgeEStat(); //判断E的输入状态是否正确
}
else
{
asm (BFSET #0x0300, SR); //禁用所有可屏蔽中断
TempUI = CurrTD3IntCounter / 20;
asm (BFCLR #0x0200, SR); //开启可屏蔽中断
i = CurrTD3IntCounter - TempUI * 20;
if (i == 2) //整周期后2ms时刻进行数据处理工作
{
CurrSmpcnt = TempUI * 96; //均为整周期时刻的smpcnt
CalAngle(); //计算内电势绝对角和发电机功角
WriteRcm3200DataRpt(); //填写内电势测量数据报文缓冲区
}
else if (i == 10) //整周期后10ms时刻进行DA输出判断,避开上送串口报文时间
{
DaOutputJudgeFlag = TRUE;
}
}
//判断SCI1的接收/发送状态切换时间
if ((ClockRecFinishCounter > 0) && (ClockRecFinishCounter < 300)) //Sci1在GPS报文接收完毕后300ms内允许切换到发送状态
{
ClockRecFinishCounter++;
}
if ((Sci1SwitchCounter > 0) && (Sci1SwitchCounter < 20)) //Sci1发送/接收状态切换计数20ms
{
Sci1SwitchCounter++;
}
//检测DA芯片错误状态
if (DA_FAULT_DETECT == 0)
{
DaErrFlag = 1;
}
else
{
DaErrFlag = 0;
}
if (!E.ErrFlag)
{
E.ErrorLastTime++;
}
if (!U.ErrFlag)
{
U.ErrorLastTime++;
}
ButtonFilter(); //对补偿值按钮调节进行去抖处理
/*for test!!!
if (IntFlag & 0x7fff)
{
asm(nop);
asm(nop);
asm(nop);
}
IntFlag = 0; //for test!!!*/
asm (BFSET #0x0300, SR); //禁用所有可屏蔽中断
*IPR = 0xfe00; //允许0-6级中断
}
/*****end of 1ms定时器中断,Timer D3*****/
/*****计算当前一秒内工频整周期时刻对应的计数值*****/
#pragma interrupt
void CalPeriodCounterQueue(void)
{
unsigned long TempUL1, TempUL2;
unsigned int TempUI1, TempUI2;
TempUL1 = AveragePpsPeriod;
asm (BFSET #0x0300, SR); //禁用所有可屏蔽中断
TempUL2 = TempUL1 / 50;
asm (BFCLR #0x0200, SR); //开启可屏蔽中断
TempUI1 = TempUL1 - TempUL2 * 50;
TempUI2 = 0;
if (FirstOutputPpsFlag)
{
TempUL1 = CurrInputPpsCounter;
}
else
{
TempUL1 = OutputPpsCounter;
}
PeriodCounterQueuePtr = &PeriodCounterQueue[0];
for (;;)
{
*PeriodCounterQueuePtr = TempUL1;
if (++PeriodCounterQueuePtr >= &PeriodCounterQueue[50])
{
break;
}
TempUL1 += TempUL2;
TempUI2 += TempUI1;
if (TempUI2 >=50)
{
TempUL1 += 1;
TempUI2 -= 50;
}
}
PeriodCounterQueuePtr = &PeriodCounterQueue[0];
}
/*****end of 计算当前一秒内工频整周期时刻对应的计数值*****/
/*****判断装置状态,驱动指示灯*****/
#pragma interrupt
void LedOutput(void)
{
if ((DetailErrInfo.Word & 0x00ff) || (GpsStat.Word & 0x00ff)) //2007.1
{
ALERT1_LED_TURN_ON;
}
else
{
ALERT1_LED_TURN_OFF;
}
if (!EinErrFlag)
{
PULSE_LED_TURN_ON;
}
if (!UinErrFlag)
{
UIN_LED_TURN_ON;
}
if (PpsLedOnFlag) //2007.1 当前秒同步正常PPS指示灯才点亮
//if (PpsSyncStat == 0) //同步异常时间不超过10秒,PPS指示灯就闪烁
{
PPS_LED_TURN_ON;
PpsLedOnFlag = FALSE;
}
if (!Sci1RecErrFlag && !SocErr && RealFixFlag) //2007.1
{
CLOCK_LED_TURN_ON;
}
}
/*****end of 判断装置状态,驱动指示灯*****/
/*****初始化内部WATCHDOG*****/
void InitIntWatchdog(void)
{
*COPTO = 0x0061; //20ms
//xxxx 保留 bit15-12
// 计算公式为:周期=16384 *( CT[11:0]+1 ) / clock cycle
*COPCTL = 0x0002; // 0000 0000 0000 1111
//xxxxxxxxxxxx 保留 bit15-4
//bit3 1 在停止模式COP依然工作
//bit2 1 在等待模式COP依然工作
//bit1 1 使COP工作
//bit0 1 COPCTL, COPTO为只读
}
/*****end of 初始化内部WATCHDOG*****/
/*****清除内部WATCHDOG*****/
void ClearIntWatchdog(void)
{
*COPSRV = 0xaaaa; //清DSP内部WATCHDOG
*COPSRV = 0x5555;
}
/*****end of 清除WATCHDOG*****/
/*****清除外部WATCHDOG*****/
void ClearExtWatchdog(void)
{
asm(BFCHG #0x0008,X:$13c1); //清外部WATCHDOG
}
/*****end of 清除WATCHDOG*****/
/*****记录输入PPS上升沿计数器值,用于测试*****/
#pragma interrupt
void RecInputPpsCounter(unsigned long RecCounter)
{
*InputPpsCounterRecBufPtr++ = RecCounter;
if (InputPpsCounterRecBufPtr >= &InputPpsCounterRecBuf[32])
{
InputPpsCounterRecBufPtr = &InputPpsCounterRecBuf[0];
}
}
/*****end of 记录输入PPS上升沿计数器值,用于测试*****/
/*****记录输出PPS上升沿计数器值,用于测试*****/
#pragma interrupt
void RecOutputPpsCounter(unsigned long RecCounter)
{
*OutputPpsCounterRecBufPtr++ = RecCounter;
if (OutputPpsCounterRecBufPtr >= &OutputPpsCounterRecBuf[32])
{
OutputPpsCounterRecBufPtr = &OutputPpsCounterRecBuf[0];
}
}
/*****end of 记录输出PPS上升沿计数器值,用于测试*****/
/*****记录TD3溢出时刻,用于测试*****/
#pragma interrupt
void RecTd3OverflowCounter(unsigned long RecCounter)
{
*Td3OverflowCounterRecBufPtr++ = RecCounter;
if (Td3OverflowCounterRecBufPtr >= &Td3OverflowCounterRecBuf[32])
{
Td3OverflowCounterRecBufPtr = &Td3OverflowCounterRecBuf[0];
}
}
/*****end of 记录输出PPS上升沿计数器值,用于测试*****/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -