📄 protocol.c
字号:
{ unsigned char offset, End_NO; unsigned char ucAddr = SubDevice[iPort].SubStations[iIndex].sub_address; int SubYC = SubDevice[iPort].SubStations[iIndex].sub_YC_NUM; if(SubYC>96) SubYC = 96 ; pFrame[0] = '#'; pFrame[1] = (ucAddr/10)+'0';//地址 范围0-99 pFrame[2] = (ucAddr%10)+'0'; offset = nGroup*24+1; pFrame[3] = (offset/10)+'0';//巡检起始地址 pFrame[4] = (offset%10)+'0'; if(nGroup == SubDevice[iPort].SubStations[iIndex].sub_FunOrder - 1) End_NO = SubYC ; else End_NO = offset+23; pFrame[5] = (End_NO/10)+'0';//巡检范围0-96 pFrame[6] = (End_NO%10)+'0'; pFrame[7] = 0x0D; //回车符的ACSIIC码 return 8;}int Read_TCWDXJ_Frame(int iPort, int Index, int nGroup, unsigned char *pRecv){ int k, nRecv = 0; int CheckPass = 0; int XJ_Num;//巡检路数 if(nGroup==SubDevice[iPort].SubStations[Index].sub_FunOrder - 1) XJ_Num = SubDevice[iPort].SubStations[Index].sub_YC_NUM - 24*nGroup; else XJ_Num = 24; nRecv = ReadComPort(iPort, pRecv, 256); if (nRecv>0) { for(k=0;k<XJ_Num;k++) { if((pRecv[8*k] == 0x23)||(pRecv[8*k] == 0x3D)) { CheckPass++; } } if( CheckPass == XJ_Num ) return nRecv; } return 0;}int Process_TCWDXJ_Recv(unsigned char *pData,int iPort, int Index, int nGroup){ int i,ret,XJ_Num,uInf_Modbus =-1; unsigned long ulInf = 0x4001+nGroup*24; unsigned char tempData[8]; unsigned short TempValue,W_value; unsigned char ucVSQ,ConvertNum,ucSect=1; unsigned char ConvertBuff[256],IEC104DataBuf_M[256]; unsigned char ucAddr = SubDevice[iPort].SubStations[Index].sub_address; if(nGroup == SubDevice[iPort].SubStations[Index].sub_FunOrder - 1) XJ_Num = SubDevice[iPort].SubStations[Index].sub_YC_NUM - 24*nGroup; else XJ_Num = 24; for (i=0;i<XJ_Num;i++) { tempData[0] = *(pData+2+8*i)-0x30; tempData[1] = *(pData+3+8*i)-0x30; tempData[2] = *(pData+4+8*i)-0x30; tempData[3] = *(pData+6+8*i)-0x30; TempValue = tempData[0]*1000+tempData[1]*100+tempData[2]*10+tempData[3]; if ( *(pData+1+8*i) == 0x2B ) W_value = TempValue; if ( *(pData+1+8*i) == 0x2D ) // W_value = ~TempValue+1; W_value = 0; uInf_Modbus = FindPointInf(YC_Msg, ucAddr, ucSect, ulInf+i); if( uInf_Modbus >=0 ) { tempData[0] = HIBYTE(W_value); tempData[1] = LOBYTE(W_value); RefreshDateData(YC_Msg, uInf_Modbus, tempData); } ConvertBuff[3*i+0] = LOBYTE(W_value); ConvertBuff[3*i+1] = HIBYTE(W_value); ConvertBuff[3*i+2] = 0; } ucVSQ = 0x80|XJ_Num; ConvertNum = XJ_Num*3; if(CONN_COMMU_Enable()) { ret = IEC_PackFrame_104(IEC104DataBuf_M,9,ucVSQ,1,ucAddr,0x01,ulInf,ConvertNum,ConvertBuff); WriteMsgToShareMem(iPort,ret,IEC104DataBuf_M,OperatorStation,YC_Msg); }}int Get_DL645_Frame(unsigned char *pFrame,unsigned char ucAddr)//威胜电度表 (部颁DL645规约){ memset(pFrame, 0, 10); *(pFrame + 0) = 0x68; *(pFrame + 1) = ucAddr; //substation address *(pFrame + 7) = 0x68; *(pFrame + 8) = 1; //CS *(pFrame + 9) = 2; //data length return 10; }int Get_ZhangZhouDL645_Frame(unsigned char *pFrame,unsigned char *AddrBuff){ int j; *pFrame = 0x68; for (j = 0; j < 6; j++) *(pFrame +1+ j) = *(AddrBuff+j); //1--6 *(pFrame + 7) = 0x68; *(pFrame + 8) = 1; //CS *(pFrame + 9) = 2; //data length return 10; }int Read_ZhangZhou_Frame(int iPort, unsigned char ucADDR, unsigned char *pRecv){ int iError = 0, len = 0, nRecv = 0; unsigned char TempRecv[32]; unsigned char iRead[EveryRead]; //TempRecv[10] = 0; if( ComDataCome(iPort, 1000) >0 ) { while(nRecv<256) { len = read(COM[iPort], iRead, sizeof(iRead)); if(len>0) { iError = 0 ; if(nRecv+len>256) break; memcpy(TempRecv+nRecv,iRead,len); nRecv += len; if(TempRecv[1]==0x68) { if(nRecv>=TempRecv[10]+13) { nRecv = TempRecv[10]+13; break; } } } else { iError ++ ; if(iError >20) break; SYS_Delay(10); } } } if(nRecv>0) { PrintDebugInfo(iPort, Recv_Data, TempRecv, nRecv); if((TempRecv[1]==0x68)&&(TempRecv[8]==0x68)&&(TempRecv[nRecv-1]==0x16)) { memcpy(pRecv, TempRecv+1, nRecv-1); return nRecv-1; } } return 0;}int Read_DL645_Frame(int iPort, unsigned char ucADDR, unsigned char *pRecv){ int iError = 0, len = 0, nRecv = 0; unsigned char CheckSum; unsigned char iRead[EveryRead]; if( ComDataCome(iPort, 1000) >0 ) { while(nRecv<256) { len = read(COM[iPort], iRead, sizeof(iRead)); if(len>0) { iError = 0 ; if(nRecv+len>256) break; memcpy(pRecv+nRecv,iRead,len); nRecv += len; if(pRecv[0]==0x68) { if(nRecv>=pRecv[9]+12) { nRecv = pRecv[9]+12; break; } } } else { iError ++ ; if(iError >20) break; SYS_Delay(10); } } } if(nRecv >0) { PrintDebugInfo(iPort, Recv_Data, pRecv, nRecv); if( (pRecv[0]==0x68) && (pRecv[7]==0x68) ) { CheckSum = GetByteCheckSum( pRecv, nRecv-2 ); if ( CheckSum==pRecv[nRecv-2] ) { return nRecv; } } } return 0;}void MeterCommOK(int iPort,unsigned char ucAddr,int uIndex){ CurrentTime CurTime; int ret=0,uInf_Modbus =-1; unsigned char TempBuff[16],CommState = 1; unsigned char IEC104DataBuf_M[256]; uInf_Modbus = FindPointInf(YX_Msg, ucAddr, 0, uIndex+2); if( uInf_Modbus >=0 ) { RefreshDateData(YX_Msg, uInf_Modbus, &CommState ); } if(CONN_COMMU_Enable()) { CurTime=GetTime(); TempBuff[0]= 2; TempBuff[1]=LOBYTE( CurTime.mSecond ); TempBuff[2]=HIBYTE( CurTime.mSecond ); TempBuff[3]=LOBYTE( CurTime.minute ); TempBuff[4]=LOBYTE( CurTime.hour ); TempBuff[5]=LOBYTE( CurTime.day ); TempBuff[6]=LOBYTE( CurTime.month ); TempBuff[7]=LOBYTE( CurTime.year ); ret=IEC_PackFrame_104(IEC104DataBuf_M,31/*类别标识*/,1/*可变结构限定词*/,3/*传输原因*/,ucAddr/*设备地址*/, 0/*扇区号*/,(uIndex+2)/*信息地址*/,8/*要转换的字节数*/,TempBuff); WriteMsgToShareMem(iPort,ret,IEC104DataBuf_M,OperatorStation,YX_Msg); }}void MeterCommError(int iPort,unsigned char ucAddr,int uIndex){ CurrentTime CurTime; int ret=0,uInf_Modbus =-1; unsigned char TempBuff[8],CommState = 0; unsigned char IEC104DataBuf_M[256]; uInf_Modbus = FindPointInf(YX_Msg, ucAddr, 0, uIndex+2); if( uInf_Modbus >=0 ) { RefreshDateData(YX_Msg, uInf_Modbus, &CommState ); } if(CONN_COMMU_Enable()) { CurTime=GetTime(); TempBuff[0] = 1; TempBuff[1] = LOBYTE( CurTime.mSecond ); TempBuff[2] = HIBYTE( CurTime.mSecond ); TempBuff[3] = LOBYTE( CurTime.minute ); TempBuff[4] = LOBYTE( CurTime.hour ); TempBuff[5] = LOBYTE( CurTime.day ); TempBuff[6] = LOBYTE( CurTime.month ); TempBuff[7] = LOBYTE( CurTime.year ); ret=IEC_PackFrame_104(IEC104DataBuf_M,31/*类别标识*/,1/*可变结构限定词*/,3/*传输原因*/,ucAddr/*设备地址*/, 0/*扇区号*/,(uIndex+2)/*信息地址*/,8/*要转换的字节数*/,TempBuff); WriteMsgToShareMem(iPort,ret,IEC104DataBuf_M,OperatorStation,YX_Msg); }}void Response_COMState(int iPort,int iNetGroup,int iConnect,unsigned char *IEC104DataBuff){ int ret,uIndex; unsigned char ucTI104,ucSect; unsigned char uSPI,ucADDR; unsigned char IEC104DataBuf_M[256]; unsigned char *p104c = IEC104DataBuff; ucTI104 = *(p104c + IEC104_OFFSET_TI); ucADDR = *(p104c + IEC104_OFFSET_ADDR); ucSect = *(p104c + IEC104_OFFSET_SECT);//对应于后台的扇区号 if(ucTI104 == IEC104_TI_C_IC_NA_1) /*100:总召唤*/ { ret = IEC_PackInspectHead_104( IEC104DataBuf_M, ucADDR, ucSect );//回答确认命令 CONN_Send104Data(iNetGroup, iConnect, IEC104DataBuf_M, ret ); SYS_Delay(10); uIndex = SUB_AddrToIndex(ucADDR); if(ucSect == 0) { uSPI = (SubDevice[iPort].SubStations[uIndex].sub_state==SUB_STATE_ONLINE) ? 0 : 1 ; ret = IEC_PackNode_104(IEC104DataBuf_M, ucADDR,20, uSPI);//装置通讯状态上送主站 CONN_Send104Data(iNetGroup, iConnect, IEC104DataBuf_M, ret ); SYS_Delay(10); } ret = IEC_PackInspectEnd_104( IEC104DataBuf_M, ucADDR, ucSect );//回答结束报文 CONN_Send104Data(iNetGroup, iConnect, IEC104DataBuf_M, ret ); SYS_Delay(10); }}void Response_DL645_DD(int iPort,int iNetGroup,int iConnect,unsigned char *IEC104DataBuff){ int ret,k,nGroup; unsigned char uSPI,ucVSQ; unsigned char ucTI104, ucCOMADDR, ucADDR; unsigned char *p104c = IEC104DataBuff; unsigned char AdjustTime[32],TempBuff[32]; unsigned char IEC104DataBuf_M[256]; int TotalMeterNum = DL645_Meter[iPort].iMeter; ucTI104 = *(p104c + IEC104_OFFSET_TI); ucADDR = *(p104c + IEC104_OFFSET_ADDR); ucCOMADDR = *(p104c + IEC104_OFFSET_SECT); switch (ucTI104) { case 103: /*103:对时*/ ModifyTime(AdjustTime,iPort); break; case IEC104_TI_C_CI_NA_1: /*101:电度量冻结*/ if(ucCOMADDR==1) { ret = IEC_PackPowerHead_104( IEC104DataBuf_M, ucADDR, ucCOMADDR, 5);//回答电度量冻结确认 CONN_Send104Data(iNetGroup, iConnect, IEC104DataBuf_M, ret ); SYS_Delay(10); if(TotalMeterNum%8==0) nGroup=TotalMeterNum/8; else nGroup=TotalMeterNum/8+1; for(k=0;k<nGroup;k++)//将存放在subStations[][]中的电度数据打包成IEC104格式上送至主站 { ret = PackPowerPlus(iPort,IEC104DataBuf_M, k, ucADDR, ucCOMADDR); //回答电度量数据报文 CONN_Send104Data(iNetGroup, iConnect, IEC104DataBuf_M, ret); SYS_Delay(10); } ret = IEC_PackPowerEnd_104( IEC104DataBuf_M, ucADDR, ucCOMADDR, 5); //回答电度量数据结束 CONN_Send104Data(iNetGroup, iConnect, IEC104DataBuf_M, ret ); SYS_Delay(10); } break; case IEC104_TI_C_IC_NA_1: /*100:总召唤*/ ret = IEC_PackInspectHead_104( IEC104DataBuf_M, ucADDR, ucCOMADDR );//回答确认命令 CONN_Send104Data(iNetGroup, iConnect, IEC104DataBuf_M, ret ); SYS_Delay(10); if(ucCOMADDR == 0) { uSPI = (SubDevice[iPort].SubStations[0].sub_state==SUB_STATE_ONLINE) ? 0 : 1 ; ret = IEC_PackNode_104(IEC104DataBuf_M, ucADDR,IEC104_COT_M_introgen,uSPI);//装置通讯状态上送主站 CONN_Send104Data(iNetGroup, iConnect, IEC104DataBuf_M, ret); SYS_Delay(10); for(k = 0; k < TotalMeterNum ; k ++)//表通信状态遥信 { if(DL645_Meter[iPort].WS_Meter[k].SubState == SUB_STATE_ONLINE) TempBuff[k] = 2; else TempBuff[k] = 1; } ucVSQ=0x80|TotalMeterNum; ret=IEC_PackFrame_104(IEC104DataBuf_M,3/*类别标识*/,ucVSQ/*可变结构限定词*/,20/*传输原因*/,ucADDR/*设备地址*/, 0/*扇区号*/,2/*信息地址*/,LOBYTE(TotalMeterNum)/*要转换的字节数*/,TempBuff); CONN_Send104Data(iNetGroup,iConnect,IEC104DataBuf_M,ret); SYS_Delay(10); } ret = IEC_PackInspectEnd_104( IEC104DataBuf_M, ucADDR, ucCOMADDR );//回答结束报文 CONN_Send104Data(iNetGroup, iConnect, IEC104DataBuf_M, ret); SYS_Delay(10); break; }}int PackPowerPlus(int iPort,unsigned char *puc104,int nGroup,unsigned char ucAddr,unsigned char ucCOMAddr){ int i,j,k,ret=0,DD_Num; unsigned long ulInf; unsigned char ucVSQ,ConvertNum; unsigned char ConvertBuff[256]; int TotalMeterNum = DL645_Meter[iPort].iMeter; switch(nGroup) { case 0: if(TotalMeterNum>8)//表总数大于8,每块表四个电度量,第一组上送前8块表的量 { DD_Num = 8*4; for(i=0;i<8;i++) { for(j=0 ; j<4 ; j++)//4 for measure num of one meter { for (k=0; k<4 ; k++) //4 for one measure num { ConvertBuff[i*4*5+j*5+k] = DL645_Meter[iPort].WS_Meter[i].MeterData[j*4+k]; } ConvertBuff[i*4*5+j*5+4] = i*4+j;//顺序号,从0开始 if (DL645_Meter[iPort].WS_Meter[i].SubState == SUB_STATE_OFFLINE) ConvertBuff[i*4*5+j*5+4] |= 0x80;//如果通信中断,上送数据无效 } } ucVSQ = 0x80|DD_Num; ConvertNum = DD_Num*5;//每个电度量5个字节 ulInf = 0x0C01; ret=IEC_PackFrame_104(puc104,IEC104_TI_M_IT_NA_1/*类别标识*/,ucVSQ/*可变结构限定词*/,IEC104_COT_M_reqcogen/*传输原因*/,ucAddr/*设备地址*/, ucCOMAddr/*扇区号*/,ulInf/*信息地址*/,ConvertNum/*要转换的字节数*/,ConvertBuff/*要转换的字节的起始地址*/ ); } else//表总数小于8,每块表四个电度量,第一组上送所有表的量 { DD_Num = TotalMeterNum*4; for(i=0;i<TotalMeterNum;i++) { for(j=0 ; j<4 ; j++)//4 for measure num of one meter { for (k=0; k<4 ; k++) //4 for one measure num { ConvertBuff[i*4*5+j*5+k] = DL645_Meter[iPort].WS_Meter[i].MeterData[j*4+k]; } ConvertBuff[i*4*5+j*5+4] = i*4+j;//顺序号,从0开始 if (DL645_Meter[iPort].WS_Meter[i].SubState == SUB_STATE_OFFLINE) ConvertBuff[i*4*5+j*5+4] |= 0x80;//如果通信中断,上送数据无效 } } ucVSQ = 0x80|DD_Num; ConvertNum = DD_Num*5;//每个电度量5个字节 ulInf = 0x0C01; ret=IEC_PackFrame_104(puc104,IEC104_TI_M_IT_NA_1/*类别标识*/,ucVSQ/*可变结构限定词*/,IEC104_COT_M_reqcogen/*传输原因*/,ucAddr/*设备地址*/, ucCOMAddr/*扇区号*/,ulInf/*信息地址*/,ConvertNum/*要转换的字节数*/,ConvertBuff/*要转换的字节的起始地址*/ ); } break; case 1: DD_Num = (TotalMeterNum-8)*4; for(i=0;i<(TotalMeterNum-8);i++) { for(j=0 ; j<4 ; j++)//4 for measure num o
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -