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

📄 processnzctd.cpp

📁 这是一个变电站的监控程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		NZ_CDT_ReviseTime(i,RtuNo,NonceInfoWord);
		break;
	case 0xe1:
	case 0xe5://遥控,升降返校
		NZ_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 NZ_CDT_Send(int i,int RtuNo)
{
	//复归 
	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]=0x03;
		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 NZ_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 if(RecBuf[NonceInfoWord+1]==0x33)
		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 NZ_CDT_SetRtuTime(int i,int RtuNo)
{
	SYSTEMTIME SysTime;
	WORD SetTimeFrame[12];
	BYTE *SetTimeFrameSyn = (BYTE *)SetTimeFrame;
	GetLocalTime(&SysTime);

	for (int l=0;l<6;l++) SetTimeFrameSyn[l] = Rtus[RtuNo].SynWord[l+1];
	SetTimeFrame[3]=0x7a71;  SetTimeFrame[4]=0x0102;
	SetTimeFrame[5]=(WORD)Rtus[RtuNo].Addr;
	SetTimeFrame[5] +=(WORD)(CDT_CheckCRC((BYTE*)&SetTimeFrame[3])*256);

	SetTimeFrame[6]=(SysTime.wMilliseconds%256)*256+0xee;
	SetTimeFrame[7] = 0;
	SetTimeFrame[7]=SysTime.wSecond*256+(SysTime.wMilliseconds>>8);
	SetTimeFrame[8]=SysTime.wMinute;
	SetTimeFrame[8] +=(WORD)(CDT_CheckCRC((BYTE*)&SetTimeFrame[6])*256);
	 
	SetTimeFrame[9]=SysTime.wHour*256+0xef;
	SetTimeFrame[10]=SysTime.wMonth*256+SysTime.wDay;
	SetTimeFrame[11]=SysTime.wYear%100;
	SetTimeFrame[11] += (WORD)(CDT_CheckCRC((BYTE*)&SetTimeFrame[9])*256);

	if (Channels[i].WorkType != 1) 
	{
		MoxaBufWrite(i,(char*)SetTimeFrame,24);
	}
}

BYTE NZ_CDT_CheckCRC(BYTE *pInfoWord)
{
//A=DS:[SI],[SI+1],[SI+2],[SI+3],[SI+4] => BL=BCH of (48,40) =mod(A*2**8,G)
//SI=SI+5 using the BCH table TBCH0. The G(X)=X**8 + X**2 + X + 1 = 107H

	BYTE ret = 0;
	for ( int i=0; i<5; i++ )
	{
		ret ^= *(pInfoWord+i);
		ret = TBCH0[ret];
	}
	return (ret^0xff);
}

void NZ_CDT_ReviseTime(int i,int RtuNo,int  NonceInfoWord)//设置时钟校正值
{
	BYTE *RecBuf = &Rtus[RtuNo].RecBuf[NonceInfoWord];
	if(Rtus[RtuNo].RecBuf[NonceInfoWord] == 0x84)//子站时钟反送 
	{
		GetLocalTime(&Rtus[RtuNo].CDT_CurTime);
		Rtus[RtuNo].CDT_ChildTime = RecBuf[1] + RecBuf[2]*256 + RecBuf[3]*1000 + RecBuf[4]*60000;//收到召唤命令的子站时间	
	}else
	{
		BYTE ReviseTimeFrame[18];
		WORD ReviseTimeWord;
		DWORD ChildWaitTime = RecBuf[1] + RecBuf[2]*256	+ RecBuf[3]*1000 + RecBuf[4]*60000;//子站等待时间	
		DWORD CurTime = Rtus[RtuNo].CDT_CurTime.wMilliseconds + Rtus[RtuNo].CDT_CurTime.wSecond * 1000//当前时间 
			+ Rtus[RtuNo].CDT_CurTime.wMinute * 6000;
		DWORD CallUpTime = Rtus[RtuNo].CDT_CallUpSysTime.wMilliseconds + Rtus[RtuNo].CDT_CallUpSysTime.wSecond * 1000
			+ Rtus[RtuNo].CDT_CallUpSysTime.wMinute * 6000;//召唤时钟的主站时间
		int ReviseTime = (CallUpTime+CurTime-ChildWaitTime)/2 - Rtus[RtuNo].CDT_ChildTime;

		for (int l=0;l<6;l++) ReviseTimeFrame[l] = Rtus[RtuNo].SynWord[l+1];
		if (ReviseTime<0)
		{
			ReviseTimeWord = (-ReviseTime) % 32512;// &0x7fff;
			ReviseTimeWord ^= 0x7fff;
			ReviseTimeWord ++;
			ReviseTimeWord |= 0x8000;
		}else
			ReviseTimeWord = ReviseTime % 32512;// &0X7fff
		*((DWORD*)&ReviseTimeFrame[6]) = 0x010b71;
		ReviseTimeFrame[10] = Rtus[RtuNo].Addr;
		ReviseTimeFrame[11] = CDT_CheckCRC(&ReviseTimeFrame[6]);

		ReviseTimeFrame[12] = 0xed;
		*((WORD*)&ReviseTimeFrame[13]) = ReviseTimeWord;
		*((WORD*)&ReviseTimeFrame[15]) = ReviseTimeWord;
		ReviseTimeFrame[17] = CDT_CheckCRC(&ReviseTimeFrame[12]);
		if (Channels[i].WorkType != 1)
		{
			MoxaBufWrite(i,(char *)ReviseTimeFrame,18);
		}
	}
}

void NZ_CDT_SOE_Event(int RtuNo,int &NonceInfoWord)//对南自:只有保护事件且报文格式不同于CDT
{
	WORD MilliSeconds;
	FERTEVENT Event;
	FERTEVENT *CurEventP;
	SYSTEMTIME CurTime;
	BYTE *RecBuf = &Rtus[RtuNo].RecBuf[NonceInfoWord];
	BYTE *SOEInfo = Rtus[RtuNo].CDT_SOEInfo;
	GetLocalTime(&CurTime);

	if (RecBuf[11] != CDT_CheckCRC(RecBuf + 6))
	{
		NonceInfoWord +=6;
		return;
	}
	if ((RecBuf[9] == SOEInfo[0]) && ((RecBuf[10]&0x8f) == (SOEInfo[1]&0x8f)) 
		&& (RecBuf[1] == SOEInfo[2]) && (RecBuf[2] == SOEInfo[3]) && (RecBuf[3] == SOEInfo[4]))
	{
		NonceInfoWord += 6;
		return;
	}
	if((Events.EventNum+1)==Events.EventSendNum)
	{
		Beep(1200,500);
		NonceInfoWord += 6;
		return;
	}
	MilliSeconds=RecBuf[1] + (RecBuf[2] & 0x03)*256;
	
	if (Rtus[RtuNo].TimeForbit == 1)
	{
		Event.ms = CurTime.wMilliseconds % 100;
		Event.hundms = CurTime.wMilliseconds / 100;
		Event.seconds = (BYTE)CurTime.wSecond;
		Event.minute = (BYTE)CurTime.wMinute;
		Event.hour = (BYTE)CurTime.wHour;
		Event.day = (BYTE)CurTime.wDay;
	}else
	{
		Event.ms = MilliSeconds % 100;
		Event.hundms = MilliSeconds / 100;
		Event.seconds = RecBuf[3] & 0x3f;
		Event.minute = RecBuf[4] & 0x3f;
		Event.hour = RecBuf[7] & 0x1f;
		Event.day = RecBuf[8] & 0x1f;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -