IEC61850-9-1 / IEC61850-9-2 报文详解 + STM32F103 完整软件实现

发布时间:2026/7/1 3:36:15
IEC61850-9-1 / IEC61850-9-2 报文详解 + STM32F103 完整软件实现 目录前置说明一、IEC61850-9-1 / 9-2 报文规范详解1. IEC61850-9-1 FT3 帧点对点光纤帧结构核心约束2. IEC61850-9-2 / 9-2LE 以太网 SV 报文二层以太网帧头固定 26 字节APDU ASN.1 TLV 轻量化结构9-2LE校验关键逻辑二、硬件整体方案1. IEC61850-9-2LESTM32F103 原生软件实现2. IEC61850-9-1 FT3 配套硬件三、STM32F103 完整软件实现仅 9-2LE 可纯 MCU 实现3.1 通用头文件 sv92.h3.2 TLV 编码与 SV 报文封装 sv92.c3.3 1PPS 同步定时器驱动TIM2 输入捕获3.4 主函数业务逻辑 main.c四、IEC61850-9-1 FT3 在 STM32 上配套软件无底层编解码五、工程限制与优化方案前置说明IEC61850-9-1FT310Mbps 曼彻斯特串行光纤时序严苛STM32F103 软件无法完成曼码编解码必须外挂 FPGA 做底层光帧处理STM32 仅通过 SPI 读取解析后的数据。IEC61850-9-2SV以太网二层报文完整 ASN.1-BER 资源开销大STM32F103 仅能实现9-2LE 轻量化子集外扩 W5500 硬件以太网芯片RAW 二层裸帧收发。STM32F103 短板72MHz、最大 128KB RAM、无内置 MAC仅适合 4kHz 低采样率0.02S 高精度校验需外挂 FPGA 做同步时序补偿。一、IEC61850-9-1 / 9-2 报文规范详解1. IEC61850-9-1 FT3 帧点对点光纤帧结构字段长度说明同步前导码16bit固定同步序列FPGA 硬件捕获帧起始帧长度8bit负载数据字节长度采样负载区可变smpCnt、同步标志、多路 32bit 采样值、通道品质CRC1616bit帧校验FPGA 硬件计算核心约束曼彻斯特编码 10Mbps单向光纤传输无网络层无 MAC/VLAN依靠光纤下行 1PPS 做采样同步smpCnt 为同步唯一标识。2. IEC61850-9-2 / 9-2LE 以太网 SV 报文二层以太网帧头固定 26 字节6B 组播目的 MAC01-0C-CD-04-XX-XX6B 源 MAC4B 802.1Q VLANTPID0x8100优先级 72B EtherType0x88BASV 报文标识APDU ASN.1 TLV 轻量化结构9-2LESVPDU{ noASDU(OCTET STRING), seqASDU{ ASDU{ svID(字符串), smpCnt(U32), // 同步核心采样计数器 confRev(U32), // 配置版本 smpSynch(U8), // 1同步正常0失步 sample[](int32), // 三相电流电压采样值 sampleQual[](u16) // 通道品质标志 } } }校验关键逻辑两路 SV 报文依靠相同 smpCnt对齐采样点失步smpSynch0、品质异常直接舍弃数据否则引入角差测量误差。二、硬件整体方案1. IEC61850-9-2LESTM32F103 原生软件实现主控STM32F103ZET6以太网W5500SPIRAW 原始套接字发二层裸帧同步输入TIM 捕获 1PPS 秒脉冲全局 smpCnt 清零基准AD外部 24 位 Σ-Δ ADC SPI 采集模拟量外设USART 调试打印、SPI Flash 存储校准参数2. IEC61850-9-1 FT3 配套硬件光收发 曼码编解码 CRC 校验FPGAXC6SLX16STM32 ↔ FPGASPI 通信仅读取解析完成的采样结构体三、STM32F103 完整软件实现仅 9-2LE 可纯 MCU 实现3.1 通用头文件 sv92.h#ifndef SV92_H #define SV92_H #include stm32f10x.h // SV组播MAC #define SV_MCAST_MAC {0x01,0x0C,0xCD,0x04,0x00,0x01} #define SV_SRC_MAC {0x00,0x11,0x22,0x33,0x44,0x55} #define SV_ETH_TYPE 0x88BA #define VLAN_TPID 0x8100 #define VLAN_PRI 0xE0 #define VLAN_ID 0x0A // 通道数量 Ia Ib Ic In Ua Ub Uc Un #define CH_NUM 8 typedef int32_t SV_SAMPLE_T; typedef uint16_t SV_QUAL_T; // ASDU核心数据结构体 typedef struct{ char svID[32]; uint32_t smpCnt; uint32_t confRev; uint8_t smpSynch; SV_SAMPLE_T sample[CH_NUM]; SV_QUAL_T qual[CH_NUM]; }ASDU_DATA_T; extern ASDU_DATA_T g_asdu; // TLV工具函数 void TLV_WriteU8(uint8_t *buf,uint8_t tag,uint8_t val,uint16_t *off); void TLV_WriteU32(uint8_t *buf,uint8_t tag,uint32_t val,uint16_t *off); void TLV_WriteStr(uint8_t *buf,uint8_t tag,char *str,uint16_t *off); uint16_t SV_Pack_APDU(uint8_t *apduBuf); void SV_Send_EthFrame(void); void SV_Parse_RxAPDU(uint8_t *rxBuf,uint16_t len); // 1PPS同步 void TIM2_1PPS_Init(void); extern uint32_t smpCnt; extern uint8_t smpSynch; #endif3.2 TLV 编码与 SV 报文封装 sv92.c#include sv92.h #include w5500.h #include usart.h ASDU_DATA_T g_asdu; uint32_t smpCnt 0; uint8_t smpSynch 0; // TLV头写入 Tag(1B) Length(1B) static void TLV_Header(uint8_t *buf,uint8_t tag,uint8_t len,uint16_t *off) { buf[(*off)] tag; buf[(*off)] len; } void TLV_WriteU8(uint8_t *buf,uint8_t tag,uint8_t val,uint16_t *off) { TLV_Header(buf,tag,1,off); buf[(*off)] val; } void TLV_WriteU32(uint8_t *buf,uint8_t tag,uint32_t val,uint16_t *off) { TLV_Header(buf,tag,4,off); buf[(*off)] (val24)0xFF; buf[(*off)] (val16)0xFF; buf[(*off)] (val8)0xFF; buf[(*off)] val0xFF; } void TLV_WriteStr(uint8_t *buf,uint8_t tag,char *str,uint16_t *off) { uint8_t len strlen(str); TLV_Header(buf,tag,len,off); memcpy(buf(*off),str,len); *off len; } // 封装9-2LE APDU负载 uint16_t SV_Pack_APDU(uint8_t *apduBuf) { uint16_t off 0; uint16_t asduStart; // seqASDU 0xA0 TLV_Header(apduBuf,0xA0,0,off); asduStart off; // svID tag 0x80 TLV_WriteStr(apduBuf,0x80,g_asdu.svID,off); // smpCnt 0x82 TLV_WriteU32(apduBuf,0x82,g_asdu.smpCnt,off); // confRev 0x83 TLV_WriteU32(apduBuf,0x83,g_asdu.confRev,off); // smpSynch 0x84 TLV_WriteU8(apduBuf,0x84,g_asdu.smpSynch,off); // sample数组 0x85 TLV_Header(apduBuf,0x85,CH_NUM*4,off); for(uint8_t i0;iCH_NUM;i){ uint32_t tmp g_asdu.sample[i]; apduBuf[off] (tmp24)0xFF; apduBuf[off] (tmp16)0xFF; apduBuf[off] (tmp8)0xFF; apduBuf[off] tmp0xFF; } // sampleQual 0x86 TLV_Header(apduBuf,0x86,CH_NUM*2,off); for(uint8_t i0;iCH_NUM;i){ apduBuf[off] (g_asdu.qual[i]8)0xFF; apduBuf[off] g_asdu.qual[i]0xFF; } // 更新ASDU长度 apduBuf[asduStart-1] off - asduStart; return off; } // 组装完整以太网SV帧并发送 void SV_Send_EthFrame(void) { uint8_t ethBuf[1500]; uint8_t apduBuf[512]; uint16_t off 0,apduLen; uint8_t mcastMac[6] SV_MCAST_MAC; uint8_t srcMac[6] SV_SRC_MAC; // 1. 目的MAC memcpy(ethBufoff,mcastMac,6); off 6; // 2. 源MAC memcpy(ethBufoff,srcMac,6); off 6; // 3. VLAN标签 ethBuf[off] (VLAN_TPID8)0xFF; ethBuf[off] VLAN_TPID0xFF; ethBuf[off] VLAN_PRI; ethBuf[off] VLAN_ID; // 4. EtherType SV ethBuf[off] (SV_ETH_TYPE8)0xFF; ethBuf[off] SV_ETH_TYPE0xFF; // 5. APDU数据 apduLen SV_Pack_APDU(apduBuf); memcpy(ethBufoff,apduBuf,apduLen); off apduLen; // W5500 RAW二层发送 W5500_SendRaw(ethBuf,off); } // 接收SV报文解析提取采样值 void SV_Parse_RxAPDU(uint8_t *rxBuf,uint16_t len) { uint16_t off 0; uint8_t tag,tagLen; memset(g_asdu,0,sizeof(ASDU_DATA_T)); while(off len){ tag rxBuf[off]; tagLen rxBuf[off]; switch(tag){ case 0x80: // svID memcpy(g_asdu.svID,rxBufoff,tagLen); off tagLen; break; case 0x82: // smpCnt g_asdu.smpCnt (rxBuf[off]24)|(rxBuf[off1]16)|(rxBuf[off2]8)|rxBuf[off3]; off tagLen; break; case 0x83: // confRev g_asdu.confRev (rxBuf[off]24)|(rxBuf[off1]16)|(rxBuf[off2]8)|rxBuf[off3]; off tagLen; break; case 0x84: // smpSynch g_asdu.smpSynch rxBuf[off]; off tagLen; break; case 0x85: // sample for(uint8_t i0;iCH_NUM;i){ g_asdu.sample[i] (rxBuf[off]24)|(rxBuf[off1]16)|(rxBuf[off2]8)|rxBuf[off3]; off 4; } break; case 0x86: // qual for(uint8_t i0;iCH_NUM;i){ g_asdu.qual[i] (rxBuf[off]8)|rxBuf[off1]; off 2; } break; default: off tagLen; break; } } if(g_asdu.smpSynch 0){ USART_SendStr(Sync Lost, Data Invalid!\r\n); } }3.3 1PPS 同步定时器驱动TIM2 输入捕获void TIM2_1PPS_Init(void) { GPIO_InitTypeDef gpio; TIM_TimeBaseInitTypeDef timBase; TIM_ICInitTypeDef ic; NVIC_InitTypeDef nvic; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); // PA0 1PPS输入 gpio.GPIO_Pin GPIO_Pin_0; gpio.GPIO_Mode GPIO_Mode_IPU; GPIO_Init(GPIOA,gpio); // 时基 72MHz/721MHz timBase.TIM_Prescaler 71; timBase.TIM_CounterMode TIM_CounterMode_Up; timBase.TIM_Period 9999; timBase.TIM_ClockDivision TIM_CKD_DIV1; TIM_TimeBaseInit(TIM2,timBase); ic.TIM_Channel TIM_Channel_1; ic.TIM_ICPolarity TIM_ICPolarity_Rising; ic.TIM_ICFilter 0x0F; TIM_ICInit(TIM2,ic); TIM_ITConfig(TIM2,TIM_IT_CC1,ENABLE); nvic.NVIC_IRQChannel TIM2_IRQn; nvic.NVIC_IRQChannelPreemptionPriority 1; nvic.NVIC_IRQChannelSubPriority 1; nvic.NVIC_IRQChannelCmd ENABLE; NVIC_Init(nvic); TIM_Cmd(TIM2,ENABLE); } // 1PPS中断每秒重置smpCnt标记同步正常 void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2,TIM_IT_CC1)) { smpCnt 0; smpSynch 1; TIM_ClearITPendingBit(TIM2,TIM_IT_CC1); } }3.4 主函数业务逻辑 main.c#include stm32f10x.h #include sv92.h #include w5500.h #include adc.h #include usart.h extern ASDU_DATA_T g_asdu; uint8_t rxFrame[1500]; int main(void) { // 底层外设初始化 STM32_RCC_Init(); USART_Init(115200); W5500_SPI_Init(); TIM2_1PPS_Init(); ADC_SPI_Init(); // 初始化SV配置 strcpy(g_asdu.svID,MU_TEST01); g_asdu.confRev 1; while(1) { // 1. 读取ADC采样值填充ASDU ADC_ReadAll(g_asdu.sample); // 2. 更新通道品质位 Check_Sensor_Qual(g_asdu.qual); g_asdu.smpCnt smpCnt; g_asdu.smpSynch smpSynch; // 3. 发送9-2LE SV报文 SV_Send_EthFrame(); // 4. 接收外部MU SV报文校验仪接收支路 if(W5500_Raw_RxReady()) { uint16_t rxLen W5500_ReadRaw(rxFrame); // 跳过26字节以太网帧头传入APDU负载 SV_Parse_RxAPDU(rxFrame26,rxLen-26); // 此处可添加比差角差比对算法匹配相同smpCnt做幅值相位运算 } delay_us(250); // 4kHz采样周期 } }四、IEC61850-9-1 FT3 在 STM32 上配套软件无底层编解码FT3 曼彻斯特时序 10Mbps 远超 STM32 软件处理能力所有光帧解析由 FPGA 完成STM32 仅 SPI 读取结构体// FT3数据交互结构体 typedef struct{ uint32_t smpCnt; uint8_t synch; int32_t chData[CH_NUM]; uint16_t qual[CH_NUM]; }FT3_FRAME_T; FT3_FRAME_T ft3Data; // SPI读取FPGA解析完成的FT3数据 void Read_FT3_Frame(void) { SPI_ReadBuffer((uint8_t*)ft3Data,sizeof(FT3_FRAME_T)); // 同步校验、数据缓存、串口打印 if(ft3Data.synch 0){ USART_SendStr(FT3 Sync Error\r\n); } }五、工程限制与优化方案内存限制仅支持 9-2LE完整 ASN.1 冗余字段全部裁剪最大采样率 4kHz同步精度F103 定时器捕获抖动 ±1μs仅满足 0.2S 级互感器0.02S 高精度校验需外挂 FPGA DPLL 消除软件抖动以太网延时W5500 SPI 传输存在抖动禁止 12.8kHz 高速采样9-1 FT3 硬性限制MCU 无法独立实现必须搭配 FPGA 光收发、曼码编解码、CRC 校验校验业务适配两路 SV/FT3 数据统一提取smpCnt做时序匹配同步异常、品质异常直接屏蔽检定结果。