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

📄 processsc1801.cpp

📁 这是一个变电站的监控程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		MoxaBufWrite(ChNo,(char*)&Rtus[RtuNo].TXBuf[0],Rtus[RtuNo].TXBufPtr);
		MoxaBufRead(ChNo,(BYTE*)temp,2048);
		Channels[ChNo].ChStatus &= 0xfbff;
		Rtus[RtuNo].TXLen=Rtus[RtuNo].TXBufPtr;
		Rtus[RtuNo].TXBufPtr=0;
		Rtus[RtuNo].bSendCanDisp=true;
	}
}
	


void SC_SOE_Event(BYTE *pSOEEventStart,int ByteLen,int RtuNo)
{	
	BYTE time[10];
	WORD yxno=0;
	BYTE BrandNo;
	SYSTEMTIME CurTime;
	GetLocalTime(&CurTime);

	for (int CurSOEEventPtr=0;CurSOEEventPtr<ByteLen;CurSOEEventPtr += 9)
	{
		if ((Events.EventNum+1)==Events.EventSendNum)
		{
			Beep(1000,2000);
			return;
		}
		BrandNo=pSOEEventStart[CurSOEEventPtr+6] & 0xf;
		yxno = 0;
		for (int i=0;i<BrandNo;i++) if(Rtus[RtuNo].RRC[i] == 0x11) yxno += 24;
		yxno += ((pSOEEventStart[CurSOEEventPtr+6]&0x30)>>4)*6;

		SC_TimeToTime0((BYTE *)time,pSOEEventStart+CurSOEEventPtr);
		for (i=0;i<6;i++)
		{
			if (!(pSOEEventStart[CurSOEEventPtr+7] & (1<<i))) continue;
			//yxno +=i;
			FERTEVENT Event;
			Event.cause=1;					
			Event.type=1;		
			Event.rtuno=RtuNo;
			Event.yxno=yxno+i;
			Event.state=(pSOEEventStart[CurSOEEventPtr+8] & (1<<i)) ? 1 : 0;

			Event.year = time[0]*256 + time[1];
			Event.month = time[2];
			Event.day = time[3];
			Event.hour=time[4];
			Event.minute=time[5];
			Event.seconds=time[6];
			Event.hundms = time[7];
			Event.ms = time[8];

			Event.Recday = (BYTE)CurTime.wDay;
			Event.Rechour = (BYTE)CurTime.wHour;
			Event.Recminute = (BYTE)CurTime.wMinute;
			Event.Recseconds = (BYTE)CurTime.wSecond;
			Event.Rechundms = CurTime.wMilliseconds / 100;
			Event.Recms = CurTime.wMilliseconds % 100;
		//	WaitForSingleObject(g_hEventMutex,INFINITE);
			FERTEVENT * CurEventP=Events.EventBuf+Events.EventNum;
			memcpy(CurEventP,&Event,sizeof(FERTEVENT));
			if(++Events.EventNum>=MAX_EVENT_NUM)
				Events.EventNum=0;
    		//	ReleaseMutex(g_hEventMutex);
		}
	}
}


void SC_MakeFrame(int RtuNo,int ChanNo,BYTE FrameType)
{
	BYTE *TXBuf;
	int i;
	int YkNo;
	/////////////////////////////////
	TXBuf=&Rtus[RtuNo].TXBuf[Rtus[RtuNo].TXBufPtr];
	TXBuf[0]=Rtus[RtuNo].Addr;
	TXBuf[1]=FrameType;
	if (Rtus[RtuNo].CurSendFrameType==FrameType)
	{
		TXBuf[1] |=0x80;
		Rtus[RtuNo].CurSendFrameType= TXBuf[1];
	}else	Rtus[RtuNo].CurSendFrameType= FrameType;
	Rtus[RtuNo].ReSendTimeFlag=0;

	switch(FrameType)
	{
	case 0x01:
	case 0x02:
	case 0x03:
	case 0x04:
	case 0x05:
	case 0x06:
	case 0x07:
	case 0x08:
	case 0x1a:
	case 0x1b:
	case 0x1e:
		TXBuf[2]=0;	TXBuf[3]=0;
		TXBuf[4]=0xff;
		for (i=0;i<4;i++) TXBuf[4] ^=TXBuf[i];
		Rtus[RtuNo].TXBufPtr +=5;
		break;
	case 0x09:
		TXBuf[2]=0;		TXBuf[3]=2;
		TXBuf[4]=(Rtus[RtuNo].DeadArea/256) & 0xf;
		TXBuf[5] =Rtus[RtuNo].DeadArea%256;;
		TXBuf[6]=0xff;
		for (i=0;i<6;i++) TXBuf[6] ^=TXBuf[i];
		Rtus[RtuNo].TXBufPtr += 7;
		break;
	case 0x0a://报告死区
		//add
		break;
	case 0x0d://COA 输出预制
		YkNo=(YKReserved[7] == 0x33)?YKReserved[3]:YKReserved[4];
		TXBuf[2]=0;		TXBuf[3]=2;//韶光1801由3 改为 2;
		TXBuf[4]=Rtus[RtuNo].WaitTime*4;
		for (i=0;i<16;i++)
		{
			if (Rtus[RtuNo].RRC[i]==0x05)
				if((YkNo -= 16)<0) break;
		}
		if (i<16) YkNo +=16;
		TXBuf[5]=(i<<4)+(YkNo & 0xf);
		//TXBuf[6]=0;// 韶光1801 不要输出表的ID字节
		//if (YKReserved[7]==0xcc) TXBuf[6] |=1;
		//if(YkNo/16) TXBuf[6] |=0x2;
		//TXBuf[6] |= 0x80;
		TXBuf[6] =0xff;
		for (i=0;i<6;i++) TXBuf[6] ^=TXBuf[i];
		Rtus[RtuNo].TXBufPtr += 7;
		break;
	case 0x0e://COD 直接输出控制
		//ADD
		break;
	case 0x11://COE (SG1801)
		YkNo=(YKReserved[7] == 0x33)?YKReserved[3]:YKReserved[4];
		TXBuf[2]=0;		TXBuf[3]=1;
		for (i=0;i<16;i++)
		{
			if (Rtus[RtuNo].RRC[i]==0x05)
				if((YkNo -= 16)<0) break;
		}
		if (i<16) YkNo +=16;
		TXBuf[4]=(i<<4)+(YkNo & 0xf);
		TXBuf[5] = 0xff;
		for (i=0;i<5;i++) TXBuf[5] ^= TXBuf[i];
		Rtus[RtuNo].TXBufPtr += 6;
		break;
	case 0x15://COL 控制输出锁存
		//add
		break;
	case 0x18://DRL 报告锁存
		//add
		break;
	case 0x19://对钟
		TXBuf[2] = 0;		TXBuf[3] = 6;
		SC_GetSciTime((char*)&TXBuf[4]);	
		TXBuf[10] = 0xff;
		for (i=0;i<10;i++) TXBuf[10] ^= TXBuf[i];
		Rtus[RtuNo].TXBufPtr += 11;
		break;
	case 0x1c://SIM 设置端口
		//add
		break;
	}
}

void SC_GetSciTime(char *time)
{
	SYSTEMTIME systime;
	WORD MilliSeconds;
	BYTE Temp[6];

	CTime Time2000(2000,1,1,0,0,0);	
	time_t time2000=Time2000.GetTime();	
	CTime TimeCur = CTime::GetCurrentTime();
	time_t timecur = TimeCur.GetTime();

	GetLocalTime(&systime);
	
	time2000 = timecur - time2000;
//	if (time2000<0)
//	{
//		time2000++;
//		MilliSeconds=systime.wMilliseconds-1000;
//	}else
		MilliSeconds=systime.wMilliseconds * 10;
	*((long*)Temp)=time2000;
	time[0] = Temp[3];
	time[1] = Temp[2];
	time[2] = Temp[1];
	time[3] = Temp[0];
	*((WORD*)&Temp[4])=MilliSeconds;
	time[4] = Temp[5];
	time[5] = Temp[4];
}


void	SC_TimeToTime0(BYTE *time,BYTE *buf)
{
	time_t t1 = buf[0]*256*65536+buf[1]*65536+buf[2]*256+buf[3];
	DWORD milliseconds=(buf[4]*256+buf[5])/10;
	CTime t2000(2000,1,1,0,0,0);
	time_t t2 = t2000.GetTime();
	time_t t3 = t1 + t2;
	CTime t(t3);
	time[0]=t.GetYear() / 256;
	time[1]=t.GetYear() % 256;
	time[2]=(BYTE)t.GetMonth();
	time[3]=(BYTE)t.GetDay();
	time[4]=(BYTE)t.GetHour();
	time[5]=(BYTE)t.GetMinute();
	time[6]=(BYTE)t.GetSecond();
	time[7]=(BYTE)(milliseconds/100);
	time[8]=(BYTE)(milliseconds%100);

}

void SC1801ZF(int ChNo)
{
	int RtuNo = Channels[ChNo].ChRtuNo[0];
	if(SCZF_Receive(ChNo))
	{
		Rtus[RtuNo].bWorking = TRUE;
		Channels[ChNo].bWorking = true;
		SCZF_Send(ChNo);
	}
}


