📄 sci.c
字号:
/*-----------------------------------------------------------------------*
* Copyright (c) 2005,北京四方同创保护与控制设备有限公司稳控事业部
* All rights reserved.
*
* 文件名称:Sci.c
* 摘 要:异步串口SCI0/1相关的功能函数
* 采用CSS-200/1规约V1.02版
* 当前版本:2.00
* 作 者:胡炯
* 完成日期:2006.12
*-----------------------------------------------------------------------*/
#include "56807.h"
#include "CSFU107.h"
void Sci0RecInt(void); //SCI0接收中断(接收RCM3200报文)
void Sci1RecInt(void); //SCI1接收中断(接收GPS串口报文)
void CalSoc(void); //利用接收的串口报文计算SOC
void SendDataToRcm3200(void); //向RCM3200发送报文
void WriteRcm3200DataRpt(void); //填写内电势测量数据报文缓冲区
void WriteRcm3200PatrolRpt(void); //填写RCM3200串口巡检报文缓冲区
void SendDataToMeter(void); //向数显表发送报文
void WriteMeterBuf(unsigned int sign, unsigned int dot); //填写数显表报文缓冲区,sign:0-不带负号,1-带负号;dot:0-不带小数点,1-带小数点
extern void InitSci0RecVariable(void); //初始化与SCIO接收相关的变量(与RCM3200通信)
extern void InitSci1RecVariable(void); //初始化与SCI1接收相关的变量(接收GPS时钟信号)
extern void InitSci1Trans(void); //初始化SCI1的发送(向数据表发送数据)
extern void InitSci1Rec(void); //初始化SCI1的接收(接收GPS时钟信号)
/*****SCI0接收中断(接收RCM3200报文)*****/
#pragma interrupt
void Sci0RecInt(void)
{
unsigned int i;
unsigned int CheckSum;
int TempI;
if (*SCI0_SCISR & 0x0f00) //FE置位
{
*SCI0_SCISR &= 0xf0ff;
}
Sci0Data = *SCI0_SCIDR;
/*for test!
*Sci0RecBufPtr = Sci0Data;
if (++Sci0RecBufPtr >= &Sci0RecBuf[50])
{
Sci0RecBufPtr = &Sci0RecBuf[0];
}
//end of for test!*/
if (RecSci0Flag == 0)
{
if (((Sci0Data == 0x51) && (LastSci0Data == 0x37))
|| ((Sci0Data == 0xaa) && (LastSci0Data == 0x40)))
{
RecSci0Flag = 1;
*RecRcm3200BufPtr++ = LastSci0Data;
*RecRcm3200BufPtr++ = Sci0Data;
}
LastSci0Data = Sci0Data;
}
else if (RecSci0Flag == 1)
{
*RecRcm3200BufPtr++ = Sci0Data;
if (Sci0Data == 0x42)
{
*IPR = 0x0200; //只允许6级中断(PLR设置为7)
asm (BFCLR #$0200,SR); //允许可屏蔽中断
RecRcm3200DataSize = RecRcm3200BufPtr - &RecRcm3200Buf[0];
switch (RecRcm3200Buf[0])
{
case 0x37: //下发内电势参数报文
{
if (RecRcm3200DataSize == (REC_RCM3200_BUF_SIZE-1)) //报文接收结束
//可能报文中数据恰好是0x42,并不是报文结束标志,则继续数据接收
{
RecRcm3200BufPtr = &RecRcm3200Buf[1];
CheckSum = 0;
for (i=0; i<(REC_RCM3200_BUF_SIZE-4); i++)
{
CheckSum ^= *RecRcm3200BufPtr++;
}
if (CheckSum == *RecRcm3200BufPtr) //校验通过
{
if (RecRcm3200Buf[2] == 0x1E) //下发内电势补偿角
{
TempI = (int)((RecRcm3200Buf[4]<<8) + RecRcm3200Buf[3]);
if ((TempI >= -1800) && (TempI <= 1800))
{
E.CompensateValue = TempI; //更新内电势补偿角
WriteFlashStartFlag = TRUE; //要求将参数写入FLASH
Sci0ResponsionFlag = TRUE; //返回应答报文
}
}
else if (RecRcm3200Buf[2] == 0x2D) //下发机端电压补偿角
{
TempI = (int)((RecRcm3200Buf[4]<<8) + RecRcm3200Buf[3]);
if ((TempI >= -1800) && (TempI <= 1800))
{
U.CompensateValue = TempI; //更新机端电压补偿角
WriteFlashStartFlag = TRUE; //要求将参数写入FLASH
Sci0ResponsionFlag = TRUE; //返回应答报文
}
}
else if (RecRcm3200Buf[2] == 0x3C) //设定装置工作模式
{
RunStat = (RecRcm3200Buf[4]<<8) + RecRcm3200Buf[3];
WriteFlashStartFlag = TRUE; //要求将参数写入FLASH
Sci0ResponsionFlag = TRUE; //返回应答报文
}
/*else if (RecRcm3200Buf[2] == 0x4B) //下发内电势绝对角(预留)
{
}
else if (RecRcm3200Buf[2] == 0x5A) //下发发电机功角(预留)
{
}
else if (RecRcm3200Buf[2] == 0x69) //下发输出模拟量值(预留)
{
} */
if (Sci0ResponsionFlag) //填写应答报文缓冲区
{
Sci0ResponsionFlag = FALSE;
if ((WriteSendRcm3200QueuePtr->DataLength != 0) && (WriteSendRcm3200QueuePtr == ReadSendRcm3200QueuePtr))
//当前正在发送此帧报文,错开队列写入位置
{
if (++WriteSendRcm3200QueuePtr >= &SendRcm3200Queue[SEND_RCM3200_QUEUE_DEPTH])
{
WriteSendRcm3200QueuePtr = &SendRcm3200Queue[0];
}
}
WriteSendRcm3200QueuePtr->Data[0] = 0x38;
WriteSendRcm3200QueuePtr->Data[1] = 0xaa;
WriteSendRcm3200QueuePtr->Data[2] = 0x42;
WriteSendRcm3200QueuePtr->DataLength = 3;
if (++WriteSendRcm3200QueuePtr >= &SendRcm3200Queue[SEND_RCM3200_QUEUE_DEPTH])
{
WriteSendRcm3200QueuePtr = &SendRcm3200Queue[0];
}
}
}
InitSci0RecVariable();
}
break;
}
case 0x40: //串口通信巡检应答报文
{
if (RecRcm3200DataSize == 3)
{
Sci0RecErrCounter = 0;
}
InitSci0RecVariable();
break;
}
}
}
}
if (RecRcm3200BufPtr > &RecRcm3200Buf[REC_RCM3200_BUF_SIZE-1])
{
InitSci0RecVariable();
}
asm (BFSET #0x0300, SR); //禁用所有可屏蔽中断
*IPR = 0xfe00; //允许0-6级中断
}
/*****end of SCI0接收中断(接收RCM3200报文)*****/
/*****SCI1接收中断服务程序(接收GPS串口报文)*****/
#pragma interrupt
void Sci1RecInt(void)
{
unsigned int TempUI;
unsigned long TempUL;
if (*SCI1_SCISR & 0x0f00) //FE置位
{
*SCI1_SCISR &= 0xf0ff;
}
Sci1Data = *SCI1_SCIDR;
/*for test!
*Sci1RecBufPtr = Sci1Data;
if (++Sci1RecBufPtr >= &Sci1RecBuf[100])
{
Sci1RecBufPtr = &Sci1RecBuf[0];
}
//end of for test!*/
//for test
DEBUG2_LED_TURN_ON;
//end for test
if (CalSocFlag) //如果此时主循环尚未完成SOC计算,暂不接收新的数据
{
return;
}
switch (RecSci1Flag)
{
case 0:
{
if ( Sci1Data == '$')
{
RecSci1BufPtr = 0;
RecSci1Flag = 1;
RecSci1Buf[RecSci1BufPtr++] = Sci1Data;
Sci1SumFlag = TRUE;
Sci1CheckSum = 0;
}
break;
}
case 1:
{
RecSci1Buf[RecSci1BufPtr++] = Sci1Data;
if (RecSci1BufPtr == 6)
{
if (!((RecSci1Buf[1] == 'P') && (RecSci1Buf[2] == 'G') && (RecSci1Buf[3] == 'R')
&& (RecSci1Buf[4] == 'M') && (RecSci1Buf[5] == 'F')))
{
InitSci1RecVariable();
return;
}
}
if (RecSci1BufPtr >= 84)
{
InitSci1RecVariable();
Sci1RecErrFlag = 1;
return;
}
if (Sci1Data == '*')
{
Sci1SumFlag = 0;
return;
}
if (Sci1SumFlag)
{
Sci1CheckSum = Sci1CheckSum^Sci1Data;
}
else
{
if (Sci1Data == 10) //recieve LF
{
CalSocFlag = TRUE;
if (!PpsOutputFlag)
{ //还未开始输出虚拟PPS时,计算GPS串口报文结束字符到来时刻落后PPS上升沿的时间
TempUI = *TMRD0_CNTR;
TempUL = *TMRD1_HOLD;
TempUL <<= 16;
TempUL += TempUI;
GpsReportReachTimeCounter = TempUL - CurrInputPpsCounter;
}
else
{ //开始输出虚拟PPS后,直接读取当前秒内的TD3中断次数
GpsReportReachTime = CurrTD3IntCounter;
/*for test!!!
if (GpsReportReachTime > GpsReportMaxReachTime)
{
GpsReportMaxReachTime = GpsReportReachTime;
}
if (GpsReportReachTime < GpsReportMinReachTime)
{
GpsReportMinReachTime = GpsReportReachTime;
}
GpsReachTime.ReachTime[GpsReachTimeWritePtr] = GpsReportReachTime;
if ((GpsReportReachTime > 980) || (GpsReportReachTime < 20))
{
if (++GpsReachTimeErrorCnt >= 2)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -