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

📄 processdcf.cpp

📁 这是一个变电站的监控程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////
// ProcessDCF.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 DCF_5(int i)
{
	BYTE RtuNo=Channels[i].ChRtuNo[0];
	if (!Rtus[RtuNo].Flag) return;
	if (DCF_Receive(i,RtuNo))
	{
		Rtus[RtuNo].bWorking=TRUE;
		Channels[i].bWorking=true;
		DCF_Protocol(i,RtuNo);
	}
	//Add by yzw 2000.12.20
	else
		Rtus[RtuNo].bWorking=FALSE;
	//Add by yzw 2000.12.20
	DCF_Send(i,RtuNo);
}

bool DCF_Receive(int ChNo,BYTE RtuNo)
{
	return CDT_Rec(ChNo,RtuNo);
}

void DCF_Protocol(int ChNo,int RtuNo)
{
	int NonceInfoWord;
	BYTE* RtuRecBuf=&(Rtus[RtuNo].RecBuf[0]);
	BYTE FrameType = Rtus[RtuNo].RecBuf[1];
//	bool bRecFullYx = false;
	if (Rtus[RtuNo].RecBuf [0] == 0x30 && Rtus[RtuNo].RecBuf [1] == 0x7A)//遥控等返校错误
	{
		int iRtuNo=(int)(*((WORD *)(YKReserved+1)));
		if (iRtuNo == RtuNo)
		{
			YKEcho[RtuNo][1] = 0xff;
			YKEchoFlag[RtuNo]=1;
		}
		return;
	}
	for (NonceInfoWord=6;NonceInfoWord < Rtus[RtuNo].RecBufPtr;NonceInfoWord +=6)
	{
		int InfoCode=RtuRecBuf[NonceInfoWord];

		if (DCF_CheckCRC(&RtuRecBuf[NonceInfoWord])!=RtuRecBuf[NonceInfoWord+5])
		{
			Rtus[Channels[ChNo].ChRtuNo[0]].ErrFrameSum++;
			continue;
		}

		if ((InfoCode >= Rtus[RtuNo].ProtocolStamp[0]) && (InfoCode <= 0x7f)) //遥测
		{
			float YcValue;
//			WORD YcModulus;
			for (int i =0; i<2; i++)
			{				
//				YcModulus = ((RtuRecBuf[NonceInfoWord + i*2+1] & 0x78)>>6) * 10;
				//如果符号为该字节最高位(第7位)指示,
				//则小数点位置应为该字节第6,5位表示,请徐工看源码考虑小数点和正负问题.			
				YcValue = (float)((RtuRecBuf[NonceInfoWord+i*2+2]) + (RtuRecBuf[NonceInfoWord+i*2+1] & 7) * 256); 
//				if (YcModulus) YcValue = (float)YcValue/YcModulus;
				if (RtuRecBuf[NonceInfoWord+i*2+1] & 0x80 /*0x40*/) YcValue = -YcValue;
				Rtus[RtuNo].YcValue[(InfoCode - Rtus[RtuNo].ProtocolStamp[0])*2 + i] = 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+((int)k/8 * 8)+(7-(k%8))] != State)
				{
					Rtus[RtuNo].YxValue[YxValuePtr+((int)k/8 * 8)+(7-(k%8))] = State;
					if (Rtus[RtuNo].RecFullYx & (1<<iPosition)) 
//					if (Rtus[RtuNo].RecFullYx == 1)
						YxEvent(RtuNo,YxValuePtr+((int)k/8 * 8)+(7-(k%8)),State);//生成变位遥信Event
				}
			}
			Rtus[RtuNo].RecFullYx |= (1<<iPosition);
//			bRecFullYx = true;
		}
		else if ((InfoCode >= Rtus[RtuNo].ProtocolStamp[2]) && (InfoCode <= 0xcf)) //电度
		{
			DWORD KwhValue = 0;
			KwhValue = (RtuRecBuf[NonceInfoWord+2]<<16) + (RtuRecBuf[NonceInfoWord+3]<<8) + RtuRecBuf[NonceInfoWord+4]; 
			Rtus[RtuNo].KwhValue[InfoCode - Rtus[RtuNo].ProtocolStamp[2]] = KwhValue;
		}else if ((InfoCode == 0xa1) || (InfoCode == 0xa2)) //水位
		{
			float WaterValue = 0;
			WaterValue = RtuRecBuf[NonceInfoWord+1]*256 + RtuRecBuf[NonceInfoWord+2]
				+ (float)(RtuRecBuf[NonceInfoWord+3]%10)/10 + (float)(RtuRecBuf[NonceInfoWord+4]%10)/100;
			Rtus[RtuNo].Water[InfoCode - 0xa1] = WaterValue;
		}else if (InfoCode == 0xa0) //频率
		{
			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 if ((InfoCode >= 0xd0) && (InfoCode <= 0xd8))//批次信息
		{
			//待处理;
		}else if ((InfoCode >= 0x80) && (InfoCode <= 0x9f))//SOE
		{
			DCF_SOE_Event(RtuNo,NonceInfoWord);
		}
		else 
			DCF_Answer(ChNo,RtuNo,NonceInfoWord);// 正确的遥控返校 厂站状态 对时
	}
	Rtus[RtuNo].RecBufPtr=0;
/*	if (Rtus[RtuNo].RecFullYx == 0)
	{
		if (bRecFullYx) Rtus[RtuNo].RecFullYx = 1;
	}*/
}

void DCF_Send(int ChNo,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] = DCF_CheckCRC(&RetFrame[6]);
		Rtus[RtuNo].TXBufPtr += 12;
	}
	//遥控,升降执行.预制.撤消命令 
	else if (Channels[ChNo].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] = 0x70;			
		YKSendFrame[8]=3;
		YKSendFrame[9]=0x01;
		YKSendFrame[10]=Rtus[RtuNo].Addr;
		switch(YKReserved[0])
		{
		case 0x11://预置
			YKSendFrame[7]  = 0x61;
			break;
		case 0x22://execute
			YKSendFrame[7] = 0xc2;
			break;
		case 0x33://cancel
			YKSendFrame[7] = 0xb3;
			break;
		}	
		if (YKReserved[11] == YK)
		{
			YKSendFrame[12] = 0xe0;
			YKSendFrame[18] = 0xe1;
			YKSendFrame[24] = 0xe2;
		}
		else if (YKReserved[11] == YT)
		{
			YKSendFrame[12] = 0xe9;
			YKSendFrame[18] = 0xea;
			YKSendFrame[24] = 0xeb;
		}
		YKSendFrame[13] = YKReserved[7];
		YKSendFrame[19] = YKReserved[7];
		YKSendFrame[25] = YKReserved[7];
		Channels[ChNo].ChStatus &= 0xfeff;
		int iTemp = YKReserved[4] * 256 + YKReserved[3];
		int iT1 = iTemp / 100;
		int iT2 = iTemp % 100;
		YKSendFrame[11] = DCF_CheckCRC(&YKSendFrame[6]);
		YKSendFrame[14] = 0;
		YKSendFrame[15] = iT2 / 10 * 16 + iT2 % 10;
		YKSendFrame[16] = iT1 / 10 * 16 + iT1 % 10;
		YKSendFrame[17] = DCF_CheckCRC(&YKSendFrame[12]);

		YKSendFrame[20] = 0;
		YKSendFrame[21] = iT2 / 10 * 16 + iT2 % 10;
		YKSendFrame[22] = iT1 / 10 * 16 + iT1 % 10;
		YKSendFrame[23] = DCF_CheckCRC(&YKSendFrame[18]);

		YKSendFrame[26] = 0;
		YKSendFrame[27] = iT2 / 10 * 16 + iT2 % 10;
		YKSendFrame[28] = iT1 / 10 * 16 + iT1 % 10;
		YKSendFrame[29] = DCF_CheckCRC(&YKSendFrame[24]);
		Rtus[RtuNo].TXBufPtr += 30;
	}
	else if (Channels[ChNo].ReviseTimeFlag & 0x02)//召唤子站时钟,13 分钟一次
	{
		BYTE *TimeBuf = &Rtus[RtuNo].TXBuf[Rtus[RtuNo].TXBufPtr];
		
		for (int l=0;l<6;l++) TimeBuf[l] = Rtus[RtuNo].SynWord[l+1];
		TimeBuf[6] = 0x30;	TimeBuf[7] = 0xa8;
		TimeBuf[8] = 0;		TimeBuf[9] = 0x01;
		TimeBuf[10] = Rtus[RtuNo].Addr;
		TimeBuf[11] = DCF_CheckCRC(TimeBuf+6);
		GetLocalTime(&Rtus[RtuNo].CDT_CallUpSysTime);
		Rtus[RtuNo].TXBufPtr += 12;
		Channels[ChNo].ReviseTimeFlag &= 0xfd;
	}
	else if (Channels[ChNo].ReviseTimeFlag & 0x08)//广播,整点进行
	{
		BYTE *TXBuf= &(Rtus[RtuNo].TXBuf[Rtus[RtuNo].TXBufPtr]);
		for (int l=0;l<6;l++) TXBuf[l] = Rtus[RtuNo].SynWord[l+1];
		TXBuf[6] = 0x30;	TXBuf[7] = 0x0b;
		TXBuf[8] = Rtus[RtuNo].Addr;		TXBuf[9] = 0x01;
		TXBuf[10] = 0;
		TXBuf[11] = DCF_CheckCRC(TXBuf+6);
		Rtus[RtuNo].TXBufPtr+=12;
		Channels[ChNo].ReviseTimeFlag &= 0xf7;
	}
	else if (Channels[ChNo].ReviseTimeFlag & 0x04)//设置子站时钟,10 分钟一次

⌨️ 快捷键说明

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