bool SCZF_Receive(int ChanNo)
{
	BYTE RecBuf[1024];
	char	Temp[2048];
	int Lenth;
	int RtuNo = Channels[ChanNo].ChRtuNo[0];
 	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
	{
		if (iNum < 5)
			return false;
		MoxaBufRead(ChanNo,RecBuf,4);
		Lenth = RecBuf[2]*256 + RecBuf[3];
		if (Lenth>640) 
		{
			MoxaBufRead (ChanNo,(BYTE*)&Temp[0],2048);
			MoxaBufRead (ChanNo,(BYTE*)Temp,2048);
			return false;
		}
		if (iNum<(Lenth+5)) 
		{
			Channels[ChanNo].ChStatus |= 0x400;	
			for (int k=0;k<4;k++)//  Rtus[Channels[ChanNo].ChRtuNo[0]].RecBuf[k] = RecBuf[k];
				Channels[ChanNo].FileHead[k]=RecBuf[k];
			return false;
		}
	}
	Channels[ChanNo].ChStatus &= 0xfbff;
	MoxaBufRead(ChanNo,&RecBuf[4],Lenth+1);
	MoxaBufRead(ChanNo,(BYTE*)&Temp[0],2048);//清通道 buffer
	Rtus[Channels[ChanNo].ChRtuNo[0]].RecFrameSum ++;
	BYTE iLpc = 0xff;
	for(int i=0;i<Lenth + 4;i++)//LPC校验
		iLpc ^= RecBuf[i];
	if (iLpc != RecBuf[Lenth + 4])
	{
		Rtus[Channels[ChanNo].CurSendRtuNo].ErrFrameSum ++;
		return false;
	} 
    
	if (RecBuf[0] != Rtus[Channels[ChanNo].ChRtuNo[0]].Addr) 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 SCZF_Send(int ChNo)
{
	int l = 0;
	int RtuNo = Channels[ChNo].ChRtuNo[0];
	BYTE *RecBuf = &(Rtus[RtuNo].RecBuf[0]);
	BYTE *SendBuf = &(Rtus[RtuNo].TXBuf[0]);
	switch(RecBuf[1] & 0x3f)
	{
	case 1:
		{
			SendBuf[0] = Rtus[RtuNo].Addr;
			SendBuf[1] = 0x41;
			SendBuf[2] = 0;
			SendBuf[3] = 18;
			SendBuf[4] = 0;
			for (int j=0;j<16;j++)
				SendBuf[5+j] = Rtus[RtuNo].RRC[j];
			SendBuf[21] = 0xf0;
			SendBuf[22] = 0xff;
			for (int i=0;i<22;i++) SendBuf[22] ^= SendBuf[i];
			Rtus[RtuNo].TXBufPtr += 23;
			break;
		}	
	case 2:
		{
			int i;
			int YcNum = (Rtus[RtuNo].YcNum + 11)/12 * 12;
			int YxNum = (Rtus[RtuNo].YxNum + 23)/24 * 24;
			SendBuf[0] = Rtus[RtuNo].Addr;
			SendBuf[1] = 0x42;
			WORD Len = 2 * YcNum + YxNum/6 +1;
			SendBuf[2] = Len>>8;
			SendBuf[3] = Len & 0xff;
			SendBuf[4] = 0;
			for (i=0;i<YcNum;i++)
			{
				int YcValue = (int)(Rtus[RtuNo].YcValue[i] * 10 + 2048) % 4096;
//				if (YcValue<0) YcValue = -YcValue;
				SendBuf[5+i*2] = YcValue / 256;
				SendBuf[5+i*2] &= 0x0f;
				SendBuf[5+i*2] |= 0x40; 
				SendBuf[5+i*2+1] = YcValue % 256;
			}
			int Index = 5 + YcNum * 2;
			BYTE YxValue;
			for (int k = 0;k<YxNum/6;k++)
			{
				YxValue = 0;
				for (int j =0;j<6;j++)
				{
					YxValue |= (Rtus[RtuNo].YxValue[k*6+j] ? 1:0) << j;
				}
				YxValue |= 0x80;
				SendBuf[Index++] = YxValue;
			}
			SendBuf[Index] = 0xff;
			for (i =0;i<Index;i++) SendBuf[Index] ^= SendBuf[i];//LPC 校验
			Rtus[RtuNo].TXBufPtr += Len + 5;
			break;
		}
		
	case 3:
		{
			SendBuf[0] = Rtus[RtuNo].Addr;
			if (RecBuf[1] & 0x80) SendBuf[1] = 0xc3;
			else SendBuf[1] = 0x43;
			int iAiRepNum = 0,iDiRepNum = 0;
			int iDiCaoNum = 0,iAiCaoNum = 0;
			for (int i = 0;i < 16;i++)// cao hao
			{
				if (Rtus[RtuNo].RRC[i] == 0x11)//di
				{
					iDiCaoNum++;
					for (int j = 0;j < 4;j++)//zu hao
					{
						BYTE YxValue = 0;
						BYTE ChangeFlag = 0;
						for (int m = 0;m < 6;m++)//每组6个点
						{
							int iDian = (iDiCaoNum - 1) * 24 + 6 * j + m;
							if (Rtus[RtuNo].YxChangeFlag[iDian] )//有变位
							{
								YxValue |= ((Rtus[RtuNo].YxValue [iDian] & 0x1) << m);
								ChangeFlag |= (1 << m);
								Rtus[RtuNo].YxChangeFlag [iDian] = 0;//通知异常遥信数据已发送
							}
						}
						if (ChangeFlag)
						{
							iDiRepNum++;
							SendBuf[5 + 3 * (iDiRepNum + iAiRepNum - 1)] = ((i + j * 16) & 0x3f);
							SendBuf[5 + 3 * (iDiRepNum + iAiRepNum - 1) + 1] = (0x80 | (YxValue & 0x3f));
							SendBuf[5 + 3 * (iDiRepNum + iAiRepNum - 1) + 2] = (ChangeFlag & 0x3f);
						}
					}
				}
				else if (Rtus[RtuNo].RRC[i] == 0x32)//ai
				{
					iAiCaoNum++;
					for (int j = 0;j < 12;j ++)//dian hao
					{
						int iDian = (iAiCaoNum - 1) * 12 + j;
						if (Rtus[RtuNo].YcChangeFlag[iDian] )
						{
							iAiRepNum++;
							int YcValue = (int)(Rtus[RtuNo].YcValue[iDian] * 10 + 2048) % 4096;
							SendBuf[5 + 3 * (iDiRepNum + iAiRepNum - 1)] = i * 16 + j;
							SendBuf[5 + 3 * (iDiRepNum + iAiRepNum - 1) + 1] = (0x40 | 
								((BYTE)(YcValue / 256) & 0xf));
							SendBuf[5 + 3 * (iDiRepNum + iAiRepNum - 1) + 2] = (int)YcValue % 256;
							Rtus[RtuNo].YcChangeFlag[iDian] = 0;
						}
					}
				}
			}

			int iLen = iAiRepNum * 3 + iDiRepNum * 3 + 1;
			SendBuf[2] = iLen / 256;
			SendBuf[3] = iLen % 256;
			if (Rtus[RtuNo].SoePtr == Rtus[RtuNo].SoeSendPtr )//have soe event
				SendBuf[4] = 0;
			else
				SendBuf[4] = 0x4;
			BYTE iLpc = 0xff;
			for(i=0;i<iLen + 4;i++)//LPC校验
				iLpc ^= SendBuf[i];
			SendBuf[4 + iLen] = iLpc;
			Rtus[RtuNo].TXBufPtr = 5 + iLen;	
			break;
		}
	case 4:
		{
			SendBuf[0] = Rtus[RtuNo].Addr;
			if (RecBuf[1] & 0x80) SendBuf[1] = 0xc4;
			else SendBuf[1] = 0x44;
			int iLen = 0;
			if (Rtus[RtuNo].SoePtr >= Rtus[RtuNo].SoeSendPtr )
				iLen = (Rtus[RtuNo].SoePtr - Rtus[RtuNo].SoeSendPtr) * 9 + 1;
			else
				iLen = (Rtus[RtuNo].SoePtr + 64 - Rtus[RtuNo].SoeSendPtr) * 9 + 1;
			SendBuf[2] = iLen / 256;
			SendBuf[3] = iLen % 256;
			SendBuf[4] = 0;
			int iPtr = Rtus[RtuNo].SoeSendPtr;
			CTime t2000(2000,1,1,0,0,0);
			for (int i = 0;i < (iLen - 1) / 9;i++)
			{
				CTime time(Rtus[RtuNo].SoeEvent[iPtr].SoeTime.wYear,Rtus[RtuNo].SoeEvent[iPtr].SoeTime.wMonth,
					Rtus[RtuNo].SoeEvent[iPtr].SoeTime.wDay,Rtus[RtuNo].SoeEvent[iPtr].SoeTime.wHour,
					Rtus[RtuNo].SoeEvent[iPtr].SoeTime.wMinute,Rtus[RtuNo].SoeEvent[iPtr].SoeTime.wSecond);
				time_t t1 = t2000.GetTime();
				time_t t2 = time.GetTime();
				DWORD dwSeconds = t2 - t1;
				BYTE temp[4];
				DWORD *wp = (DWORD *)(&temp[0]);
				*wp = dwSeconds;
				SendBuf[5 + i * 9] = temp[3];
				SendBuf[5 + i * 9 + 1] = temp[2];
				SendBuf[5 + i * 9 + 2] = temp[1];
				SendBuf[5 + i * 9 + 3] = temp[0];
				SendBuf[5 + i * 9 + 4] = (BYTE)(Rtus[RtuNo].SoeEvent[iPtr].SoeTime.wMilliseconds * 10 / 256);
				SendBuf[5 + i * 9 + 5] = (BYTE)(Rtus[RtuNo].SoeEvent[iPtr].SoeTime.wMilliseconds * 10 % 256);
				SendBuf[5 + i * 9 + 6] = (Rtus[RtuNo].SoeEvent[iPtr].CaoNo + Rtus[RtuNo].SoeEvent[iPtr].ZuNo * 16) & 0x3f;
				SendBuf[5 + i * 9 + 7] = (Rtus[RtuNo].SoeEvent[iPtr].ChangeFlag) & 0x3f;
				SendBuf[5 + i * 9 + 8] = (Rtus[RtuNo].SoeEvent[iPtr].YxValue) & 0x3f;
				if (iPtr++ == 64) iPtr = 0;
			}
			Rtus[RtuNo].SoeSendPtr = Rtus[RtuNo].SoePtr ;
			BYTE iLpc = 0xff;
			for(l=0;l< iLen + 4;l++)//LPC校验
			 iLpc ^= SendBuf[l];
			SendBuf[iLen + 4] = iLpc;
			Rtus[RtuNo].TXBufPtr = iLen + 5;
			break;
		}
		
	case 9:
		{
			SendBuf[0] = Rtus[RtuNo].Addr;
			if (RecBuf[1] & 0x80) SendBuf[1] = 0xc9;
			else SendBuf[1] = 0x49;
			SendBuf[2] = 0;
			SendBuf[3] = 1;
			SendBuf[4] = 0;
			 BYTE iLpc = 0xff;
			 for(l=0;l< 5;l++)//LPC校验
				 iLpc ^= SendBuf[l];
			 SendBuf[5] = iLpc;
			 Rtus[RtuNo].TXBufPtr = 6;
			 break;
		}
		
	case 0x19:
		{
			SendBuf[0] = Rtus[RtuNo].Addr;
			if (RecBuf[1] & 0x80) SendBuf[1] = 0xd9;
			else SendBuf[1] = 0x59;
			SendBuf[2] = 0;
			SendBuf[3] = 0x7;
			SendBuf[4] = 0;
			for (l = 0;l < 6;l++)
				SendBuf[5 + l] = RecBuf[4+l];
			 BYTE iLpc = 0xff;
			 for(l=0;l< 5 + 6;l++)//LPC校验
				 iLpc ^= SendBuf[l];
			 SendBuf[11] = iLpc;
			 Rtus[RtuNo].TXBufPtr = 12;
			 break;
		}
		
	case 0x1a:
		{
			SendBuf[0] = Rtus[RtuNo].Addr;
			if (RecBuf[1] & 0x80) SendBuf[1] = 0xda;
			else SendBuf[1] = 0x5a;
			SendBuf[2] =  0;
			SendBuf[3] = 0x07;
			SendBuf[4] = 0;
			SC_GetSciTime((char*)(SendBuf+5));
			SendBuf[11] = 0xff;
			for (l=0;l<11;l++) SendBuf[11] ^= SendBuf[l];
			Rtus[RtuNo].TXBufPtr = 12;
			break;
		}
		
	}
	if (Rtus[RtuNo].TXBufPtr > 0) 
	{
		char Temp[2048];
		if (Channels[ChNo].WorkType == 1) 
		{
			Rtus[RtuNo].TXBufPtr = 0;
			return;
		}// 转发应不旁听
		MoxaBufWrite(ChNo,(char*)SendBuf,Rtus[RtuNo].TXBufPtr);
		MoxaBufRead(ChNo,(BYTE*)Temp,2048);
		//Channels[ChNo].ChStatus &= 0xfbff;//RTU 不能清
		Rtus[RtuNo].TXLen=Rtus[RtuNo].TXBufPtr;
		Rtus[RtuNo].TXBufPtr=0;
		Rtus[RtuNo].bSendCanDisp=true;
	}
}

⌨️ 快捷键说明

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