📄 processcdt.cpp
字号:
///////////////////////////////////////////////////////////////////////
// ProcessCDT.cpp
#include "stdafx.h"
#include "fert2000.h"
#include "process.h"
extern bool bStopFlag;
extern CHANNEL Channels[MAX_CHANNEL_NUM];
extern RTU Rtus[MAX_RTU_NUM];
extern SYSTEMCOUNT SystemCount;
//extern CDatabase Database;
extern BYTE DebugCommand[0x23];//当前调试的命令数组
extern char DebugRtuNo;
extern EVENT Events;
extern RecSendThread RecSendThread1;
extern long ProgramStartTime;
extern NetProcess NetProcess1;
extern char YKEchoFlag[MAX_RTU_NUM];
extern BYTE YKEcho[MAX_RTU_NUM][6];//?
extern BYTE YKReserved[24];//?
extern unsigned char TBCH0[];
extern CFert2000App theApp;
//////////////////////////////////////////////////////////////////////////
void CDT(int i)
{
BYTE RtuNo=Channels[i].ChRtuNo[0];
if (!Rtus[RtuNo].Flag) return;
if (CDT_Rec(i,RtuNo))
{
Rtus[RtuNo].bWorking=TRUE;
Channels[i].bWorking=true;
CDT_Protocol(i,RtuNo);
}
//Add by yzw 2000.12.20
else
Rtus[RtuNo].bWorking=FALSE;
//Add by yzw 2000.12.20
CDT_Send(i,RtuNo);
}
bool CDT_Rec(int i,BYTE RtuNo)
{
BYTE Temp;
int SynstrCount = Channels[i].SynstrCount;
int InLen = MoxaBufIqueue(i);
if (InLen<6) return false;
if ((SynstrCount<6) && !(Channels[i].ChStatus & 0x2000))//同步字个数小于6,并且不是第一个信息字
{
for (int j=0;j<InLen;j++)
{
MoxaBufRead(i,&Temp,1);
if(Temp == Rtus[RtuNo].SynWord[SynstrCount+1]) SynstrCount++;
else SynstrCount = 0;
if (SynstrCount==6) break;
}
Channels[i].SynstrCount = SynstrCount;
}
InLen=MoxaBufIqueue(i);
if (SynstrCount==6)
{
if (InLen<6) return false;
MoxaBufRead(i,Channels[i].FileHead,6);
if (Channels[i].FileHead[5] != CDT_CheckCRC(Channels[i].FileHead))
{
Rtus[Channels[i].ChRtuNo[0]].ErrFrameSum += 5;
Rtus[Channels[i].ChRtuNo[0]].RecFrameSum += 5;
Channels[i].SynstrCount = 0;
return false;
}
Channels[i].SynstrCount = 0;
InLen -= 6;
Channels[i].ChStatus |= 0x2000;
}
if (Channels[i].ChStatus & 0x2000)
{
int Lenth = Channels[i].FileHead[2] * 6;
if (InLen <= Lenth && Lenth != 0)
return false;
else
{
Rtus[Channels[i].ChRtuNo[0]].RecFrameSum += Channels[i].FileHead[2] + 1;
MoxaBufRead(i,&Rtus[RtuNo].RecBuf[6],Lenth);
for (int j=0;j<6;j++) Rtus[RtuNo].RecBuf[j] = Channels[i].FileHead[j];
Rtus[RtuNo].RecBufPtr=Lenth+6;
Rtus[RtuNo].RecLen=Lenth+6;
Rtus[RtuNo].bReceiveCanDisp = TRUE;
SynstrCount = 0;
Channels[i].ChStatus &= 0xdfff;
}
}
else
return false;
return true;
}
void CDT_Protocol(int i,BYTE RtuNo)
{
int NonceInfoWord;
BYTE* RtuRecBuf=&(Rtus[RtuNo].RecBuf[0]);
//Add by yzw 2001.6.6 保证同一个功能码的信息字只处理一次,消除某些误码或者遥信变位连送三遍的情况下出现的不一致现象
bool bInfoWordIsHandle[255];
for (int kk = 0;kk < 255;kk++)
bInfoWordIsHandle[kk] = false;
///////////////////////////////////////
for (NonceInfoWord=6;NonceInfoWord < Rtus[RtuNo].RecBufPtr;NonceInfoWord +=6)//以信息字为单位,一个一个处理
{
int InfoCode=RtuRecBuf[NonceInfoWord];//功能码
if (CDT_CheckCRC(&RtuRecBuf[NonceInfoWord])!=RtuRecBuf[NonceInfoWord+5])//校验不对
{
Rtus[Channels[i].ChRtuNo[0]].ErrFrameSum++;
continue;
}
//Add by yzw 2001.6.6 保证同一个功能码的信息字只处理一次,消除某些误码或者遥信变位连送三遍的情况下出现的不一致现象
// if (bInfoWordIsHandle[InfoCode] == true)
// continue;
// else
// bInfoWordIsHandle[InfoCode] = true;
////////////////////////////////////////////
if ((InfoCode>=Rtus[RtuNo].ProtocolStamp[0])&&(InfoCode<=0x7f))//遥测,功能码在遥测定义起始码和7F之间
{
for (int j=0;j<2;j++)
{
WORD YcValue;
if (Rtus[RtuNo].ProtocolStamp[5]) //高低交换
YcValue=RtuRecBuf[NonceInfoWord+j*2+2] + RtuRecBuf[NonceInfoWord+j*2+1]*256;
else
YcValue = RtuRecBuf[NonceInfoWord+j*2+1] + RtuRecBuf[NonceInfoWord+j*2+2]*256;
WORD YcSign = (Rtus[RtuNo].ProtocolStamp[3])?0x8000:0x800;//遥测符号位:15 or 11
if (YcSign == 0x800)//遥测符号位:11
{
if ((YcValue & 0x8000) || (YcValue & 0x4000)) continue;
if (YcValue & YcSign)//遥测为负数
{
YcValue &= 0x7ff;
if(Rtus[RtuNo].ProtocolStamp[6]==1)//补码表示负数
YcValue = 0x7ff + 1 - YcValue;
Rtus[RtuNo].YcValue[(InfoCode-Rtus[RtuNo].ProtocolStamp[0])*2+j]=-(float)YcValue;
}
else
{
YcValue = YcValue & 0x7ff;
Rtus[RtuNo].YcValue[(InfoCode-Rtus[RtuNo].ProtocolStamp[0])*2+j]=(float)YcValue;
}
}
else if (YcSign == 0x8000)//遥测符号位:15
{
if (YcValue & YcSign)//遥测为负数
{
YcValue &= 0x7fff;
if(Rtus[RtuNo].ProtocolStamp[6]==1)//补码表示负数
YcValue = 0x7fff + 1 - YcValue;
if(Rtus[RtuNo].ProtocolStamp[4])//数值进制为BCD码
YcValue=(YcValue & 0xf) + ((YcValue & 0xf0)>>4)*10
+((YcValue & 0xf00)>>8)*100 + ((YcValue & 0x7000)>>12)*1000;
Rtus[RtuNo].YcValue[(InfoCode-Rtus[RtuNo].ProtocolStamp[0])*2+j]=-(float)YcValue;
}
else
{
YcValue &= 0x7fff;
if(Rtus[RtuNo].ProtocolStamp[4])//数值进制为BCD码
YcValue=(YcValue & 0xf) + ((YcValue & 0xf0)>>4)*10
+((YcValue & 0xf00)>>8)*100 + ((YcValue & 0x7000)>>12)*1000;
Rtus[RtuNo].YcValue[(InfoCode-Rtus[RtuNo].ProtocolStamp[0])*2+j]=(float)YcValue;
}
}
}
}
else if ((InfoCode>=Rtus[RtuNo].ProtocolStamp[1]) && (InfoCode<=0xff))//遥信
{
int iPosition = InfoCode - 0xf0;//第几组谣信已收到
int YxDWordPtr = InfoCode-Rtus[RtuNo].ProtocolStamp[1];
int YxValuePtr=YxDWordPtr*32;
DWORD YxWord=*(DWORD*)&RtuRecBuf[NonceInfoWord+1];
BYTE State=0;
for (int k=0;k<32;k++)
{
State = (YxWord & (1<<k)) ? 1 : 0;
if (Rtus[RtuNo].YxValue[YxValuePtr+k] != State)
{
Rtus[RtuNo].YxValue[YxValuePtr+k] = State;
if (Rtus[RtuNo].RecFullYx & (1<<iPosition))
YxEvent(RtuNo,YxValuePtr+k,State);//生成变位遥信Event
}
}
Rtus[RtuNo].RecFullYx |= (1<<iPosition);
}
else if((InfoCode>=Rtus[RtuNo].ProtocolStamp[2]) && (InfoCode<=0xdf))//电能KWH
{
if (!(RtuRecBuf[NonceInfoWord+4] & 0x80))//有效
{
DWORD KWHValue = 0;
if ((RtuRecBuf[NonceInfoWord+4] & 0x20) == 0)//not bcd
{
KWHValue = RtuRecBuf[NonceInfoWord+1] + RtuRecBuf[NonceInfoWord+2] * 256
+ RtuRecBuf[NonceInfoWord+3] * 256 * 256;
}
else
{
BYTE *t = &RtuRecBuf[NonceInfoWord+1];
KWHValue = ((t[2] & 0xf0)/16*10 + (t[2] & 0x0f))*10000
+ ((t[1] & 0xf0)/16*10 + (t[1] & 0x0f))*100 + ((t[0] & 0xf0)/16*10 + (t[0] & 0x0f));
}
Rtus[RtuNo].KwhValue[InfoCode-Rtus[RtuNo].ProtocolStamp[2]]=KWHValue;
}
}
else if ((InfoCode>=0x8d) && (InfoCode<=0x92))//水位
{
float WaterValue;
WaterValue =(float)((RtuRecBuf[NonceInfoWord+1] & 0xf)/100.0);
WaterValue +=(float)((RtuRecBuf[NonceInfoWord+1]>>4)/10.0);
WaterValue +=(RtuRecBuf[NonceInfoWord+2] & 0xf);
WaterValue +=(float)((RtuRecBuf[NonceInfoWord+2]>>4)*10.0);
WaterValue +=(float)((RtuRecBuf[NonceInfoWord+3] & 0xf)*100.0);
WaterValue +=(float)((RtuRecBuf[NonceInfoWord+3]>>4)*1000.0);
Rtus[RtuNo].Water[InfoCode-0x8d]=WaterValue;
}
else if ((InfoCode>=0x86) && (InfoCode<=0x89))//总加遥测
{
}
else if (InfoCode==0x8a)//频率
{
float Freq;
for (int k=0;k<2;k++)
{
Freq =0;
Freq =(float)((RtuRecBuf[NonceInfoWord+k*2+1] & 0xf)/100.0);
Freq +=(float)((RtuRecBuf[NonceInfoWord+k*2+1]>>4)/10.0);
Freq +=(float)(RtuRecBuf[NonceInfoWord+k*2+2] & 0xf);
Freq +=(float)((RtuRecBuf[NonceInfoWord+k*2+2]>>4)*10.0);
Rtus[RtuNo].Freq[k] = Freq;
}
}
else
CDT_Answer(i,RtuNo,NonceInfoWord);//SOE 子站时钟返送 子站状态信息,遥控返校 升降返校
}
Rtus[RtuNo].RecBufPtr=0;
}
void CDT_Answer(int i,int RtuNo,int &NonceInfoWord)
{
switch(Rtus[RtuNo].RecBuf[NonceInfoWord])
{
case 0x80://0x81 SOE
CDT_SOE_Event(RtuNo,NonceInfoWord);
break;
case 0x84:
case 0x85://子站时钟
CDT_ReviseTime(i,RtuNo,NonceInfoWord);
break;
case 0xe1:
case 0xe5://遥控,升降返校
CDT_YK_SJ_Pro(i,RtuNo,NonceInfoWord);
break;
case 0xec://子站状态信息
if(*((DWORD*)&Rtus[RtuNo].RecBuf[NonceInfoWord+1]) & 0X3007D)
Rtus[RtuNo].RTUStatus |=0x40;
Rtus[RtuNo].RTU_CDTStatus = *((DWORD*)&Rtus[RtuNo].RecBuf[NonceInfoWord+1]);
if (Rtus[RtuNo].RecBuf[NonceInfoWord+1] & 0x80)
{
Rtus[RtuNo].RTUStatus |= 0x2;
BYTE TimeBuf[12];
CDT_SetRtuTime(i,RtuNo);
//召唤子站时钟命令
for (int l=0;l<6;l++) TimeBuf[l] = Rtus[RtuNo].SynWord[l+1];
TimeBuf[6]=0x31; TimeBuf[7] =0x4c;
TimeBuf[8]=0; TimeBuf[9]=0x01;
TimeBuf[10]=Rtus[RtuNo].Addr;
TimeBuf[11]=CDT_CheckCRC(&TimeBuf[6]);
GetLocalTime(&Rtus[RtuNo].CDT_CallUpSysTime);
if (Channels[i].WorkType != 1)
{
MoxaBufWrite(i,(char*)TimeBuf,12);
}
}
if (Rtus[RtuNo].RecBuf[NonceInfoWord+1] & 0x2)
{
}
break;
}
}
void CDT_Send(int i,int RtuNo)
{
//复归 Add by yzw 2001.7.18
if (Rtus[RtuNo].bRet)
{
Rtus[RtuNo].bRet = false;
BYTE *RetFrame = &Rtus[RtuNo].TXBuf[Rtus[RtuNo].TXBufPtr];
for (int l=0;l<6;l++) RetFrame[l] = Rtus[RtuNo].SynWord[l+1];
RetFrame[6] = 0x31;
RetFrame[7] = 0x3d;
RetFrame[8] = 0x00;
RetFrame[9] = 0x01;
RetFrame[10] = Rtus[RtuNo].Addr;
RetFrame[11] = CDT_CheckCRC(&RetFrame[6]);
Rtus[RtuNo].TXBufPtr += 12;
}
/////////////////////////////////////
//遥控,升降执行.预制.撤消命令
else if (Channels[i].ChStatus & 0x100)
{
BYTE *YKSendFrame = &Rtus[RtuNo].TXBuf[Rtus[RtuNo].TXBufPtr];
for (int l=0;l<6;l++) YKSendFrame[l] = Rtus[RtuNo].SynWord[l+1];
YKSendFrame[6] = 0x71;
YKSendFrame[8]=3;
YKSendFrame[9]=0x01;
YKSendFrame[10]=Rtus[RtuNo].Addr;
switch(YKReserved[0])
{
case 0x11:
YKSendFrame[7] = 0x61;
YKSendFrame[12] = 0xe0;
YKSendFrame[13] = YKReserved[7];
break;
case 0x22:
YKSendFrame[7] = 0xc2;
YKSendFrame[12] = 0xe2;
YKSendFrame[13] = 0xaa;
break;
case 0x33:
YKSendFrame[7] = 0xb3;
YKSendFrame[12] = 0xe3;
YKSendFrame[13] = 0x55;
break;
}
Channels[i].ChStatus &= 0xfeff;
YKSendFrame[11] = CDT_CheckCRC(&YKSendFrame[6]);
YKSendFrame[14] = (YKReserved[7]==0x33)?YKReserved[3] : YKReserved[4];
YKSendFrame[15] = YKSendFrame[13];
YKSendFrame[16] = YKSendFrame[14];
YKSendFrame[17] = CDT_CheckCRC(&YKSendFrame[12]);
for(int k=0;k<12;k++) YKSendFrame[18+k]=YKSendFrame[12+k%6];
Rtus[RtuNo].TXBufPtr += 30;
}
else if (Channels[i].ReviseTimeFlag & 0x08)//广播,整点进行
{
WORD *TXBuf= (WORD*)&(Rtus[RtuNo].TXBuf[Rtus[RtuNo].TXBufPtr]);
BYTE *TimeBufSyn = (BYTE *)TXBuf;
for (int l=0;l<6;l++) TimeBufSyn[l] = Rtus[RtuNo].SynWord[l+1];
*(TXBuf+3)=0x9e21;
*(TXBuf+4)=0x0100;
*(TXBuf+5)=0xff;
*(TXBuf+5)+=CDT_CheckCRC((BYTE*)(TXBuf+3))*256;
Rtus[RtuNo].TXBufPtr+=12;
Channels[i].ReviseTimeFlag &= 0xf7;
}
else if (Channels[i].ReviseTimeFlag & 0x02)//召唤子站时钟,13分钟一次
{
WORD *TimeBuf = (WORD*)&Rtus[RtuNo].TXBuf[Rtus[RtuNo].TXBufPtr];
BYTE *TimeBufSyn = (BYTE*)TimeBuf;
// CDT_SetRtuTime(i,RtuNo);
for (int l=0;l<6;l++) TimeBufSyn[l] = Rtus[RtuNo].SynWord[l+1];
TimeBuf[3]=0x4c31;
TimeBuf[4]=0x0100;
TimeBuf[5]=Rtus[RtuNo].Addr;
TimeBuf[5] += CDT_CheckCRC((BYTE*)&TimeBuf[3])*256;
GetLocalTime(&Rtus[RtuNo].CDT_CallUpSysTime);
Rtus[RtuNo].TXBufPtr += 12;
Channels[i].ReviseTimeFlag &= 0xfd;
}
else if (Channels[i].ReviseTimeFlag & 0x04)//设置子站时钟,10 分钟一次
{
SYSTEMTIME SysTime;
GetLocalTime(&SysTime);
BYTE *TXBuf= &(Rtus[RtuNo].TXBuf[Rtus[RtuNo].TXBufPtr]);
for (int l=0;l<6;l++) TXBuf[l] = Rtus[RtuNo].SynWord[l+1];
TXBuf[6] = 0x71; TXBuf[7] = 0x7a;
TXBuf[8] = 2; TXBuf[9] = 0x01;
TXBuf[10] = Rtus[RtuNo].Addr;
TXBuf[11] = CDT_CheckCRC(TXBuf+6);
TXBuf[12]=0xee;
TXBuf[13]=SysTime.wMilliseconds%256;
TXBuf[14]=SysTime.wMilliseconds/256;
TXBuf[15]=(BYTE)SysTime.wSecond;
TXBuf[16]=(BYTE)SysTime.wMinute;
TXBuf[17] =CDT_CheckCRC(TXBuf+12);
TXBuf[18]=0xef;
TXBuf[19]=(BYTE)SysTime.wHour;
TXBuf[20]=(BYTE)SysTime.wDay;
TXBuf[21]=(BYTE)SysTime.wMonth;
TXBuf[22]=SysTime.wYear%100;
TXBuf[23] =CDT_CheckCRC(TXBuf+18);
Rtus[RtuNo].TXBufPtr+=24;
Channels[i].ReviseTimeFlag &= 0xfb;
// return;
}
// 设定命令
/* if (Channels[i].WorkType == 5)//通道测试
{
if ((Rtus[RtuNo].TXBufPtr<6) && (Channels[i].ReviseTimeFlag & 16))
{
BYTE *TXBuf= (BYTE*)&Rtus[RtuNo].TXBuf[Rtus[RtuNo].TXBufPtr];
for (int l=0;l<6;l++) TXBuf[l] = Rtus[RtuNo].SynWord[l+1];
Rtus[RtuNo].TXBufPtr +=6;
Channels[i].ReviseTimeFlag &= 0xef;
}
}*/
if (Rtus[RtuNo].TXBufPtr)
{
if (Channels[i].WorkType == 1) //旁听
{
Rtus[RtuNo].TXBufPtr = 0;
return;
}
Rtus[RtuNo].TXLen=Rtus[RtuNo].TXBufPtr;
Rtus[RtuNo].bSendCanDisp=TRUE;
MoxaBufWrite(i,(char*)&Rtus[RtuNo].TXBuf[0],Rtus[RtuNo].TXBufPtr);
Rtus[RtuNo].TXBufPtr=0;
}
}
void CDT_YK_SJ_Pro(int i,int RtuNo,int &NonceInfoWord)
{
BYTE *RecBuf = Rtus[RtuNo].RecBuf;
if (RtuNo != *((WORD*)(YKReserved+1))) return;
if ((RecBuf[NonceInfoWord+1]==RecBuf[NonceInfoWord+3]) && (RecBuf[NonceInfoWord+1]==YKReserved[7])
&& (RecBuf[NonceInfoWord+1]!=0xff))
YKEcho[RtuNo][1] = YKReserved[7];
else
YKEcho[RtuNo][1] = 0xff;
YKEchoFlag[RtuNo]=1;
/* if (RecBuf[NonceInfoWord+1] == 0xcc)
YKReserved[4] = RecBuf[NonceInfoWord+2];
else
YKReserved[3] = RecBuf[NonceInfoWord+2];*/
for (int k=0;k<2;k++)
{
if ((NonceInfoWord+6) >= Rtus[RtuNo].RecBufPtr) break;
for (int j=0;j<6;j++)
if (RecBuf[NonceInfoWord+6+j] != RecBuf[NonceInfoWord+j]) break;
if (j>=6) NonceInfoWord +=6;
else break;
}
}
void CDT_SetRtuTime(int i,int RtuNo)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -