61850 9-1详解SUNNY.MAN由于文档摘抄了别的文档内容,为了避免被说重复发不了,先写程序,然后介绍内容。
我的硬件,使用DSP28335+DM9000。
一、头文件#define MAX_ASDU_NUM 16/*---------------------------------------------------------------*/typedef union_tagSmV9_1{unsigned short SmV[12];struct{unsigned short CurrentPhaseAProt;// 0 A相电流.保护用unsigned short CurrentPhaseBProt;// 0 B相电流.保护用unsigned short CurrentPhaseCProt;// 0 C相电流.保护用unsigned short CurrentNeutral;// 0 零序电流unsigned short CurrentPhaseAMes;// 0 A相电流.测量用unsigned short CurrentPhaseBMes;// 0 B相电流.测量用unsigned short CurrentPhaseCMes;// 0 C相电流.测量用unsigned short VoltagePhaseA;// 0 A相电压unsigned short VoltagePhaseB;// 0 B相电压unsigned short VoltagePhaseC;// 0 C相电压unsigned short VoltageNeutral;// 0 零序电压unsigned short BusbarVoltage;// 0 母线电压};}SmV9_1;typedef union_tagStateWord{unsigned short stateword[2];struct{unsigned short phhealth:1;//0需要维护0正常1告警unsigned short mod:1;//1模式 0运行1测试unsigned short wakeup:1;//2唤醒 0正常数据有效1唤醒其间数据无效unsigned short synmod:1;//3合并器同步方式 0不可以使用插值1可以使用插值同步unsigned short synpulse:1;//4.同步脉冲 0采样已经同步,同步丢失,如果使用插值则一直是unsigned short ch0state:1;//5通道-7数据是否有效0有效无效unsigned short ch1state:1;//6通道-7数据是否有效0有效无效unsigned short ch2state:1;//7通道-7数据是否有效0有效无效unsigned short ch3state:1;//8通道-7数据是否有效0有效无效unsigned short ch4state:1;//9通道-7数据是否有效0有效无效unsigned short ch5state:1;//10通道-7数据是否有效0有效无效unsigned short ch6state:1;//11通道-7数据是否有效0有效无效unsigned short tratype:1;//.12电流传感器类型 0电流值1电流导数unsigned short currentfactor:1;//13保护电流比例因子 0 SCp=01cf1=00e7unsigned short res1:1;//14备用unsigned short res2:1;//15备用unsigned short ch7state:1;//0通道-7数据是否有效0有效无效unsigned short ch8state:1;//1通道-7数据是否有效0有效无效unsigned short ch9state:1;//2通道-7数据是否有效0有效无效unsigned short ch10state:1;//3通道-7数据是否有效0有效无效unsigned short ch11state:1;//4通道-7数据是否有效0有效无效unsigned short res:11;//自定义};}StateWord9_1;/*----------------------------------------------------------------------------------------------*/typedef struct_tagNetHead{unsigned char DesMac[6];//目的unsigned char SourMac[6];//源的unsigned short TPID;//标记协议标识0x81 00union{struct{unsigned short VID:12;unsigned short CIF:1;unsigned short UserPriority:3;};unsigned short tci;}TCI;//0x80 00(100 0 0000 0000 0000)unsigned short netType;//0x88 ba}NetHead;typedef struct_tagAPDUHEAD{unsigned short APPID;unsigned short APDULen;unsigned short res1;unsigned short res2;}APDUHead_9_1;typedef struct_tagAsduHead9_1{unsigned char tag;//标签unsigned short len;//所有ASDU长度+2(asdnno) asn.1格式unsigned short Asduno;//asdu个数}ASDUHEAD9_1;typedef struct_tagAsdu{unsigned short AsduLen;unsigned char LNName;unsigned char DataSetName;unsigned short LDName;unsigned short RatedPhaseCurrent;// 500 额定相电流unsigned short RatedNeutralCurrent;// 500 额定零序电流unsigned short RatedPhaseVoltage;// 5774 额定相电压或是额定零序电压unsigned short RatedDelayTime;// 4000 额定延时时间,单位US从采样时刻到发送数据的时间SmV9_1smv;StateWord9_1stateword;//状态字unsigned short samplecount;//发送流水号unsigned char samplerate;//采样率,每周波unsigned char confver;//配置版本}Asdu9_1;/*---------------------------------------------------------------------------------------------------*/typedef struct_tagSavdata9_1{NetHead netHead;APDUHead_9_1apduHead;ASDUHEAD9_1asduHead;Asdu9_1asdu[MAX_ASDU_NUM];}SAVDATA_9_1;bool DecodeSmv_9_1(unsigned char* a_chBuf,SAVDATA_9_1* a_pResult);二、可执行文件#include"rx9_1.h"//收到的字符串unsigned short ConverBuf(const unsigned char *buf){unsigned short res;if(buf){res=buf[1];res+=buf[0]<<8;}return res;}unsigned short GetAsnLen(unsigned char * buf,int &len){unsigned short res;if(buf[0]==0x82){res=buf[2];res+=buf[1]*256;len=2;}else if(buf[0]==0x81){res=buf[1];len=1;}else{res=buf[0];len=0;}return res;}bool DecodeSmv_9_1(unsigned char* a_chBuf,SAVDATA_9_1* a_pResult) {if(a_pResult == 0)return false;int nstpos = 0;for(int i=0;i<6;i++)a_pResult->netHead.DesMac[i]=a_chBuf[nstpos++];for(int i=0;i<6;i++)a_pResult->netHead.SourMac[i]=a_chBuf[nstpos++];a_pResult->netHead.TPID=ConverBuf(&a_chBuf[nstpos]);nstpos+=2;a_pResult->netHead.TCI.tci=ConverBuf(&a_chBuf[nstpos]);nstpos+=2;a_pResult->Type=ConverBuf(&a_chBuf[nstpos]);nstpos+=2;a_pResult->apduHead.APPID=ConverBuf(&a_chBuf[nstpos]);//appidnstpos+=2;a_pResult->apduHead.APDULen=ConverBuf(&a_chBuf[nstpos]);//apdulennstpos+=2;a_pResult->apduHead.res1=ConverBuf(&a_chBuf[nstpos]);//res2nstpos+=2;a_pResult->apduHead.res2=ConverBuf(&a_chBuf[nstpos]);//res1nstpos+=2;a_pResult->asduHead.tag=a_chBuf[nstpos];//tagnstpos+=1;int len=0;a_pResult->asduHead.len=GetAsnLen(&a_chBuf[nstpos],len);//asdutotalLennstpos+=(len+1);if(a_pResult->asduHead.tag != 0x80)return false;a_pResult->asduHead.Asduno=ConverBuf(&a_chBuf[nstpos]);//asduNonstpos+=2;unsigned char *asdubuf=&a_chBuf[nstpos];for(int i=0; i<a_pResult->asduHead.Asduno;i++)//解析所有的ASDU{a_pResult->asdu[i].AsduLen=ConverBuf(&a_chBuf[nstpos]);//asduLennstpos+=2;a_pResult->asdu[i].LNName=a_chBuf[nstpos];//LNNamenstpos++;a_pResult->asdu[i].DataSetName=a_chBuf[nstpos];//DataSetnstpos++;a_pResult->asdu[i].LDName=ConverBuf(&a_chBuf[nstpos]);//LDnstpos+=2;a_pResult->asdu[i].RatedPhaseCurrent=ConverBuf(&a_chBuf[nstpos]);// 额定相电流nstpos+=2;a_pResult->asdu[i].RatedNeutralCurrent=ConverBuf(&a_chBuf[nstpos]);// 额定零序电流nstpos+=2;a_pResult->asdu[i].RatedPhaseVoltage=ConverBuf(&a_chBuf[nstpos]);// 额定相电压或是额定零序电压nstpos+=2;a_pResult->asdu[i].RatedDelayTime=ConverBuf(&a_chBuf[nstpos]);// 额定延时时间,单位US从采样时刻到发送数据的时间nstpos+=2;for(int j=0;j<12;j++){a_pResult->asdu[i].smv.SmV[j]=ConverBuf(&a_chBuf[nstpos]);nstpos+=2;}a_pResult->asdu[i].stateword.stateword[0]=ConverBuf(&a_chBuf[nstpos]);//stateword1 nstpos+=2;a_pResult->asdu[i].stateword.stateword[1]=ConverBuf(&a_chBuf[nstpos]);//stateword2 nstpos+=2;a_pResult->asdu[i].samplecount=ConverBuf(&a_chBuf[nstpos]);//samplecountnstpos+=2;a_pResult->asdu[i].samplerate=a_chBuf[nstpos];//sampleratenstpos++;a_pResult->asdu[i].confver=a_chBuf[nstpos];//configvernstpos++;}return true;}三、测试代码unsigned char bufsv[]={0x01,0x0c,0xcd,0x04,0x01,0x03,0x08,0xac,0x7d,0x01,0x26,0x64,0x81,0x00,0x80,0x00,0x88,0xba,0x40,0x00,0x00,0xc5,0x00,0x00,0x00,0x00,0x80,0x81,0xba,0x00,0x04,0x00,0x2c,0x02,0x01,0x00,0x03,0x01,0xf4,0x01,0xf4,0x16,0x8e,0x0f,0xa0,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00,0x0A,0x00,0x0B,0x00,0x0C,0x0f,0xf0,0x40,0x1f,0x0e,0xbf,0x64,0x00,0x00,0x2c,0x02,0x01,0x00,0x03,0x01,0xf4,0x01,0xf4,0x16,0x8e,0x0f,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,0x40,0x1f,0x0e,0xc0,0x64,0x00,0x00,0x2c,0x02,0x01,0x00,0x03,0x01,0xf4,0x01,0xf4,0x16,0x8e,0x0f,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,0x40,0x1f,0x0e,0xc1,0x64,0x00,0x00,0x2c,0x02,0x01,0x00,0x03,0x01,0xf4,0x01,0xf4,0x16,0x8e,0x0f,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x40,0x1f,0x0e,0xc2,0x64,0x00};int_tmain(int argc, _TCHAR* argv[]){SAVDATA_9_1svdata;printf("%s\n","process data...");int j=0;for(int i=0;i<sizeof(bufsv)/sizeof(bufsv[0]);i++) {printf("0x%02x ",bufsv[i]);// j++;// if(j%16==0)//printf("\n");}const char *pSmvname[12]={"CurrentPhaseAProt","CurrentPhaseBProt","CurrentPhaseCProt","CurrentNeutral","CurrentPhaseAMes","CurrentPhaseBMes","CurrentPhaseCMes","VoltagePhaseA","VoltagePhaseB","VoltagePhaseC","VoltageNeutral","BusbarVoltage"};const char *pStateWorld[]={"phhealth","mod","wakeup","synmod","synpulse","ch0state","ch1state","ch2state","ch3state","ch4state","ch5state","ch6state","tratype","currentfactor","res1","res2","ch7state","ch8state","ch9state","ch10state","ch11state","res"};printf("\n");DecodeSmv_9_1(bufsv,& svdata);printf("analyz result:\n");printf(" netinfo:\n");printf("destmac=[%02x %02x %02x %02x %02x %02x]\n",Head.DesMac[0],Head.DesMac[1] ,Head.DesMac[2],Head.DesMac[3],Head.DesMac[4],Head.DesMac[5]);printf("sourmac=[%02x %02x %02x %02x %02x %02x]\n",Head.SourMac[0],Head.SourMac[ 1],Head.SourMac[2],Head.SourMac[3],Head.SourMac[4],Head.SourMac[5]);printf(" TPID=%04x\n",Head.TPID);printf(" erPriority=%02x TCI.VID=%02xTCI.CIF=%02x\n",erPriority,Head.TCI.VID,Head.TCI.CI F);printf(" NetType=%02x\n",Type);printf(" apduinfo\n");printf(" APPID=%04x APDULen=%04x Res1=%04xRes2=%04x\n",svdata.apduHead.APPID,svdata.apduHead.APDULen,svdata.apduHead.res1,svdata.apduH ead.res2);printf(" asduheadinfo\n");printf(" AsduTag=%02x ASDUTotalLen=%04xAsduNo=%04x\n",svdata.asduHead.tag,svdata.asduHead.len,svdata.asduHead.Asduno);printf(" -----------------------------asduInfo----------------------------\n");for(int i=0;i<svdata.asduHead.Asduno;i++){printf(" Asduinfo%02x\n",i+1);printf("AsduLen=%04x,LNname=%02x,DataSetName=%02x,LDName=%04x\n",svdata.asdu[i].AsduLen,svdata.asdu[ i].LNName,svdata.asdu[i].DataSetName,svdata.asdu[i].LDName);printf("RatedPhaseCurrent=%04x,RatedNeutralCurrent=%04x\n",svdata.asdu[i].RatedPhaseCurrent,svdata.a sdu[i].RatedNeutralCurrent);printf(" RatedPhaseVoltage=%04x,RatedDelayTime=%04x\n",svdata.asdu[i].RatedPhaseVoltage,svdata.asdu[i].RatedDelayTime);printf("************************SMV**************************************\n");for(int j=0;j<12;j++){printf(" %s=%04x\n",pSmvname[j],svdata.asdu[i].smv.SmV[j]);}printf("************************StateWord1**************************************\n");for(int j=0;j<16;j++){printf(" %s=%02x\n",pStateWorld[j],(svdata.asdu[i].stateword.stateword[0]>>j) & 0x1);}printf("************************StateWord2**************************************\n");for(int j=0;j<5;j++){printf(" %s=%02x\n",pStateWorld[16+j],(svdata.asdu[i].stateword.stateword[1]>>j) &0x1);//16是上一个关键字的索引数}printf(" %s=%04x\n",pStateWorld[21],(svdata.asdu[i].stateword.stateword[1]>>5));//21是第二个关键字的保留值printf("samplecount=%04x,samplerate=%02x,confver=%02x\n",svdata.asdu[i].samplecount,svdata.asdu[i].s amplerate,svdata.asdu[i].confver);}printf(" -----------------------------asduInfo----------------------------\n");printf("%s\n","press return key exit ...");getchar();return 0;}四、文档说明1.物理层:选用IEEE 802.3规定的100Base-FX,一般用多模光纤,ST接口,当然也可使作SC接口。