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

📄 processdfdirect.cpp

📁 这是一个变电站的监控程序
💻 CPP
字号:
#include "stdafx.h"
#include "fert2000.h"
#include "process.h"

extern bool bStopFlag;
extern RecSendThread RecSendThread1;
extern unsigned char TBCH0[];   
extern  CFert2000App theApp;

extern ADDR *Addr;

extern BYTE bSynWord[6];


void DFDirect(int i,int RtuNo)
{
	if (DFDirect_Rec(i,RtuNo))
		DFDirect_Protocol(i,RtuNo);
	DFDirect_Send(i,RtuNo);
}


bool DFDirect_Rec(int i,int RtuNo)
{
	BYTE Temp;
	DWORD num=0;
	CHANPARA *chanpara = Addr->ChanPara_addr + i;
	//read data
	BYTE RecBuf[1024];
	Sleep(10);
	if (chanpara->Start >= 1024 || chanpara->Start < 0) chanpara->Start = 0;
	if (chanpara->End >= 1024 || chanpara->End < 0) chanpara->End = 0;

	if (((chanpara->Start - chanpara->End + 1024 -1)%1024) == 0)
		chanpara->Start = chanpara->End;
	int iRet = ChanBufRead(i,RecBuf,(chanpara->Start - chanpara->End + 1024 - 1)%1024);
	BYTE * ChanRecBuf = &chanpara->RecBuffer[0];
	WORD ChanEnd = chanpara->End;
	for (int j=0;j<iRet;j++)
	{
		ChanRecBuf[ChanEnd++] = RecBuf[j];
		if (ChanEnd >= 1024) ChanEnd = 0;
	}
	chanpara->End = ChanEnd;
	///////////////////////////
	int SynstrCount = chanpara->SynstrCount;
	int InLen = ChanBufIqueue(i);
	if (InLen<6) return false;
	if ((SynstrCount<6) && !(chanpara->ChStatus & 0x2000))//同步字个数小于6,并且不是第一个信息字
	{
		for (int j=0;j<InLen;j++)
		{
			ChanBufDataGet(i,&Temp,1);
			if(Temp == bSynWord[SynstrCount]) 
				SynstrCount++; 
			else 
				SynstrCount = 0;
			if (SynstrCount==6) 
			{
				DispBufData(i,255,1,bSynWord,6,0);
				break;			
			}
		}
		chanpara->SynstrCount = SynstrCount;
		return false;
	}

	InLen=ChanBufIqueue(i);
	if (SynstrCount==6)
	{
		if (InLen<6) return false;
		ChanBufDataGet(i,chanpara->FileHead ,6);
		if (chanpara->FileHead[5] != CDT_CheckCRC(chanpara->FileHead))
		{
            chanpara->SynstrCount = 0;
			return false;
		}
		chanpara->SynstrCount = 0;
		InLen -= 6;
		chanpara->ChStatus |= 0x2000;
	}

	if (chanpara->ChStatus & 0x2000) 
	{
		int Lenth = chanpara->FileHead[2] * 6;
		if (InLen < Lenth && Lenth != 0) 
			return false;
		else
		{
			for (int j = 0;j < 6;j++)
				chanpara->ProcBuffer[j] = chanpara->FileHead [j];
			ChanBufDataGet(i,&chanpara->ProcBuffer[6],Lenth);
			chanpara->SynstrCount = 0;
			chanpara->ChStatus &= 0xdfff;
			DispBufData(i,255,1,chanpara->ProcBuffer,6+Lenth,0);
		}
	}
	else 
		return false;
	return true;
}



void DFDirect_Protocol(int i,int RtuNo)  
{
	int NonceInfoWord = 0;
	CHANPARA *chanpara = Addr->ChanPara_addr + i;
	RTUPARA *rtupara = GetRtuParaPt(Addr,RtuNo);
	if (rtupara == NULL) return;
	BYTE* RecBuf=&(chanpara->ProcBuffer[0]);
	int iLen = RecBuf[2] * 6;
	for (NonceInfoWord=6;NonceInfoWord < iLen+6;NonceInfoWord +=6)//以信息字为单位,一个一个处理
	{
		int InfoCode=RecBuf[NonceInfoWord];//功能码

		if (CDT_CheckCRC(&RecBuf[NonceInfoWord])!=RecBuf[NonceInfoWord+5])//校验不对
			continue;
		if ((InfoCode>=0)&&(InfoCode<=0x7f))//遥测,功能码在遥测定义起始码和7F之间
		{
			for (int j=0;j<2;j++)
			{
				WORD YcValue;
				YcValue = RecBuf[NonceInfoWord+j*2+1] + RecBuf[NonceInfoWord+j*2+2]*256;
				WORD YcSign = 0x800;//遥测符号位:11
				if ((YcValue & 0x8000) || (YcValue & 0x4000)) continue;//遥测溢出或者无效
				if (YcValue & YcSign)//遥测为负数 
				{
					YcValue &= 0x7ff;
					YcValue = 0x7ff + 1 - YcValue;
					rtupara->YcValue[InfoCode+j]=-YcValue;
				}
				else
				{
					YcValue = YcValue & 0x7ff;
					rtupara->YcValue[InfoCode+j]=YcValue;
				}
			}
		}
		else if ((InfoCode>=0xf0) && (InfoCode<=0xff))//遥信
		{
			int iPosition = InfoCode - 0xf0;//第几组谣信已收到
			int YxDWordPtr = InfoCode-0xf0;
			int YxValuePtr=YxDWordPtr*32;	
			DWORD YxWord=*(DWORD*)&RecBuf[NonceInfoWord+1];
			BYTE State=0;
			for (int k=0;k<32;k++)
			{
				State = (YxWord & (1<<k)) ? 1 : 0;
				if (rtupara->YxValue[YxValuePtr+k] != State)
					rtupara->YxValue[YxValuePtr+k] = State;
			}
		}
		else if (InfoCode == 0x80)//soe
		{
			NonceInfoWord  += 30;
			if (RecBuf[11] == CDT_CheckCRC(RecBuf + 6))
			{
				WORD MilliSeconds;
				FERTEVENT Event;
				SYSTEMTIME CurTime;
				GetLocalTime(&CurTime);

				MilliSeconds=RecBuf[1] + (RecBuf[2] & 0x03)*256;
				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;
				Event.month = (BYTE)CurTime.wMonth;
				Event.year = CurTime.wYear;

				Event.Recms = CurTime.wMilliseconds % 100;
				Event.Rechundms = CurTime.wMilliseconds/100;
				Event.Recseconds = (BYTE)CurTime.wSecond;
				Event.Recminute = (BYTE)CurTime.wMinute;
				Event.Rechour = (BYTE)CurTime.wHour;
				Event.Recday = (BYTE)CurTime.wDay;

				Event.rtuno = RtuNo;
				Event.yxno = RecBuf[9] + (RecBuf[10] & 0xf)*256;
				Event.cause = 1;
				Event.type = 1;
				Event.state = (RecBuf[10] & 0x80) ? 1 : 0;
				
				GenRtuEvent(Addr,RecSendThread1.g_hSCADAToMMIEvent,&Event);
				STATION *station = Addr->Station_addr;
				for (int k = 0;k < station->yxnum;k++)//判断是否存在此遥信
				{
					YXPARA *yxpara = Addr->YxPara_addr + k;
					if (!yxpara->validf)
						continue;
					if (yxpara->rtuno == RtuNo && yxpara->yxno == Event.yxno)
						break;
				}
				if (k == station->yxnum) 
					return;
				int iRealYxNo = k;
				for (k = 0;k < station->zyxnum;k++)//判断是否转发
				{
					ZFYXPARA *zfyxpara = Addr->ZfYxPara_addr + k;
					if (!zfyxpara->validf)
						continue;
					CString str1 = zfyxpara->yxname;
					WORD tYxNo = (WORD)atoi(str1.Right(5));
					if (tYxNo == iRealYxNo)
						break;
				}
				if (k == station->zyxnum)
					return;
				for (int j = 0;j < station->channum ;j++)//产生上传SOE,遥信变位
				{
					CHANPARA *chanpara = Addr->ChanPara_addr + j;
					if (chanpara->useflag && chanpara->openflag && chanpara->updown == 0)
					{
						chanpara->SoeEvent[chanpara->SoePtr].YxNo = k;
						chanpara->SoeEvent[chanpara->SoePtr].YxState = (Event.state & 0x1);
					    chanpara->SoeEvent[chanpara->SoePtr].SoeTime.wYear = Event.year ;
						chanpara->SoeEvent[chanpara->SoePtr].SoeTime.wMonth = Event.month ;
						chanpara->SoeEvent[chanpara->SoePtr].SoeTime.wDay = Event.day ;
						chanpara->SoeEvent[chanpara->SoePtr].SoeTime.wHour = Event.hour ;
						chanpara->SoeEvent[chanpara->SoePtr].SoeTime.wMinute = Event.minute ;
						chanpara->SoeEvent[chanpara->SoePtr].SoeTime.wSecond = Event.seconds;
						chanpara->SoeEvent[chanpara->SoePtr].SoeTime.wMilliseconds = Event.hundms * 100 + Event.ms;
						chanpara->SoePtr = (chanpara->SoePtr+1) % 100;
						chanpara->bYxChange = true;
						chanpara->bYxwChange[k/32] = true;
						chanpara->bSoe = true;
					}
				}
			}
		}
	}	
	if (RecBuf[0] == 0x71 && RecBuf[1] == 0xf4)//收到遥信报文
	{
		if (rtupara->RecFullYx == 255)
			rtupara->RecFullYx = 0;
		else if (rtupara->RecFullYx == 0)
			rtupara->RecFullYx = 1;
	}
}										


void DFDirect_Send(int i,int RtuNo)
{
	CHANPARA *chanpara = Addr->ChanPara_addr + i;
	RTUPARA *rtupara = GetRtuParaPt(Addr,RtuNo);
	if (rtupara->CommandSendFlag[7] == true)
	{
		SYSTEMTIME SysTime;
		GetLocalTime(&SysTime);

		BYTE TXBuf[64];
		for (int l=0;l<6;l++) TXBuf[l] = bSynWord[l];
		TXBuf[6] = 0x71;	TXBuf[7] = 0x7a;
		TXBuf[8] = 2;		TXBuf[9] = 0x01;
		TXBuf[10] = rtupara->rtuaddr ;
		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);
		int iSendLen = 24;
		ChanBufWrite(i,TXBuf,iSendLen);
		DispBufData(i,RtuNo,0,TXBuf,iSendLen,0);
	}
}


⌨️ 快捷键说明

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