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

📄 processcdt91rec.cpp

📁 这是一个变电站的监控程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include "fert2000.h"
#include "process.h"
#include "math.h"
#include "fert2000Dlg.h"

extern bool bStopFlag;
extern RecSendThread RecSendThread1;
extern  CFert2000App theApp;
extern CFert2000Dlg *MainDlg;
extern ADDR *Addr;
extern unsigned char TBCH0[];   
extern ADDR *Addr;
extern BYTE bSynWord[6];

//////////////////////////////////////////////
void CDT91_RECEIVE(int i,int iRtuNo)
{
    if (CDT91_Rec(i,iRtuNo))
	{
		CDT91_Protocol(i,iRtuNo);
	}
	CDT91_Send(i,iRtuNo);
}

bool CDT91_Rec(int i,int iRtuNo)
{
    int iStatus=3;
	BYTE Temp;
	DWORD num=0;
	CHANPARA *chanpara = Addr->ChanPara_addr + i;
	//read data
	BYTE RecBuf[1024];
	if (chanpara->Start < 0 || chanpara->Start >= 1024) chanpara->Start = 0;
	if (chanpara->End < 0 || chanpara->End >= 1024) 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);
    Sleep(10);
	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,iStatus);
				break;			
			}
		}
		chanpara->SynstrCount = SynstrCount;
		return false;
	}

	InLen=ChanBufIqueue(i);
	if (SynstrCount==6)
	{
		if (InLen<6) 
			return false;
		ChanBufDataGet(i,chanpara->FileHead ,6);
		BYTE *buf = chanpara->FileHead ;
		if (buf[0]==bSynWord[0] && buf[1]==bSynWord[1] && buf[2] == bSynWord[2] &&
			buf[3]==bSynWord[3] && buf[4]==bSynWord[4] && buf[5] == bSynWord[5])//the second synword
		{
			chanpara->SynstrCount = 6;
//			DispBufData(i,255,1,bSynWord,6,iStatus);
			return false;
		}
		else 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,iStatus);
		}
	}
	else 
		return false;
	return true;
}

void CDT91_Protocol(int i,int iRtuNo)
{
	int NonceInfoWord = 0;
    CHANPARA *chanpara = Addr->ChanPara_addr + i;
	RTUPARA *rtupara = GetRtuParaPt(Addr,iRtuNo);
    if (!rtupara) 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*2+j]=-YcValue;
				}
				else
				{
					YcValue = YcValue & 0x7ff;
					rtupara->YcValue[InfoCode*2+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>=0xa0 && InfoCode<=0xdf)//电能KWH
		{
			if (!(RecBuf[NonceInfoWord+4] & 0x80))//有效
			{
				DWORD KWHValue = 0;
				if ((RecBuf[NonceInfoWord+4] & 0x20) == 0)//二进制 
				{
					KWHValue = RecBuf[NonceInfoWord+1] + RecBuf[NonceInfoWord+2] * 256 
						+ RecBuf[NonceInfoWord+3] * 256 * 256;
				}
				else//bcd 字节内用BCD,字节间用二进制
				{
					BYTE *t = &RecBuf[NonceInfoWord+1];
					KWHValue = ((t[2] & 0xf0)/16*10 + t[2] & 0x0f)*256*256 
						+ ((t[1] & 0xf0)/16*10 + t[1] & 0x0f)*256 + ((t[0] & 0xf0)/16*10 + t[0] & 0x0f);
				}
				rtupara->KwhValue[InfoCode-0xa0]=KWHValue;

			}
		}
		else if ((InfoCode>=0x8d) && (InfoCode<=0x92))//水位
		{
			float WaterValue;
		
			WaterValue =(float)((RecBuf[NonceInfoWord+1] & 0xf)/100.0);
			WaterValue +=(float)((RecBuf[NonceInfoWord+1]>>4)/10.0);
			WaterValue +=(float)(RecBuf[NonceInfoWord+2] & 0xf);
			WaterValue +=(float)((RecBuf[NonceInfoWord+2]>>4)*10.0);
			WaterValue +=(float)((RecBuf[NonceInfoWord+3] & 0xf)*100.0);
			WaterValue +=(float)((RecBuf[NonceInfoWord+3]>>4)*1000.0);
			rtupara->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)((RecBuf[NonceInfoWord+k*2+1] & 0xf)/100.0);
				Freq +=(float)((RecBuf[NonceInfoWord+k*2+1]>>4)/10.0);
				Freq +=(float)(RecBuf[NonceInfoWord+k*2+2] & 0xf);
				Freq +=(float)((RecBuf[NonceInfoWord+k*2+2]>>4)*10.0);
                rtupara->Freq[k] = Freq;
			}
		}
        else 
			CDT91Rec_Answer(i,iRtuNo,NonceInfoWord);//SOE 子站时钟返送 子站状态信息,遥控返校 升降返校
	}
    if (RecBuf[0] == 0x71 && RecBuf[1] == 0xf4)//收到遥信报文
	{
		if (rtupara->RecFullYx == 255)
			rtupara->RecFullYx = 0;
		else if (rtupara->RecFullYx == 0)
			rtupara->RecFullYx = 1;
	}	
}

void CDT91_Send(int i,int iRtuNo)
{   
	int iStatus=2;
	int Sendlen=0;
	STATION *station = Addr->Station_addr;
	CHANPARA *chanpara = Addr->ChanPara_addr + i;
	RTUPARA *rtupara = GetRtuParaPt(Addr,iRtuNo);
	if (!rtupara) return;
	BYTE *SendBuf = & chanpara->SendBuffer[0];

    //遥控,升降执行.预制.撤消命令 
    if(rtupara->CommandSendFlag[8]==true || rtupara->CommandSendFlag[9]==true)
	{   
	    for (int l=0;l<6;l++) SendBuf[l] = bSynWord[l];
	    Sendlen=6;	
		if (rtupara->CommandSendFlag[8] == true)
		{
			rtupara->CommandSendFlag[8] = false;
			if (rtupara->SetCommand[1] != YK) return;
		}
		else
		{
			rtupara->CommandSendFlag[9] = false;
			if (rtupara->SetCommand[1] != YT) return;
		}
        SendBuf[6] = 0x71;//控制字节			
		SendBuf[8]=3;
		SendBuf[9]=0x01;
		SendBuf[10]=rtupara->rtuaddr;//目的站址
		switch(rtupara->SetCommand[2])
		{
		case 0x11:
			SendBuf[7]  = 0x61;//帧类别遥控选择
			SendBuf[12] = 0xe0;//信息字功能码
			SendBuf[13] = rtupara->SetCommand[4];//遥控操作码
			break;
		case 0x22:
			SendBuf[7] = 0xc2;//执行
			SendBuf[12] = 0xe2;
			SendBuf[13] = 0xaa;
			rtupara->SetCommand[1] = 255;
			break;
		case 0x33:
			SendBuf[7] = 0xb3;//撤消
			SendBuf[12] = 0xe3;
			SendBuf[13] = 0x55;
			rtupara->SetCommand[1] = 255;
			break;
		}				
        SendBuf[11] = CDT_CheckCRC(&SendBuf[6]);
		SendBuf[14] = rtupara->SetCommand[6];//遥控对象号
		SendBuf[15] = SendBuf[13];//重复
		SendBuf[16] = SendBuf[14];
		SendBuf[17] = CDT_CheckCRC(&SendBuf[12]);
		for(int k=0;k<12;k++) SendBuf[18+k]=SendBuf[12+k%6];//三个信息字相同
		Sendlen+=24;
        ChanBufWrite(i,SendBuf,Sendlen);
	    DispBufData(i,iRtuNo,0,SendBuf,Sendlen,iStatus);
	}

⌨️ 快捷键说明

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