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

📄 protocol.c

📁 泵站系统屏与屏之间的通信
💻 C
📖 第 1 页 / 共 5 页
字号:
		*(ModbusBuff+2) = HIBYTE(DDStartAddr);		*(ModbusBuff+3) = LOBYTE(DDStartAddr);		*(ModbusBuff+4) = 0x00;		*(ModbusBuff+5) = 0x08;		CRCValue = CRC16(ModbusBuff, 6);		*(ModbusBuff+6) = HIBYTE(CRCValue);		*(ModbusBuff+7) = LOBYTE(CRCValue);		ret = 8;	}	else	{		ret = 0;	}	return ret;}void GEPLC_Command_Handle(int iPort,int iNetGroup,int iConnect,unsigned char *ModbusBuff,unsigned short *CommandBuff,int iLen){	float TempYT;	unsigned long ulInf;	unsigned long TempDD;	unsigned long HiWord,LoWord;	int DO_Num, iDO, PER_NUM = 64,DdCount = 4;	int i, k, m, nRecv, nLen, iGroup, ret = 0;	unsigned short  CRC16Result,Temp[2];	unsigned char ucVSQ,ucSPI,ConLen,ucLen,ucSect = 1;	unsigned char TempYt[4],SendBuff[128];	unsigned char RetFlag[2],IEC104DataBuf_M[256];	unsigned char TempDgt[512],COM_Recv[256],DD_Buff[36];	unsigned char ucADDR = ModbusBuff[0];	unsigned char ucSECT = CommandBuff[0];	if (iLen == 8)//电度量	{		for(k=0;k<3;k++)		{			COMM_SendBuff(iPort,ModbusBuff, iLen);			SYS_Delay(200);			ret = Read_Modbus_Frame(iPort,ucADDR,COM_Recv);			if(ret>0)			{				ret = IEC_PackPowerHead_104( IEC104DataBuf_M, ucADDR, ucSect, 5);//回答电度量冻结确认				CONN_Send104Data(iNetGroup, iConnect, IEC104DataBuf_M, ret );				SYS_Delay(10);				for(i = 0; i < DdCount; i++)				{					HiWord = COM_Recv[3 + 4 * i]*256 + COM_Recv[4 + 4 * i] ;					LoWord = COM_Recv[5 + 4 * i]*256 + COM_Recv[6 + 4 * i] ;					TempDD = HiWord*0x10000 + LoWord ;					Temp[0]=TempDD & 0xFFFF;					Temp[1]=(TempDD >> 16) & 0xFFFF;					DD_Buff[0 + i * 5] = LOBYTE(Temp[0]);					DD_Buff[1 + i * 5] = HIBYTE(Temp[0]);					DD_Buff[2 + i * 5] = LOBYTE(Temp[1]);					DD_Buff[3 + i * 5] = HIBYTE(Temp[1]);					DD_Buff[4 + i * 5] = i;				}				ucVSQ = 0x80 | DdCount;				ucLen = DdCount * 5;				ret = IEC_PackFrame_104(IEC104DataBuf_M, 15, ucVSQ, 37, ucADDR, 1, 1, ucLen, DD_Buff);				CONN_Send104Data(iNetGroup, iConnect, IEC104DataBuf_M, ret );				SYS_Delay(10);				ret = IEC_PackPowerEnd_104( IEC104DataBuf_M, ucADDR, ucSect, 5); //回答电度量数据结束				CONN_Send104Data(iNetGroup, iConnect, IEC104DataBuf_M, ret );				SYS_Delay(10);				break;			}			SYS_Delay(200);		}	}	if(iLen==9)//总召唤命令,上送遥信 	{		ret = IEC_PackInspectHead_104( IEC104DataBuf_M, ucADDR, ucSECT );//回答确认命令		CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);		SYS_Delay(10);		switch(ucSECT)		{		case 0:	//上送通信状态			ucSPI = SubDevice[iPort].SubStations[0].sub_state;			ret	=IEC_PackNode_104(IEC104DataBuf_M,ucADDR,IEC104_COT_M_introgen,ucSPI);			CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);			SYS_Delay(10);			break;		case 2://上送遥信DI量,DI个数为512			nLen=Get_GEPLC_DgtFrame(SendBuff,ucADDR,DI,iPort);			for(k=0;k<3;k++)			{				COMM_SendBuff(iPort,SendBuff,nLen);				SYS_Delay(200);				nRecv = Read_Modbus_Frame(iPort, ucADDR, COM_Recv);				if ( nRecv > 0 )				{					for(i=0;i<512;i++)						TempDgt[i] = GetDigital(COM_Recv+3,i)+1;					for( m=0; m<(512/PER_NUM); m++ )					{						ucVSQ = 0x80 | PER_NUM ;						ConLen = PER_NUM ;						ulInf = PER_NUM*m+1 ;						ret=IEC_PackFrame_104(IEC104DataBuf_M,3/*类别标识*/,ucVSQ/*可变结构限定词*/,20/*传输原因*/,ucADDR/*设备地址*/,							0x02/*扇区号*/,ulInf/*信息地址*/,ConLen/*要转换的字节数*/,&TempDgt[ulInf-1]);						CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);						SYS_Delay(10);					}					break;				}				SYS_Delay(200);			}			break;		case 3://上送遥信量			nLen = Get_GEPLC_DgtFrame(SendBuff,ucADDR,DO,iPort);			for(k=0;k<3;k++)			{				COMM_SendBuff(iPort,SendBuff,nLen) ;				SYS_Delay(200) ;				nRecv = Read_Modbus_Frame(iPort, ucADDR, COM_Recv) ;				if ( nRecv > 0 )				{					DO_Num = SubDevice[iPort].SubStations[0].sub_YX_NUM;					for(i=0;i<DO_Num;i++)						TempDgt[i] = GetDigital(COM_Recv+3,i)+1 ;					iGroup = DO_Num/PER_NUM ;					for(m=0;m<iGroup;m++)					{						ucVSQ = 0x80 | PER_NUM ;						ConLen = PER_NUM ;						ulInf = PER_NUM*m+1 ;						ret = IEC_PackFrame_104(IEC104DataBuf_M,3/*类别标识*/,ucVSQ/*可变结构限定词*/,20/*传输原因*/,ucADDR/*设备地址*/,							0x03/*扇区号*/,ulInf/*信息地址*/,ConLen/*要转换的字节数*/,&TempDgt[ulInf-1]);						CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);						SYS_Delay(10);					}					if(DO_Num%PER_NUM)					{						iDO = DO_Num%PER_NUM ;						ucVSQ = 0x80 | iDO ;						ConLen = iDO ;						ulInf = PER_NUM*m+1 ;						ret=IEC_PackFrame_104(IEC104DataBuf_M,3/*类别标识*/,ucVSQ/*可变结构限定词*/,20/*传输原因*/,ucADDR/*设备地址*/,							0x03/*扇区号*/,ulInf/*信息地址*/,ConLen/*要转换的字节数*/,&TempDgt[ulInf-1]);						CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);						SYS_Delay(10);					}					break;				}				SYS_Delay(200);			}			break;					default :			break;		}		ret = IEC_PackInspectEnd_104( IEC104DataBuf_M, ucADDR, ucSECT );//回答结束报文		CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);			SYS_Delay(10);	}	if (iLen==13)//遥控选择命令 	{		for (k=0;k<3;k++)		{			COMM_SendBuff(iPort,ModbusBuff, iLen);			SYS_Delay(200);			ret = Read_Modbus_Frame(iPort, ucADDR, COM_Recv);			if(ret>0)			{				SYS_Delay(100);					//组查询遥控返校信息的报文,查询返校标志位的信息//				SendBuff[0] = ucADDR;				SendBuff[1] = 0x03;					SendBuff[2] = 0x3;				SendBuff[3] = 0x01;				SendBuff[4] = 0x00;				SendBuff[5] = 0x01;				CRC16Result = CRC16(SendBuff, 6); 					SendBuff[6] = HIBYTE(CRC16Result);				SendBuff[7] = LOBYTE(CRC16Result);				////////////组查询遥控返校信息的报文////////////				COMM_SendBuff(iPort,SendBuff, 8);				SYS_Delay(200);				ret = Read_Modbus_Frame(iPort,ucADDR,COM_Recv);				if (ret>0) 				{					ulInf = CommandBuff[1];					if (COM_Recv[4]==0xF0)					{						//遥控选择成功						RetFlag[0]=CommandBuff[2];						ret=IEC_PackFrame_104(IEC104DataBuf_M,46/*类别标识*/,1/*可变结构限定词*/,7/*传输原因*/,ucADDR/*设备地址*/,							0x03/*扇区号*/,ulInf/*信息地址*/,1/*要转换的字节数*/,RetFlag);						CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);						SYS_Delay(10);					}					else if (COM_Recv[4]==0x0F)					{						//遥控选择失败						RetFlag[0] = CommandBuff[2];						ret = IEC_PackFrame_104(IEC104DataBuf_M,46/*类别标识*/,1/*可变结构限定词*/,0x47/*传输原因*/,ucADDR/*设备地址*/,							003/*扇区号*/,ulInf/*信息地址*/,1/*要转换的字节数*/,RetFlag);						CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);						SYS_Delay(10);					}					else					{						//其他情况(标志位不是成功标志),选择失败						RetFlag[0] = CommandBuff[2];						ret = IEC_PackFrame_104(IEC104DataBuf_M,46/*类别标识*/,1/*可变结构限定词*/,0x47/*传输原因*/,ucADDR/*设备地址*/,							0x03/*扇区号*/,ulInf/*信息地址*/,1/*要转换的字节数*/,RetFlag);						CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);						SYS_Delay(10);					}					}				break;			}			SYS_Delay(200);		}		}	if (iLen==11)//遥控执行、撤销命令 	{		for (k=0;k<3;k++)		{			COMM_SendBuff(iPort,ModbusBuff, iLen);			SYS_Delay(200);			ret = Read_Modbus_Frame(iPort,ucADDR,COM_Recv);			if(ret>0)			{				if (ModbusBuff[8]==0x80)//执行				{					ulInf = CommandBuff[1];					RetFlag[0] = CommandBuff[2];					ret=IEC_PackFrame_104(IEC104DataBuf_M,46/*类别标识*/,1/*可变结构限定词*/,7/*传输原因*/,ucADDR/*设备地址*/,						0x03/*扇区号*/,ulInf/*信息地址*/,1/*要转换的字节数*/,RetFlag);					CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);					SYS_Delay(10);				}				if (ModbusBuff[8]==0xA0)//取消				{					ulInf = CommandBuff[1];					RetFlag[0] = CommandBuff[2];					ret=IEC_PackFrame_104(IEC104DataBuf_M,46/*类别标识*/,1/*可变结构限定词*/,9/*传输原因*/,ucADDR/*设备地址*/,						0x03/*扇区号*/,ulInf/*信息地址*/,1/*要转换的字节数*/,RetFlag);					CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);					SYS_Delay(10);				}						break;			}			SYS_Delay(200);		}	}	if (iLen==14)//直控	{		for (k=0;k<3;k++)		{			COMM_SendBuff(iPort,ModbusBuff, iLen-1);			SYS_Delay(200);			ret =  Read_Modbus_Frame(iPort,ucADDR,COM_Recv);			if ( ret>0 )			{				//直控执行结束,返回确认报文				ulInf=CommandBuff[1];				RetFlag[0]=CommandBuff[2];				ret=IEC_PackFrame_104(IEC104DataBuf_M,46/*类别标识*/,1/*可变结构限定词*/,7/*传输原因*/,ucADDR/*设备地址*/,					0x03/*扇区号*/,ulInf/*信息地址*/,1/*要转换的字节数*/,RetFlag/*要转换的字节的起始地址*/ );				CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);				SYS_Delay(10);				//直控过程结束,返回报文//				ret=IEC_PackFrame_104(IEC104DataBuf_M,46/*类别标识*/,1/*可变结构限定词*/,10/*传输原因*/,ucADDR/*设备地址*/,//					0x03/*扇区号*/,ulInf/*信息地址*/,1/*要转换的字节数*/,RetFlag/*要转换的字节的起始地址*/ );//				CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);	//				SYS_Delay(10);				break;			}			SYS_Delay(200);		}	}	if (iLen==15)//遥调执行	{		for (k=0;k<3;k++)		{			COMM_SendBuff(iPort,ModbusBuff, iLen);			SYS_Delay(200);			ret = Read_Modbus_Frame(iPort,ucADDR,COM_Recv);			if ( ret>0)			{				//遥调执行结束,返回确认报文				ulInf = CommandBuff[1];				*(ModbusBuff+13)=0;				ret=IEC_PackFrame_104(IEC104DataBuf_M,50/*类别标识*/,1/*可变结构限定词*/,7/*传输原因*/,ucADDR/*设备地址*/,					0x03/*扇区号*/,ulInf/*信息地址*/,5/*要转换的字节数*/,(ModbusBuff+9)/*要转换的字节的起始地址*/ );				CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);				SYS_Delay(10);				//遥调过程结束,返回报文				ret=IEC_PackFrame_104(IEC104DataBuf_M,50/*类别标识*/,1/*可变结构限定词*/,10/*传输原因*/,ucADDR/*设备地址*/,					0x03/*扇区号*/,ulInf/*信息地址*/,5/*要转换的字节数*/,(ModbusBuff+9)/*要转换的字节的起始地址*/ );				CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);					SYS_Delay(10);				break;			}			SYS_Delay(200);		}	}	if (iLen==20)//遥调选择或遥调撤消	{		if (ModbusBuff[8]==6)//遥调选择		{			ulInf = ModbusBuff[14]*0x10000+ModbusBuff[13]*0x100+ModbusBuff[12];			TempYt[0] = *(ModbusBuff+15);       			TempYt[1] = *(ModbusBuff+16);     			TempYt[2] = *(ModbusBuff+17);      			TempYt[3] = *(ModbusBuff+18);			memcpy(&TempYT,TempYt,4);			if ( (TempYT<0.0)||(TempYT>204800.0) )	//如果遥调值不在0-32767之间,返回选择失败信息				ret=IEC_PackFrame_104(IEC104DataBuf_M,50/*类别标识*/,1/*可变结构限定词*/,0x47/*传输原因*/,ModbusBuff[11]/*设备地址*/,				0x03/*扇区号*/,ulInf/*信息地址*/,5/*要转换的字节数*/,(ModbusBuff+15) );			else				ret=IEC_PackFrame_104(IEC104DataBuf_M,50/*类别标识*/,1/*可变结构限定词*/,7/*传输原因*/,ModbusBuff[11]/*设备地址*/,				0x03/*扇区号*/,ulInf/*信息地址*/,5/*要转换的字节数*/,(ModbusBuff+15) );			CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);			SYS_Delay(10);		}		if (ModbusBuff[8]==8)//遥调撤消		{			ulInf=ModbusBuff[14]*0x10000+ModbusBuff[13]*0x100+ModbusBuff[12];			ret=IEC_PackFrame_104(IEC104DataBuf_M,50/*类别标识*/,1/*可变结构限定词*/,9/*传输原因*/,ModbusBuff[11]/*设备地址*/,				0x03/*扇区号*/,ulInf/*信息地址*/,5/*要转换的字节数*/,(ModbusBuff+15) );			CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret);				SYS_Delay(10);		}	}	if (iLen==19)//校时命令	{		for(k=0;k<3;k++)		{			COMM_SendBuff(iPort,ModbusBuff, iLen);			SYS_Delay(200);				ret = Read_Modbus_Frame(iPort,ucADDR,COM_Recv);			if(ret>0)			{				break;			}			SYS_Delay(200);			}		}}void Check_SOEInfo(int iPort,unsigned short SOE_Pointer){	unsigned char old_SOEPointer=SubDevice[iPort].SubStations[0].sub_DataTemp[0];	if((SOE_Pointer==0)||(SOE_Pointer>TotalSOE)) 		return;//SOE指针不能大于16	if(SOE_Pointer != old_SOEPointer)	{		if(SOE_Pointer>old_SOEPointer)		{			Process_SOEInf(iPort,old_SOEPointer,SOE_Pointer-old_SOEPointer);		}		else		{			Process_SOEInf(iPort,old_SOEPointer,TotalSOE-old_SOEPointer);						Process_SOEInf(iPort,0,SOE_Pointer);		}	}}void Process_SOEInf(int iPort,unsigned short SOE_Pointer,int nChange){	int k,ret;	unsigned long ulInf;	unsigned short TempMs,StartAddr;	unsigned char SendBuff[10],TempBuff[16],COM_Recv[256],IEC104DataBuf_M[256];	unsigned short  CRC16Result;	unsigned char ucADDR = SubDevice[iPort].SubStations[0].sub_address;	SYS_Delay(100);		//组查询SOE信息的报文//	SendBuff[0] = ucADDR ;	SendBuff[1] = 0x03;		StartAddr = SOEStartAddr+SOE_Pointer*5;//每条SOE信息占用5个寄存器	SendBuff[2] = (unsigned char)(StartAddr/256);	SendBuff[3] = (unsigned char)(StartAddr%256);	SendBuff[4] = 0x00;	SendBuff[5] = 5*nChange;	CRC16Result = CRC16(SendBuff, 6); 		SendBuff[6] = HIBYTE(CRC16Result);	SendBuff[7] = LOBYTE(CRC16Result);	////////////组查询SOE信息的报文////////////	COMM_SendBuff(iPort,SendBuff, 8);	SYS_Delay(200);	ret = Read_Modbus_Frame(iPort,ucADDR,COM_Recv);	if ((ret>0) && (COM_Recv[1]==0x03))	{		for(k=0;k<nChange;k++)		{			TempBuff[0] = COM_Recv[4+k*10]+1;	//信息元素(双点)			TempBuff[1] = TempBuff[2] = 0;				//相对时间			TempMs = COM_Recv[7+k*10]*1000				+ COM_Recv[5+k*10]*256 + COM_Recv[6+k*10];			TempBuff[3] = (unsigned char)(TempMs&0xff);	//毫秒低			TempBuff[4] = (unsigned char)(TempMs>>8);	//毫秒高			TempBuff[5] = COM_Recv[8+k*10];		//分			TempBuff[6] = COM_Recv[9+k*10];					//时			TempBuff[7] = COM_Recv[10+k*10];						//日			TempBuff[8] =COM_Recv[11+k*10];					//月			TempBuff[9] = COM_Recv[12+k*10];					//年			ulInf = COM_Recv[3+k*10];			//SOE序号对应后台的信息体地址			ret=IEC_PackFrame_104(IEC104DataBuf_M,38/*类别标识*/,1/*可变结构限定词*/,3/*传输原因*/,ucADDR/*设备地址*/,				0x01/*扇区号*/,ulInf/*信息地址*/,10/*要转换的字节数*/,&TempBuff[0]);			CONN_Broad104Data(IEC104DataBuf_M,ret);			SYS_Delay(10);			SubDevice[iPort].SubStations[0].sub_DataTemp[0]++;			if(SubDevice[iPort].SubStations[0].sub_DataTemp[0]>TotalSOE) 				SubDevice[iPort].SubStations[0].sub_DataTemp[0]=1;		}	}}	void Process_GEPLC_Recv(int iPort, unsigned char *pData)

⌨️ 快捷键说明

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