📄 protocol.c
字号:
#include "include/mcuapi.h"int Read_Modbus_Frame(int iPort, unsigned char ucADDR, unsigned char *pRecv){ int i, k, iError = 0, len = 0, nRecv = 0; 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[1]==0x01) || (pRecv[1]==0x02) || (pRecv[1]==0x03) || (pRecv[1]==0x04) ) { if(nRecv>=pRecv[2]+5) { nRecv = pRecv[2]+5; break; } } if( (pRecv[1]==0x10) || (pRecv[1]==0x05) || (pRecv[1]==0x06) ) { if(nRecv>=8) { nRecv = 8; break; } } } else { iError ++ ; if(iError >30) break; SYS_Delay(10); } } } if( nRecv>0 ) { PrintDebugInfo(iPort, Recv_Data, pRecv, nRecv); if(pRecv[0] != ucADDR) return Error_Recv; if(CRC16(pRecv, nRecv)==0) { return nRecv; } else return Error_Recv; } return 0;}int Read_Modbus_Cmd(int iPort, unsigned char ucADDR, unsigned char *pRecv){ int i, k, iError = 0, len = 0, nRecv = 0; 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[1]==0x01) || (pRecv[1]==0x02) || (pRecv[1]==0x03) || (pRecv[1]==0x04) || (pRecv[1]==0x05) || (pRecv[1]==0x06) ) { if(nRecv>=8) { nRecv = 8; break; } } if(pRecv[1]==0x10) { if(nRecv>=pRecv[6]+9) { nRecv = pRecv[6]+9; break; } } } else { iError ++ ; if(iError >30) break; SYS_Delay(10); } } } if( nRecv>0 ) { PrintDebugInfo(iPort, Recv_Data, pRecv, nRecv); if(pRecv[0] != ucADDR) return Error_Recv; if(CRC16(pRecv, nRecv)==0) { return nRecv; } else return Error_Recv; } return 0;}int Get_GEPLC_Frame(unsigned char *pFrame,unsigned char ucAddr,int nGroup,int iPort){ int Yc_Group, ret = 0; unsigned short CRCResult; SUB_Station *pSub = &SubDevice[iPort].SubStations[0]; int SubYC = pSub->sub_YC_NUM +1 ;//modify for soe int SubYX = pSub->sub_YX_NUM ; int RequierOrder = pSub->sub_FunOrder; if(SubYC%120) Yc_Group = SubYC/120 + 1 ; else Yc_Group = SubYC/120 ; pFrame[0] = ucAddr ; switch( nGroup ) { case 0: pFrame[1] = 0x03 ; pFrame[2] = HIBYTE(AnaStartAddr + RequierOrder*120) ; pFrame[3] = LOBYTE(AnaStartAddr + RequierOrder*120) ; pFrame[4] = 0x00 ; if( RequierOrder == (Yc_Group-1) ) pFrame[5] = SubYC - RequierOrder*120; else pFrame[5] = 120 ; CRCResult = CRC16( pFrame, 6 ); pFrame[6] = HIBYTE(CRCResult); pFrame[7] = LOBYTE(CRCResult); ret = 8; break; case 2: if( WriteGR100Data )//看是否需要把GR100的数据写入PLC { pFrame[1] = 0x10 ; pFrame[2] = HIBYTE(PLC_YC_Addr) ; pFrame[3] = LOBYTE(PLC_YC_Addr) ; pFrame[4] = 0x00 ; pFrame[5] = 16 ; //第1个为GR100通讯状态,然后是15个遥测数据 pFrame[6] = pFrame[5]*2; memcpy(pFrame+7, GR100_Data, pFrame[6]); CRCResult=CRC16(pFrame,pFrame[6]+7); pFrame[pFrame[6]+7] = HIBYTE(CRCResult); pFrame[pFrame[6]+8] = LOBYTE(CRCResult); ret = pFrame[6]+9; } else { pFrame[1] = 0x02 ; pFrame[2] = HIBYTE(DgtStartAddr) ; pFrame[3] = LOBYTE(DgtStartAddr) ; pFrame[4] = HIBYTE(512+SubYX) ; pFrame[5] = LOBYTE(512+SubYX) ; CRCResult=CRC16(pFrame,6); pFrame[6] = HIBYTE(CRCResult); pFrame[7] = LOBYTE(CRCResult); ret = 8; } break; default : pFrame[1] = 0x02 ; pFrame[2] = HIBYTE(DgtStartAddr) ; pFrame[3] = LOBYTE(DgtStartAddr) ; pFrame[4] = HIBYTE(512+SubYX) ; pFrame[5] = LOBYTE(512+SubYX) ; CRCResult=CRC16(pFrame,6); pFrame[6] = HIBYTE(CRCResult); pFrame[7] = LOBYTE(CRCResult); ret = 8; break; } return ret;}int Get_GEPLC_DgtFrame(unsigned char *pFrame,unsigned char ucAddr,int DgtType,int iPort){ unsigned short CRCResult; int SubYX = SubDevice[iPort].SubStations[0].sub_YX_NUM ; if(SubYX>512) SubYX = 512; pFrame[0] = ucAddr ; pFrame[1] = 0x02 ; switch(DgtType) { case DI : pFrame[2] = HIBYTE(DgtStartAddr) ; pFrame[3] = LOBYTE(DgtStartAddr) ; pFrame[4] = 0x02 ;//512 pFrame[5] = 0x00 ; break; case DO : pFrame[2] = HIBYTE(DgtStartAddr+512) ; pFrame[3] = LOBYTE(DgtStartAddr+512) ; pFrame[4] = HIBYTE(SubYX) ; pFrame[5] = LOBYTE(SubYX) ; break; } CRCResult =CRC16(pFrame,6); pFrame[6] = HIBYTE(CRCResult); pFrame[7] = LOBYTE(CRCResult); return 8 ; }void ProcessHMICmd(int iPort, unsigned char ucAddr, unsigned char *pData, int nLen){ int i, k,nSend,nRecv; unsigned short CRCResult; unsigned char SendBuff[256]; unsigned char pRecv[256]; memcpy(SendBuff, pData, nLen); SendBuff[0] = ucAddr; CRCResult = CRC16(SendBuff, nLen-2); SendBuff[nLen-2] = HIBYTE(CRCResult); SendBuff[nLen-1] = LOBYTE(CRCResult); nSend = nLen; if( pData[0] >0 ) //串口Modbus { memcpy(SendBuff, pData, nLen); SendBuff[0] = ucAddr; CRCResult = CRC16(SendBuff, nLen-2); SendBuff[nLen-2] = HIBYTE(CRCResult); SendBuff[nLen-1] = LOBYTE(CRCResult); nSend = nLen; } else //ModbusTCP,前5个字节为0 { SendBuff[0] = ucAddr; memcpy(SendBuff+1, pData+7, nLen - 7); CRCResult = CRC16(SendBuff, (nLen-7)+1); SendBuff[nLen-6] = HIBYTE(CRCResult); SendBuff[nLen-5] = LOBYTE(CRCResult); nSend = nLen - 4; } for(k=0;k<3;k++) { COMM_SendBuff(iPort, SendBuff, nLen); SYS_Delay(200); nRecv = Read_Modbus_Frame(iPort, ucAddr, pRecv); if (nRecv>0) { break; } }}int IEC_Frame_104ToModbus(unsigned char *ModbusBuff,unsigned short *CommandBuff,unsigned char *IEC104DataBuff){ int i,k,j,m,ret=0; CurrentTime CurTime; unsigned short YX_Num,CRCValue; unsigned char ucADDR = *(IEC104DataBuff+11); *(ModbusBuff + 0) = ucADDR; if( *(IEC104DataBuff+6)==103) //clock synchronization command,ASDU_103//校时命令 { *(ModbusBuff+1) = 0x10; *(ModbusBuff+2) = 0x02; *(ModbusBuff+3) = 0xd9; *(ModbusBuff+4) = 0x00; *(ModbusBuff+5) = 0x05; *(ModbusBuff+6) = 0x0A; *(ModbusBuff+7) = 0x00; *(ModbusBuff+8) = 0x01; *(ModbusBuff+9) = 0x00; *(ModbusBuff+10) = 0x01; CurTime = GetTime(); *(ModbusBuff+11) = HEX_TO_BCD(LOBYTE(CurTime.month));//月 *(ModbusBuff+12) = HEX_TO_BCD(LOBYTE(CurTime.year));//年 *(ModbusBuff+13) = HEX_TO_BCD(LOBYTE(CurTime.hour));//时 *(ModbusBuff+14) = HEX_TO_BCD(LOBYTE(CurTime.day));//日 *(ModbusBuff+15) = HEX_TO_BCD(LOBYTE(CurTime.mSecond/1000));//秒 *(ModbusBuff+16) = HEX_TO_BCD(LOBYTE(CurTime.minute));//分 CRCValue=CRC16(ModbusBuff,17); *(ModbusBuff+17) = HIBYTE(CRCValue); *(ModbusBuff+18) = LOBYTE(CRCValue); ret = 19; } else if ( *(IEC104DataBuff+6)==100 )//总召唤 { CommandBuff[0] = *(IEC104DataBuff + 10); *(ModbusBuff+1) = 0x02; *(ModbusBuff+2) = HIBYTE(DgtStartAddr); *(ModbusBuff+3) = LOBYTE(DgtStartAddr); YX_Num = 1024; *(ModbusBuff+4) = HIBYTE(YX_Num); *(ModbusBuff+5) = LOBYTE(YX_Num); CRCValue = CRC16(ModbusBuff, 6); *(ModbusBuff+6) = HIBYTE(CRCValue); *(ModbusBuff+7) = LOBYTE(CRCValue); *(ModbusBuff+8) = 0xFF; ret = 9; } ///////////////////////遥控///////////////////////////////// else if ( *(IEC104DataBuff+6)==46 ) { *(ModbusBuff+1) = 0x10; if ( *(IEC104DataBuff+8)==6 ) { if ( ( *(IEC104DataBuff+15) & 0x80 )==0x80 )//遥控选择 { CommandBuff[1]=(*(IEC104DataBuff+12+1) )*256 + ( *(IEC104DataBuff+12) ); CommandBuff[2]=*(IEC104DataBuff+15); *(ModbusBuff+2) = 0x02; *(ModbusBuff+3) = 0xff; *(ModbusBuff+4) = 0x00; *(ModbusBuff+5) = 0x02; *(ModbusBuff+6) = 0x04;//要写的字结数 *(ModbusBuff+7) = *(IEC104DataBuff+12+1);//遥控序号高字节 *(ModbusBuff+8) = *(IEC104DataBuff+12);//遥控序号低字节 *(ModbusBuff+9) = 0x00 ;//选择命令高字节 if ( ( *(IEC104DataBuff+15) & 0x83 )==0x81 ) *(ModbusBuff+10) = 0x55 ;//选择命令低字节 (0x55:跳开) if ( ( *(IEC104DataBuff+15) & 0x83 )==0x82 ) *(ModbusBuff+10) = 0xAA ;//选择命令低字节 (0xAA:合上) CRCValue=CRC16(ModbusBuff,11); *(ModbusBuff+11) = HIBYTE(CRCValue); *(ModbusBuff+12) = LOBYTE(CRCValue); ret = 13; } if ( ( *(IEC104DataBuff+15) & 0x80 )==0 )//遥控执行 { CommandBuff[1] = (*(IEC104DataBuff+12+1) )*256 + ( *(IEC104DataBuff+12) ); CommandBuff[2] = *(IEC104DataBuff+15); if(CommandBuff[1]>=0x6301)//直控 { *(ModbusBuff+2) = 0x02; *(ModbusBuff+3) = 0xF4; *(ModbusBuff+4) = 0x00; *(ModbusBuff+5) = 0x02; *(ModbusBuff+6) = 0x04;//要写的字节数 *(ModbusBuff+7) = *(IEC104DataBuff+12+1); *(ModbusBuff+8) = *(IEC104DataBuff+12); *(ModbusBuff+9) = 0x00; *(ModbusBuff+10) = CommandBuff[2];//2:合,1:分 CRCValue=CRC16(ModbusBuff,11); *(ModbusBuff+11) = HIBYTE(CRCValue); *(ModbusBuff+12) = LOBYTE(CRCValue); *(ModbusBuff+13) = 0xff; ret = 14; } else { *(ModbusBuff+2) = 0x03; *(ModbusBuff+3) = 0x02; *(ModbusBuff+4) = 0x00; *(ModbusBuff+5) = 0x01; *(ModbusBuff+6) = 0x02;//要写的字节数 *(ModbusBuff+7) = 0x00; *(ModbusBuff+8) = 0x80;//(0x80:执行) CRCValue=CRC16(ModbusBuff,9); *(ModbusBuff+9) = HIBYTE(CRCValue); *(ModbusBuff+10) = LOBYTE(CRCValue); ret = 11; } } } if ( *(IEC104DataBuff+8)==8 )//遥控撤销 { CommandBuff[1] = (*(IEC104DataBuff+12+1) )*256 + ( *(IEC104DataBuff+12) ); CommandBuff[2] = *(IEC104DataBuff+15); *(ModbusBuff+2) = 0x3; *(ModbusBuff+3) = 0x02; *(ModbusBuff+4) = 0x00; *(ModbusBuff+5) = 0x01; *(ModbusBuff+6) = 0x02;//要写的字节数 *(ModbusBuff+7) = 0x00; *(ModbusBuff+8) = 0xA0;//(0xA0:撤销 CRCValue=CRC16(ModbusBuff,9); *(ModbusBuff+9) = HIBYTE(CRCValue); *(ModbusBuff+10) = LOBYTE(CRCValue); ret = 11; } } else if ( *(IEC104DataBuff+6)==50 )///////////////////////////遥调//////////////////////////////////// { CommandBuff[1] = (*(IEC104DataBuff+12+1) )*256 + ( *(IEC104DataBuff+12) ); if((CommandBuff[1]<0x6201)||(CommandBuff[1]>=0x6301)) return 0; if ( *(IEC104DataBuff+8)==6 ) { if ( *(IEC104DataBuff+19)==0x80 )//遥调选择 { for (i=0;i<20;i++) *(ModbusBuff+i)=*(IEC104DataBuff+i); ret = 20; } if ( *(IEC104DataBuff+19) ==0 )//遥调执行 { *(ModbusBuff+1) = 0x10; *(ModbusBuff+2) = 0x2; *(ModbusBuff+3) = 0xdf; *(ModbusBuff+4) = 0x00; *(ModbusBuff+5) = 0x03; *(ModbusBuff+6) = 0x06;//要写的字节数 *(ModbusBuff+7) = *(IEC104DataBuff+12+1); *(ModbusBuff+8) = *(IEC104DataBuff+12); *(ModbusBuff+9) = *(IEC104DataBuff+15+1); *(ModbusBuff+10) = *(IEC104DataBuff+15); *(ModbusBuff+11) = *(IEC104DataBuff+15+3); *(ModbusBuff+12) = *(IEC104DataBuff+15+2); CRCValue = CRC16(ModbusBuff, 13); *(ModbusBuff+13) = HIBYTE(CRCValue); *(ModbusBuff+14) = LOBYTE(CRCValue); ret = 15; } } if ( *(IEC104DataBuff+8)==8 )//遥调撤销 { for (i=0;i<20;i++) *(ModbusBuff+i)=*(IEC104DataBuff+i); ret = 20; } } else if ( *(IEC104DataBuff+6)==101 )//电度量 { *(ModbusBuff+1) = 0x03;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -