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

📄 processsc1801.cpp

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

//////////////////////////////////////////////////////////////////////////
//SC1801 protocol

void SC1801(int ChNo)
{
	int	RecRtuNo = 0;

	if (Channels[ChNo].CurSendRtuNo == -1)
	{
		for (int j=0;j<Channels[ChNo].ChRtuNum;j++) 
			if (Rtus[Channels[ChNo].ChRtuNo[j]].Flag) break;
		if (j<Channels[ChNo].ChRtuNum) Channels[ChNo].CurSendRtuNo = j;
	}
	else 
		SC_Send(ChNo);
			
	if(SC_Receive(ChNo,&RecRtuNo))
	{
		Rtus[RecRtuNo].bWorking = TRUE;
		Channels[ChNo].bWorking = true;
		SC_Protocol(ChNo,RecRtuNo);
	}
	//Add by yzw 2000.12.20
	else
		Rtus[RecRtuNo].bWorking=FALSE;
	//Add by yzw 2000.12.20
}



bool SC_Receive(int ChanNo,int *RtuNo)
{
	BYTE RecBuf[1024];
	char	Temp[2048];
	int Lenth;
	*RtuNo=-1;
 	int iNum = MoxaBufIqueue(ChanNo);
	if (Channels[ChanNo].ChStatus & 0x400)//接受到一桢
	{
		Lenth=Channels[ChanNo].FileHead[2]* 256 + Channels[ChanNo].FileHead[3];
		if (iNum<(Lenth+1)) 
			return false;
		for (int k=0;k<4;k++)// RecBuf[k]=Rtus[Channels[ChanNo].ChRtuNo[0]].RecBuf[k];
			RecBuf[k]=Channels[ChanNo].FileHead[k];
		Channels[ChanNo].ChStatus &= 0xfbff;
	}
	else
	{
		BYTE *FileHead = &Channels[ChanNo].FileHead[0];
		if (Channels[ChanNo].WorkType == 0)//前置机
		{
			if (iNum < 5)
				return false;
			if (iNum >1000)
			{
				MoxaBufRead(ChanNo,(BYTE*)&Temp[0],2000);
				return false;
			}
			MoxaBufRead(ChanNo,(BYTE*)RecBuf,4);
			Lenth = RecBuf[2]*256 + RecBuf[3];
			if (Lenth>500) 
			{
				MoxaBufRead (ChanNo,(BYTE *)&Temp[0],2048);
				return false;
			}
			if (iNum<(Lenth+5)) 
			{
				Channels[ChanNo].ChStatus |= 0x400;	
				for (int k=0;k<4;k++)
					Channels[ChanNo].FileHead[k]=RecBuf[k];
				return false;
			}
		}
		else if (Channels[ChanNo].WorkType == 1)//旁听
		{
			int j = 0;
			if (!(Channels[ChanNo].ChStatus & 0x2000))
			{
				if (iNum < 5 )
					return false;
				else if (iNum > 1000)
				{
					MoxaBufRead(ChanNo,(BYTE*)&Temp[0],2000);
					return false;
				}
				MoxaBufRead(ChanNo,FileHead,2);
				j=2;
			}
				
			bool Ok = false;
			while(j < (iNum-1))//留最后一个;
			{
				MoxaBufRead(ChanNo,(FileHead + 2),1);
				j++;
				for (int k=0;k < Channels[ChanNo].ChRtuNum;k++)
				{
					if (FileHead[0] == Rtus[Channels[ChanNo].ChRtuNo[k]].Addr) break;
				}
				if ((k < Channels[ChanNo].ChRtuNum) && (FileHead[1] & 0x40) && (FileHead[2] <= 3)
					&& ((FileHead[1] & 0x3f) <= 0x1f))//Notes: 未考虑挂葫芦
				{
					Ok = true;
					break;
				}
				else
				{
					FileHead[0] = FileHead[1];
					FileHead[1] = FileHead[2];
				}
			}
			if (Ok)
			{
				Channels[ChanNo].ChStatus &= 0xdfff;
				MoxaBufRead(ChanNo,(FileHead+3),1);
			}else 
			{
				Channels[ChanNo].ChStatus |= 0x2000;
				return false;
			}
			iNum = MoxaBufIqueue(ChanNo);
			Lenth = FileHead[2]*256 + FileHead[3];
			if (iNum<(Lenth+1)) 
			{
				Channels[ChanNo].ChStatus |= 0x400;	
				return false;
			}
			for (int k=0;k<4;k++)
				RecBuf[k] = FileHead[k];
		}
	}

	Channels[ChanNo].ChStatus &= 0xfbff;
	MoxaBufRead(ChanNo,&RecBuf[4],Lenth+1);
	MoxaBufRead(ChanNo,(BYTE*)&Temp[0],2048);//清通道 buffer
	Rtus[Channels[ChanNo].ChRtuNo[Channels[ChanNo].CurSendRtuNo]].RecFrameSum ++;
	BYTE iLpc = 0xff;
	for(int i=0;i<Lenth + 4;i++)//LPC校验
		iLpc ^= RecBuf[i];
	if (iLpc != RecBuf[Lenth + 4])
	{
		Rtus[Channels[ChanNo].ChRtuNo[Channels[ChanNo].CurSendRtuNo]].ErrFrameSum ++;
		return false;
	} 
    
	for (int j = 0;j < Channels[ChanNo].ChRtuNum;j++)
	{
		BYTE RtuAddr = Rtus[Channels[ChanNo].ChRtuNo[j]].Addr;
		if (RecBuf[0] == RtuAddr)
		{
			*RtuNo = Channels[ChanNo].ChRtuNo[j];
			break;
		}
	}
    if (*RtuNo==-1)
		return false;
	for ( i = 0;i <5+Lenth;i++)
		Rtus[*RtuNo].RecBuf[i] = RecBuf[i];
	Rtus[*RtuNo].RecLen = Lenth+5;
	Rtus[*RtuNo].bReceiveCanDisp = TRUE;	
	return true;	
}



void SC_Protocol(int ChNo,int RtuNo)
{

	BYTE* RtuRecBuf=&(Rtus[RtuNo].RecBuf[0]);	
	WORD ByteLen=RtuRecBuf[3]+RtuRecBuf[2]*256;
	int i;
	bool bSaveFrame = true;
	//int YxNo;		
	BYTE BrandNo;
	WORD KwhNum=0,YcNum=0,YxNum=0;

//	Rtus[RtuNo].CommandSendFlag[RtuRecBuf[1] & 0x3f]=0;
	switch (RtuRecBuf[1]&0x3f)
	{
	case 0x0://NAK		 
		SC_RtuState(RtuRecBuf[4],RtuNo);
		break;
	case 0x1://RRC 配置
		SC_RtuState(RtuRecBuf[4],RtuNo);
		for (i=0;i<16;i++) Rtus[RtuNo].RRC[i]=RtuRecBuf[i+5];
		for (i=0;i<16;i++)
		{
			switch(RtuRecBuf[i+5])
			{
			case 0x32:
				YcNum +=12;
				break;
			case 0x11:
				YxNum +=24;
				break;
			case 0x3b:
				KwhNum +=8;
			}
		}
		Rtus[RtuNo].YxwNum = (Rtus[RtuNo].YxNum+15)/16;
		Rtus[RtuNo].KwhNum=KwhNum;
		Rtus[RtuNo].YcNum=YcNum;
		Rtus[RtuNo].YxNum=YxNum;
		break;
	case 0x2://DRF 全数据
		SC_RtuState(RtuRecBuf[4],RtuNo);
		if ((RtuRecBuf[5] & 0xc0) == 0x40)//yc
		{
			BYTE *RtuRecBufYx;
			BYTE State=0;
			WORD YcNum=Rtus[RtuNo].YcNum;

			for (i=0;i<YcNum;i++)
			{
				Rtus[RtuNo].YcValue[i]=(float)RtuRecBuf[5+i*2+1] + (RtuRecBuf[5+i*2] &0xf)*256;
			}
			RtuRecBufYx=&RtuRecBuf[5+YcNum*2];
			for (i=0;i<Rtus[RtuNo].YxNum;i++)
			{
				State = (RtuRecBufYx[(int)i/6] & (1<<i%6))?1:0;
				if(Rtus[RtuNo].YxValue[i] != State)
				{
					Rtus[RtuNo].YxValue[i] = State;
					if (Rtus[RtuNo].RecFullYx == 1) YxEvent(RtuNo,i,State);
				}
			}
		}else if ((RtuRecBuf[5] & 0xc0) == 0x80)//yx
		{
			BYTE *RtuRecBufYc;
			BYTE State=0;
			WORD YxNum=Rtus[RtuNo].YxNum;
			
			for (i=0;i<YxNum;i++)
			{
				State = (RtuRecBuf[5+(int)i/6] & (1<<i%6))?1:0;
				if (Rtus[RtuNo].YxValue[i] != State)
				{
					Rtus[RtuNo].YxValue[i] = State;
					if (Rtus[RtuNo].RecFullYx == 1) YxEvent(RtuNo,i,State);
				}				
			}
			RtuRecBufYc=&RtuRecBuf[5+YxNum/6];
			for (i=0;i<Rtus[RtuNo].YcNum;i++)
			{
				Rtus[RtuNo].YcValue[i]=(float)RtuRecBufYc[i*2+1] + (RtuRecBufYc[i*2] &0xf)*256;
			}
		}else break;		
		Rtus[RtuNo].RecFullYx = 1;
		break;
	case 0x03://XRF 异常数据
		int No;
		SC_RtuState(RtuRecBuf[4],RtuNo);

		for (i=0;i<ByteLen-1;i+=3)
		{
			if (RtuRecBuf[5+i+1] & 0x40)//yc
			{
				BrandNo=RtuRecBuf[5+i]>>4;
				No=0;
				if (Rtus[RtuNo].RRC[BrandNo] != 0x32) continue;
				for (int j=0;j<BrandNo;j++) //由槽号取点号
					if (Rtus[RtuNo].RRC[j]==0x32) No +=12;
				No=No + (RtuRecBuf[5+i] & 0xf);
				Rtus[RtuNo].YcValue[No]=(float)RtuRecBuf[5+i+2] + (RtuRecBuf[5+i+1] & 0xf)*256;
			}else if(RtuRecBuf[5+i+1] & 0x80)
			{
				BrandNo=RtuRecBuf[5+i] & 0xf;
				No=0;
				if (Rtus[RtuNo].RRC[BrandNo] != 0x11) continue;
				for (int j=0;j<BrandNo;j++) 
					if (Rtus[RtuNo].RRC[j]==0x11) No +=24;

				No=No + ((RtuRecBuf[5+i]>>4) & 0x3)*6;
				for (j=0;j<6;j++)
				{					
					if (RtuRecBuf[5+i+2] & (1<<j))
					{
						if (Rtus[RtuNo].YxValue[No+j] == ((RtuRecBuf[5+i+1] & (1<<j)) ? 1:0)) continue;
						Rtus[RtuNo].YxValue[No+j]=(RtuRecBuf[5+i+1] & (1<<j)) ?1 :0;
						if (Rtus[RtuNo].RecFullYx == 1)
							YxEvent(RtuNo,No+j,Rtus[RtuNo].YxValue[No+j]);//生成变位遥信Event
					}
				}
			}
		}
		if (Rtus[RtuNo].RecFullYx == 0) //如果全数据未收到
		{
			Rtus[RtuNo].CommandSendFlag [0x01] = true;
			Rtus[RtuNo].CommandSendFlag [0x02] = true;
		}
		break;
	case 0x04://SOE
		SC_RtuState(RtuRecBuf[4],RtuNo);
		SC_SOE_Event(&RtuRecBuf[5],ByteLen-1,RtuNo);
		break;
	case 0x05://脉冲累加值
		SC_RtuState(RtuRecBuf[4],RtuNo);
		ByteLen--;
		for (i=0;i<ByteLen;i +=2)
		{
			Rtus[RtuNo].KwhValue[i/2] = RtuRecBuf[5+i]*256 + RtuRecBuf[5+i+1];
		}
		Rtus[RtuNo].CommandSendFlag[0x08] = true;
		break;
	case 0x06://PAZ 脉冲清零
	case 0x09://SDB 死区值
	case 0x19://SST 对钟
	case 0x1a://报告时钟
	case 0x1c://SIM 设置接口 
		SC_RtuState(RtuRecBuf[4],RtuNo);
		break;
//	case 0x07://PAF
//	case 0x08://PAT
//		SC_MakeFrame(RtuNo,0x05);//报告脉冲值
//		Rtus[RtuNo].CommandSendFlag[0x05]=true;
//		break;
	case 0x0a://报死区值
		SC_RtuState(RtuRecBuf[4],RtuNo);
		//add dispose deadarea
		break;
	case 0x0d://COA//遥控预制
		//SC_MakeFrame(RtuNo,0x11);
		//YxNo=0;
		BYTE Temp;

		Temp=~RtuRecBuf[6];
//		Temp += 1;		
		BrandNo=Temp>>4;
		if (RtuNo==*((WORD*)(YKReserved+1)))
		{
			BYTE YkNo = (YKReserved[7] == 0x33)?YKReserved[3]:YKReserved[4];
			BYTE ReturnYkNo = 0;
			for(i=0;i<BrandNo;i++)
				if(Rtus[RtuNo].RRC[i]==0x05) ReturnYkNo +=16;
			ReturnYkNo = ReturnYkNo + (Temp & 0xf);
			if (ReturnYkNo == YkNo)
				YKEcho[RtuNo][1] = YKReserved[7]; 
			else YKEcho[RtuNo][1] = 0xff;
			YKEchoFlag[RtuNo]=1;
		}
		break;
	case 0x08://PAT
	case 0x0e://COD 直接输出控制
	case 0x11://COE 执行输出
	case 0x15://COL 控制输出锁存
		break;
	case 0x18://DRL 锁存数据报告
		SC_RtuState(RtuRecBuf[4],RtuNo);
		//add dispose lock
		break;
	case 0x1b://RIM 报告接口
		SC_RtuState(RtuRecBuf[4],RtuNo);
		//add dispose port
		break;
	default:
		break;
	}
	if((Rtus[RtuNo].CurSendFrameType &0x3f) == (RtuRecBuf[1] &0x3f)) Rtus[RtuNo].CurSendFrameType=0;
	if (RtuNo == Channels[ChNo].ChRtuNo[Channels[ChNo].CurSendRtuNo]) Channels[ChNo].CurSendRtuNo++;
}
			

void SC_RtuState(BYTE RtuStateByte,int RtuNo)
{
	Rtus[RtuNo].RTUStatus=RtuStateByte & 0x7f;
	if (RtuStateByte & 0x01)//RTU Reset
	{
//		SC_MakeFrame(RtuNo,1);//配置		
		if (Rtus[RtuNo].CurSendFrameType!=1) Rtus[RtuNo].CommandSendFlag[1]=true;
//		SC_MakeFrame(RtuNo,0x09);//SDB 死区
		Rtus[RtuNo].CommandSendFlag[0x09]=true;
		Rtus[RtuNo].CommandSendFlag[2]=true;
		Rtus[RtuNo].CommandSendFlag[3]=true;
//		Rtus[RtuNo].CommandSendFlag[4]=true;
		Rtus[RtuNo].CommandSendFlag[5]=true;
//		Rtus[RtuNo].CommandSendFlag[6]=true;
		Rtus[RtuNo].CommandSendFlag[0x19]=true;

	}	
	if (RtuStateByte & 0x02) 
	{
		//SC_MakeFrame(RtuNo,0x19);//时钟
		Rtus[RtuNo].CommandSendFlag[0x19]=true;
		//SC_MakeFrame(RtuNo,0x02);//全数据
		Rtus[RtuNo].CommandSendFlag[0x02]=true;
	}
	if (RtuStateByte & 0x1c) Rtus[RtuNo].CommandSendFlag[0x04]=true;  //SC_MakeFrame(RtuNo,0x04);//SOE
	
	if (RtuStateByte & 0x20) Rtus[RtuNo].CommandSendFlag[0x05]=true;//SC_MakeFrame(RtuNo,0x05);//报告脉冲值
	if (RtuStateByte & 0x40)  Rtus[RtuNo].CommandSendFlag[0x1e]=true; //SC_MakeFrame(RtuNo,0x1e);//复位	
	if (RtuStateByte == 0) Rtus[RtuNo].CommandSendFlag [0x03] = true;
}


void SC_Send(int ChNo)
{
	static int TimeFlag=0;
	static BYTE SendSort[25]={0x1e,0x11,0x0e,0x0d,0x04,0x01,0x09,0x19,0x02,0x06,0x15,0x0a,0x07,
		                      0x18,0x1a,0x1c,0x1b,0x08,0x05,0x03,0,0,0,0,0};//modify by feng 99.11.1 22:28 0x05
	int i;
	BYTE *CurChanRtuNo=&Channels[ChNo].ChRtuNo[0];
	if (Channels[ChNo].ChStatus & 0x100)
	{
		if(YKReserved[0] == 0x11) Rtus[YKReserved[1]].CommandSendFlag[0x0d]=true;
		else if(YKReserved[0] == 0x22) Rtus[YKReserved[1]].CommandSendFlag[0x11] = true;
		Channels[ChNo].ChStatus &= 0xfeff;
	}
	if (Channels[ChNo].ReviseTimeFlag & 0x08) //脉冲值清零
	{
		for (i=0;i<Channels[ChNo].ChRtuNum;i++)  Rtus[CurChanRtuNo[i]].CommandSendFlag[0x06]=true;//SC_MakeFrame(Channels[ChNo].ChRtuNo[i],0x06);
		Channels[ChNo].ReviseTimeFlag &= 0xf7;
	}
								
	if (Channels[ChNo].ReviseTimeFlag & 0x01)//异常数据
	{
		Channels[ChNo].ReviseTimeFlag &= 0xfe;
		for (i=0;i<Channels[ChNo].ChRtuNum;i++) Rtus[CurChanRtuNo[i]].CommandSendFlag[0x03]=true;    //SC_MakeFrame(Channels[ChNo].ChRtuNo[i],0x02);
		if (Channels[ChNo].ReviseTimeFlag &0x02) //全数据
		{
			for (i=0;i<Channels[ChNo].ChRtuNum;i++)
			{
				Rtus[CurChanRtuNo[i]].CommandSendFlag[0x01]=true;
				Rtus[CurChanRtuNo[i]].CommandSendFlag[0x02]=true;
			}
			Channels[ChNo].ReviseTimeFlag &= 0xfd;
		}
		if (Channels[ChNo].ReviseTimeFlag & 0x04)//对时 
		{   
			for (i=0;i<Channels[ChNo].ChRtuNum; i++) 
			{
				Rtus[CurChanRtuNo[i]].CommandSendFlag[0x19]=true;
				Rtus[CurChanRtuNo[i]].CommandSendFlag[0x09]=true;
				Rtus[CurChanRtuNo[i]].CommandSendFlag[0x07]=true;
			}
		    Channels[ChNo].ReviseTimeFlag &= 0xfb;
		}
	}

	Channels[ChNo].CurSendRtuNo = Channels[ChNo].CurSendRtuNo % Channels[ChNo].ChRtuNum;
	int RtuNo = Channels[ChNo].ChRtuNo[Channels[ChNo].CurSendRtuNo];
	if (!Rtus[RtuNo].Flag)
	{
		int j = Channels[ChNo].CurSendRtuNo;
		int RtuNum = Channels[ChNo].ChRtuNum;
		for (int l=0;l<Channels[ChNo].ChRtuNum;l++)
			if(Rtus[Channels[ChNo].ChRtuNo[++j%RtuNum]].Flag) break;

		if (l>=Channels[ChNo].ChRtuNum)
		{
			Channels[ChNo].CurSendRtuNo = -1;
			return;
		}else Channels[ChNo].CurSendRtuNo = j % RtuNum;
	}
		
	RtuNo = Channels[ChNo].ChRtuNo[Channels[ChNo].CurSendRtuNo];
	if (!Rtus[RtuNo].CurSendFrameType)
	{
		int m = 0,SendCommandNo = 0;
		if(RtuNo != DebugRtuNo)
		{
			for (m=0;m<20;m++) if (Rtus[RtuNo].CommandSendFlag[SendSort[m]]) break;			
			if (m<20) SendCommandNo = SendSort[m];
		}
		else if (DebugCommand[0x20])//进行调试
		{
			for (m=0;m<20;m++) if (DebugCommand[SendSort[m]]) break;
			if (m<20) SendCommandNo = SendSort[m];
			DebugCommand[SendCommandNo] = 0;
		}else
		{
			if(DebugCommand[0x21]<DebugCommand[0x22])
				SendCommandNo = DebugCommand[DebugCommand[0x21]];
			else m=20;
			DebugCommand[0x21]++;
		}

		if (m<20)
		{
			SC_MakeFrame(RtuNo,ChNo,SendCommandNo);
			Rtus[RtuNo].IsWait = true;
			Rtus[RtuNo].CommandSendFlag[SendCommandNo]=false;
		}else Channels[ChNo].CurSendRtuNo++;
	}
	else
	{
        if (!Rtus[RtuNo].IsWait) 
		{
			SC_MakeFrame(RtuNo,ChNo,Rtus[RtuNo].CurSendFrameType);
			Rtus[RtuNo].IsWait = true;
		}else if (Rtus[RtuNo].ReSendTimeFlag >Rtus[RtuNo].AnswerWaitTime)//Wait AnswerWaitTime Seconds ReSend
		{
			if (Rtus[RtuNo].CurSendFrameType & 0x80)
				Rtus[RtuNo].CurSendFrameType=0;
			else Rtus[RtuNo].IsWait = false;
			Channels[ChNo].CurSendRtuNo = ++Channels[ChNo].CurSendRtuNo%Channels[ChNo].ChRtuNum;
		}			
	}

				
	char temp[2048];
	if (Rtus[RtuNo].TXBufPtr) 
	{			
		if (Channels[Rtus[RtuNo].RtuChNo].WorkType == 1)
		{
			Rtus[RtuNo].TXBufPtr = 0;
			return;
		}

⌨️ 快捷键说明

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