做电力自动化的人,对IEC 60870-5-101这串字符应该都不陌生。它是国际电工委员会制定的电力系统远动通信规约,专门用来在调度主站、变电站后台、配电终端这些设备之间传遥信、遥测、遥控、遥调,也就是咱们常说的“四遥”信息。这篇文章要聊的是101规约里的“平衡式”传输模式,很多刚开始写规约解析的工程师看到“平衡式”三个字就发懵,以为和电力系统的三相平衡有什么关系,其实它指的是链路层的一种工作方式:主站和从站都能主动往链路上发数据,而不是像非平衡式那样只能靠主站挨个点名轮询。把这个区别吃透,再回头看抓包工具里的十六进制报文,很多困惑一下子就解开了。这篇文章适合刚摸到电力规约门槛的同学、现场调试RTU或DTU的工程师,也适合想用Python或者C语言自己写一个101报文解析器的人参考。
1. 平衡式101到底是什么,解决什么问题
1.1 101规约的来龙去脉
IEC 60870-5-101是国际电工委员会在1995年前后发布的远动通信标准,全称翻译过来是“远动设备及系统——第5部分:传输规约——第101篇:基本远动任务配套标准”。别看名字绕口,它在电力系统里的地位相当高,国内大量配电自动化终端、变电站测控装置、调度数据网前置机都跑这个规约。它规定了信息怎么打包、怎么排序、怎么校验,保证不同厂家设备之间互相能看懂。
101规约的分层模型脱胎于IEC 60870-5系列标准,底层数据链路层基于FT1.2帧格式,上层叫ASDU,也就是应用服务数据单元。打个比方,链路层像是快递运输车,负责把包裹稳定送到目的地;ASDU像是包裹里的货物本身,货物长什么样,里面是遥控命令还是遥测数据,都要靠ASDU来定义。搞懂了链路层和ASDU这两层,101规约基本就掌握了一大半。
在学习101规约时,很多人喜欢直接抄报文分析,这个思路没错,但建议先理清一个前提:它有两种传输模式。一种是非平衡式,一种是平衡式。行业里也常叫“非均衡”和“均衡”。这两种模式在轮询机制、帧格式、时序要求上都有明显区别,如果拿着非平衡式的抓包经验去套平衡式,很容易在链路建立这一步就卡住。
1.2 平衡式与非平衡式的本质区别
非平衡式是一问一答的模式,主站掌握绝对主动权,从站只能被点名之后回答。主站发请求帧,从站回响应帧,如果从站有越限数据、变位信息,也必须憋着,等主站下一次轮询到它才能上报。这种模式优点是逻辑简单,特别适合一条总线上挂很多从站的RS-485网络;缺点是实时性差,从站重要状态变化要等一个轮询周期才能送到主站。
平衡式正好反过来,它的链路是对等的,主站可以发,从站也可以主动发。只要从站检测到遥信变位或者遥测越死区,立刻就往链路上怼一帧数据,不需要等主站问。这种模式适合点对点的通道,比如一个调度主站前置机和一台变电站远动机之间用专线或RS-232直连,从站有突发事件就能秒级上送,实时性比非平衡式强很多。
两种模式的对比如下:
| 对比项 | 非平衡式 | 平衡式 |
|---|---|---|
| 链路主动权 | 主站完全控制 | 主站和从站均可主动发送 |
| 从站上送实时性 | 依赖轮询周期,较慢 | 变化即上送,实时性好 |
| 典型物理通道 | RS-485总线,多从站共享 | RS-232、四线RS-485等点对点通道 |
| 典型应用场景 | 配电自动化、多终端总线 | 变电站远动直连、微网控制器 |
| 控制字段PRM位 | 从站响应帧PRM=0 | 从站主动发送帧PRM=1 |
| 调试复杂度 | 较低,时序固定 | 需考虑双方竞争和冲突避免 |
需要说明的是,平衡式并不是说从站可以不分时机乱发。它仍然要遵循链路层的过程规则,比如帧计数位FCB要配合、确认帧要回复,只是在“谁先开口说话”这件事上,从站有了更多自主权。
1.3 什么场合你会用到平衡式
平衡式101最常见的现场是变电站远动直连。变电站里的远动通信管理机通过串口和调度主站前置机连接,通信通道可能是2M专线,也可能是RS-232直连。这种情况下,链路只有两端设备,不需要复杂的总线寻址,用平衡式就能充分发挥从站主动上送的优点。
另一个典型场景是微网控制器和储能变流器之间的通信,或者是分布式发电单元和就地监控主机之间的连接。微网里的功率波动快,逆变器状态变化频繁,如果还用非平衡式轮询,等主站问到的时候,可能几分钟都过去了。用平衡式101,变流器检测到并网开关变位或者功率越限,立即主动上报,监控系统才能及时做调控策略。
还有一种情况是程用规约转换器连接老式RTU。很多老RTU只支持平衡式101,因为当年设计时就是点对点专线,根本没有总线的概念。新系统接入这种老设备,只能跟着它用平衡式模式,这时对报文解析能力的要求就更高。
2. 报文结构拆解:链路层、ASDU层一次说清
2.1 FT1.2帧格式:单字符、固定长度、可变长度
101规约的数据链路层叫FT1.2异步式字节传输帧格式,这个FT1.2就是IEC 60870-5-1里面定义的一种帧格式。它有三种帧形态:单字符帧、固定长度帧、可变长度帧。
单字符帧最简单,就是单独一个字节0xE5。它专门用来做确认响应,相当于通信里的“收到”或者“没收到”这种状态回复。在平衡式链路中非常常见,因为从站收到主站的命令后,如果不需要回带数据,直接回一个0xE5就行。
固定长度帧的结构是六个字节:
| 字段 | 长度 | 说明 |
|---|---|---|
| 启动字符 | 1字节 | 固定为0x10 |
| 控制字C | 1字节 | 表示链路控制类型 |
| 链路地址A | 1字节 | 从站地址,默认从1开始 |
| 帧校验和CS | 1字节 | 控制字和地址的累加和 |
| 结束字符 | 1字节 | 固定为0x16 |
固定长度帧用于链路控制类报文,比如复位链路、请求链路状态、确认收到用户数据这类操作。它不携带应用数据,只在链路层做“握手”。
可变长度帧就复杂一些,结构如下:
| 字段 | 长度 | 说明 |
|---|---|---|
| 启动字符 | 1字节 | 固定为0x68 |
| 长度L | 1字节 | 控制字、链路地址和ASDU的总字节数 |
| 启动字符 | 1字节 | 再次出现0x68 |
| 控制字C | 1字节 | 链路控制信息 |
| 链路地址A | 1字节 | 从站地址 |
| ASDU数据 | L-2字节 | 应用服务数据单元 |
| 帧校验和CS | 1字节 | 从控制字到ASDU末字节的累加和 |
| 结束字符 | 1字节 | 固定为0x16 |
这里有个细节:长度L不包括第一个0x68、第二个0x68、校验和和结束字符,只包括C、A和ASDU三部分。所以如果ASDU是9个字节,L就是C的1字节加A的1字节再加ASDU的9字节,等于11,十六进制写成0x0B。L最大是255,也就是说一帧可变长度报文最多能带253字节的ASDU数据。
帧校验和CS的计算也不复杂,把所有参与校验的字节加起来,取低8位。比如固定长度帧,CS就等于控制字加链路地址之和的末8位;可变长度帧,CS等于控制字、链路地址、ASDU所有字节累加的末8位。
2.2 控制字段里的每个bit都是什么意思
控制字段别看只有一个字节,信息量很大。IEC 60870-5-1规定它的bit1到bit8各有分工,分别叫DIR、PRM、FCB、FCV,以及后面的四位功能码。这个顺序是从最低位开始数的,实际显示成字节时,bit1就是十进制数1对应的那一位。
DIR表示传输方向,0代表主站到从站,1代表从站到主站。PRM表示报文来源类型,1是启动报文,0是从动报文。非平衡式链路里,主站发的启动报文PRM=1,从站回的从动报文PRM=0。平衡式链路里,从站主动上送时PRM这一位也是1,这正是识别平衡式主动帧的关键标志。
FCB叫帧计数位,FCV叫帧计数有效位。主站在发送需要确认的报文时,会把FCV置1,并交替翻转FCB。从站通过检查FCB是否交替变化,来判断是不是有新报文,以及有没有漏帧。这是个防重帧机制,类似网络通信里的序列号,非常重要。
功能码决定链路层的动作或响应类型。主站发送时,功能码0表示复位链路,功能码1表示请求链路状态,功能码3表示发送用户数据并要求确认,功能码4表示发送用户数据但无需确认。从站响应时,功能码0表示确认,功能码8表示带回数据的响应,功能码9表示无数据响应,功能码11表示链路状态响应。实际解析时,先看PRM位,再查对应的功能码表,基本就能判断这一帧是什么动作了。
举个例子:非平衡式主站轮询从站时,经常发“请求链路状态”命令,这就是PRM=1、FCV=0、功能码1的固定长度帧。从站如果链路正常且没有数据上报,就回一个功能码11的“链路状态响应”帧,告诉主站“链路通,但没数据”。
2.3 ASDU结构与常见类型速查
ASDU是应用层的数据包,也是解析时最需要花心思的部分。它的结构固定包含类型标识、可变结构限定词、传送原因、公共地址,然后是信息对象地址和信息元素。在IEC 60870-5-101的配套标准里,ASDU的公共地址是2字节,信息对象地址通常是3字节,和104规约保持一致。
类型标识是一个字节,用来表示后续信息对象的种类。最常见的类型有:
| 类型标识 | 含义 | 对应信息 |
|---|---|---|
| 1 (0x01) | M_SP_NA_1 | 单点遥信 |
| 3 (0x03) | M_DP_NA_1 | 双点遥信 |
| 9 (0x09) | M_ME_NA_1 | 归一化遥测值 |
| 11 (0x0B) | M_ME_NB_1 | 标度化遥测值 |
| 13 (0x0D) | M_ME_NC_1 | 短浮点遥测值 |
| 45 (0x2D) | C_SC_NA_1 | 单点遥控命令 |
| 46 (0x2E) | C_DC_NA_1 | 双点遥控命令 |
| 100 (0x64) | C_IC_NA_1 | 总召唤命令 |
| 101 (0x65) | C_CI_NA_1 | 电度召唤 |
可变结构限定词用来描述信息对象的个数和排列方式。最高位是SQ位,SQ=0表示信息地址连续,SQ=1表示不连续。低7位表示信息对象数量。比如0x01表示只有一个信息对象,0x81表示信息地址连续,之后跟着多个地址连续的数据值。
传送原因表示这个报文是主动上送、召唤响应、激活确认还是停止激活。常见值有0x06激活、0x07激活确认、0x08停止激活、0x0A激活终止、0x14响应总召唤、0x03突发报文。解析时看到0x03,就要意识到这是从站主动上送的变化信息,这在平衡式链路中属于正常现象,不要当异常处理。
信息对象地址在101里固定占3字节,而且低字节在前。信息元素则根据类型标识不同而不同,比如单点遥信的SCO是一个字节,遥测值可能是两个字节的归一化值或者四个字节的浮点值。解析时一定要按标准里对这个类型的定义来取长度,一个字节差就会导致后续全部错位。
3. 从抓包到解析:一个平衡式报文的全过程
3.1 抓包工具与解析环境准备
调试101规约报文,第一步是拿到正确的原始数据。串口工具是少不了的,现场调试用得最多的就是串口助手,比如友善串口助手、SSCOM、Hercules,都可以用来监视串口收发。不过这类工具只能看到十六进制字节,不能解析规约语义,所以还需要配合自己的解析脚本,或者用一些专业协议分析软件。
抓包方式有讲究。一个串口同时接设备调试,可能会干扰通信,稳妥的办法是串口T型转接,在RX和TX线上并联一路到USB转串口模块,只开启接收,不发送任何数据,这样就能实时监听到链路上的原始报文而不会影响两台设备之间的通信。如果是RS-485总线,建议用带监听模式的总线分析仪,保证能看到AB线上的差分信号转换后的字节流。
对于平衡式101来说,抓包时最需要注意的一点是:链路可能双向都有主动帧。我见过不少人只盯着主站发的报文看,忽略了从站主动上送的帧,结果解析半天发现时序对不上。所以抓包一定要同时抓两个方向,并且打上时间戳,后面才能还原一帧一帧的交互过程。
3.2 先把固定长度帧拆明白
固定长度帧是链路握手的基础,先从这个入手最简单。假设串口助手抓到这样一帧:
10 12 01 13 16这显然是固定长度帧。第一个字节0x10是启动字符,最后一个字节0x16是结束字符,中间分别是控制字0x12、地址0x01、校验和0x13。来验算一下校验和:0x12加0x01等于0x13,完全一致。这说明这一帧在传输过程中没有发生字节错误。
接着看控制字0x12,换算成二进制是00010010。bit1是0,说明DIR=0,主站发给从站;bit2是1,说明PRM=1,这是主站主动发起的启动报文;bit3和bit4都是0;高四位是0001,也就是功能码1。对照IEC 60870-5-2的功能码表,主站发送时功能码1代表“请求链路状态”。所以这帧的意思是:主站要求从站报告当前链路状态。
正常情况下,从站会回复一帧固定长度响应:
10 0B 01 0C 16控制字0x0B换算成二进制是00001011。bit1是1,说明DIR=1,从站发给主站;bit2是0,说明PRM=0,这是从动响应;bit3和bit4是多少不重要,重点看高四位功能码1011等于11,正好是“链路状态响应”。也就是说从站告诉主站:链路正常,没有数据要传。校验和0x0C等于0x0B加0x01,验算无误。
非平衡式模式下,主站发出请求后会等从站响应,这个一问一答的时间间隔通常按超时参数配置,一般是50到200毫秒。平衡式模式下,从站也可能不等主站问,直接主动发固定长度帧来报告链路状态变化。
3.3 主站总召唤报文逐字节解析
固定长度帧解析完,再看一个真实的可变长度帧。假设抓到主站发出的总召唤命令:
68 0B 68 3A 01 64 01 06 01 00 00 00 00 14 BB 16从前往后拆:
- 0x68是启动字符。
- 0x0B是长度L,表示后面数据区总字节数是11。
- 再次出现0x68,确认这是可变长度帧类型。
- 0x3A是控制字,二进制00111010。bit1=0表示主站到从站,bit2=1表示启动报文,bit4=1表示FCV有效,高四位0011表示功能码3,也就是“发送用户数据并要求确认”。
- 0x01是链路地址,表示送往地址为1的从站。
- 后面的9个字节就是ASDU:
64 01 06 01 00 00 00 00 14逐个看:0x64是类型标识100,总召唤命令;0x01是可变结构限定词,表示只有一个信息对象,SQ=0;0x06是传送原因,表示激活;0x01 0x00是公共地址,低字节在前,等于地址1;0x00 0x00 0x00是信息对象地址;0x14是总召唤限定词,0x14表示召唤全数据。
校验和计算一下:0x3A加0x01加0x64加0x01加0x06加0x01加0x00加0x00加0x00加0x00加0x14,结果低8位是0xBB,和末尾校验和一致。整个报文就是主站请求从站把所有遥信遥测数据“全景扫描”上报一遍。
总召唤是101规约调试中最常碰到的报文。现场做完链路后,主站一般都会先发总召唤,从站收到后要回一个确认帧,然后循环把全部信息上送。如果总召唤解析不对,后续数据全拉不上来。很多初学者的误区是把0x64当成某个设备地址,看到这个字节就跳过去,其实它是类型标识,不是地址,识别类型标识才是ASDU解析的第一步。
3.4 从站主动上送的平衡式时序
平衡式最鲜明的特征,就是从站可以主动发起用户数据帧。假设从站检测到开关遥信变位,此时链路并未处于主站轮询窗口期内,从站直接发出这样一帧:
68 0B 68 3B 01 01 01 03 01 00 01 00 00 00 00 ...控制字0x3B换算成二进制是00111011,bit1=1表示DIR=1,从站到主站;bit2=1表示PRM=1,这是一帧主动发送的启动报文;bit4=1表示FCV有效;高四位0011表示功能码3,发送用户数据并要求确认。这个“DIR=1、PRM=1”的组合,就是平衡式主动帧的标志,非平衡式的从站响应帧不会出现这种组合。
ASDU部分,0x01是类型标识,单点遥信;0x01是可变结构限定词,一个信息对象;0x03是传送原因,表示突发报文;地址字段之后的信息元素携带遥信值。主站收到这帧后,链路层要回一个确认帧,通常是单字符帧0xE5或者带确认功能的固定长度帧,告诉从站“帧收到了,不用重发”。
从这个时序就能看出平衡式的价值:开关一旦变位,从站毫秒级就能把信息推到主站,而不是干等着下一个轮询周期。调试平衡式链路时,看到从站主动发帧不用慌,这是设计行为,只要PRM位和功能码对得上,直接按正常流程解析就行。
4. 实际调试里那些坑,我一个个踩过
4.1 常见问题速查表
调试101规约,现场千奇百怪的问题都会冒出来,我把这些年遇到的高频问题整理成一张速查表:
| 现象 | 可能原因 | 解决思路 |
|---|---|---|
| 从站总是回0xE5或功能码9,不上送数据 | 链路没建立,或主站没发总召唤 | 先查链路地址,再手动触发总召唤 |
| 校验和一直不对 | 串口参数不一致、半双工发送碰撞 | 核对波特率数据位,检查收发线是否短路 |
| 帧能收到,但ASDU解析全乱 | 字节序没对齐,或类型标识判断错误 | 先确认控制字长度L,再逐字节对齐ASDU字段 |
| 从站上送数据慢,要等很长时间 | 配置成了非平衡式模式 | 检查传输模式是否设为平衡式 |
| 遥控命令发出去没动作 | 遥控类型标识错误,或遥控输出标志位不对 | 对比DCO字节,确认遥控选择执行流程 |
| 部分遥信老是漏报 | 主动上送帧和主站轮询帧冲突 | 增加随机延时,错开发送时机 |
| 报文时间戳对不上 | 同步对时命令没处理 | 检查校时ASDU类型和处理逻辑 |
| 反复出现重传帧 | 确认帧丢失,或FCB翻转不一致 | 检查接收确认逻辑,按FCB状态重传 |
4.2 平衡式特有的竞争与冲突处理
相比非平衡式,平衡式调试最大的坑就是链路竞争。RS-485是半双工总线,同一时刻只能有一个设备往总线上发数据。如果主站正在发请求,从站偏偏这时也检测到变位事件往总线发数据,两个信号就会在线上撞在一起,报文全变乱码,校验和必挂。
解决冲突的思路有好几种。第一种是物理上避免,改用RS-232全双工点对点通道,或者四线制RS-485,收发各用一对线,理论上不存在发送冲突。第二种是软件错峰,从站主动上送前加一个随机延时,比如10到100毫秒,降低和主站请求帧撞车的概率。第三种是链路层重发机制,发送方发现没有在超时时间内收到确认帧,就按重传次数上限重发数据,保证关键数据不丢。
实际工程里,我见过不少从站主动上送过于频繁导致总线利用率过高的情况。遥信变位一秒变好几次,从站就一秒发好几帧,再加上主站轮询,半双工总线上全是帧碰撞。这时候需要把平衡式主动上报功能和死区滤波结合起来,连续抖动信号不去上送,只有确认状态翻转稳定后才发,既保证实时性,又不把总线淹了。
4.3 RS-232和RS-485物理层选择对解析的影响
报文解析出错,很多时候问题不在解析逻辑,而在物理层。RS-232和RS-485用在101平衡式链路上,表现完全不同。RS-232是全双工,TX和RX独立,主站发一帧、从站发一帧,互不干扰,抓包时两个方向能分别看到清晰的数据,解析起来最舒服。
RS-485是半双工差分传输,只有AB一对线,发送和接收共用物理介质。收发切换需要时间,如果设备里的驱动芯片切换速度不够快,报文开头或结尾会有几个字节被吃掉。调试时看到首字节0x68变成乱码,或者末字节0x16丢失,十有八九是RS-485方向切换时序没调好。
还有一个物理细节必须注意:RS-485终端电阻和偏置电阻。距离长、节点多的时候,不接终端电阻会反射信号,报文出现随机错位;不接偏置电阻,空闲电平可能处于不定态,抓包软件会抓到一堆0x00或0xFF。现场遇到校验和频繁不对,先别急着改程序,用万用表量一量AB线之间的电压是否正常,很多问题其实是硬件惹的祸。解析报文的时候,也要记住RS-485线上看到的数据其实是用差分信号还原出来的逻辑电平,并非原始电信号,抓包设备自身不稳定也会引入误码。
5. 扩展:平衡式101在微网调控和更广场景里的位置
5.1 101、104、61850、698到底怎么配合
电力系统通信规约不止101一个,实际工程里经常是几种规约同时存在,各管一段。101跑在串口上,适合专线点对点;104规约是101的网络版,封装在TCP/IP协议栈上,适合以太网传输;IEC 61850是数字化变电站的站控层规约,报文基于MMS和GOOSE,结构化程度更高;698规约则主要面向电能采集和费控。
这四者的关系可以用一句话总结:61850负责站内设备之间的高速互操作,101和104负责站和主站之间远动信息传输,698负责计量信息上传。在实际变电站工程中,站内测控装置通过61850把数据送给远动机,远动机再通过104或101送给调度主站,主站侧看到的还是熟悉的四遥信息,底层用了什么规约并不影响上层功能。平衡式101在其中扮演的角色,就是把实时性要求高的信号通过专线快速送到调度端,在光纤通道还没有覆盖到的地方,它依然是保底方案。
5.2 平衡式101在微网电力调控中的应用
微网和外部电网的电力调控,近年来越来越受关注。微网系统里有很多分布式电源、储能变流器、负荷开关,这些设备和就地监控主机之间需要快速交换实时状态。考虑到很多就地监控主机只有串口接口,又不希望引入复杂的以太网组网,平衡式101就成了很合适的选择。
举个例子,微网并网点处的开关状态一旦发生变化,并网变流器需要马上告诉能量管理系统,能量管理系统才能决定是孤岛运行还是并网运行。如果使用非平衡式,并网点状态变化可能要等一轮巡检才能被发现;使用平衡式101后,变流器检测到开关变位,一帧报文毫秒级上送,能量管理系统紧接着发起调控策略,切换过程就平滑很多。主动上送突发报文、链路快速恢复、专线传输这几个特点,刚好契合微网对实时性的要求。
如果通道需要走以太网,那就把101换成104规约,两者ASDU层几乎兼容,很多代码可以复用。这也解释了为什么现在的通信管理机大多同时支持101和104,解析层共享一套ASDU处理逻辑,只是链路层一个走串口一个走TCP,非常方便。
5.3 工程选型建议
搞清楚了平衡式101的定位,选型时就能少走弯路。如果通道是RS-232点对点,或者只有两台设备直连,优先考虑平衡式,能极大提升事件上送实时性。如果现场是RS-485总线挂多个从站,尽量不要用平衡式,半双工冲突会让人头疼,这种情况下老老实实配置非平衡式轮询更可靠。
如果是新建的以太网通道,直接上104规约更省事;但如果调试工具或者现有主站系统只支持101,那就要在通信管理机上做规约转换,把以太网过来的104报文转成串口101报文。此时平衡式还是非平衡式,要看串口那一侧的从站设备支持什么。有些老设备只支持平衡式,没办法,硬着头皮配平衡式就好。
最后提醒一句,不同厂家对101规约的细节实现还是会有一点差异,尤其是信息对象地址分配、公共地址范围、浮点遥测的字节序。调试前先找设备厂家要到点表,里面会写明每个点的地址和类型,解析时对着点表核对,能节省大量时间。
我个人在实际操作中的体会是,解析平衡式101报文,顺序千万别搞反。先把链路层判断清楚,看启动字符、长度、控制字、校验和,确认链路状态正常后,再进到ASDU层去分析类型标识、传送原因、信息对象地址。很多人在链路层还没通的时候就急着看数据,结果被各种校验和错误和重传刷屏,越调越乱。建议先写一个校验和检查的小工具,把抓包日志导进去,自动过滤掉CRC不对的坏帧,剩下的有效帧再去做语义分析。这一步做好了,后面所有问题都能看得清清楚楚。另外,平衡式链路中从站主动上送报文时,抓包工具最好开启时间戳显示,这样排查网络延时和帧碰撞时才有据可查。