⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 processcdt.cpp

📁 这是一个变电站的监控程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////
// 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 + -