news 2026/8/31 12:56:31

DLT698与DLT645协议解析:电表地址读取的实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DLT698与DLT645协议解析:电表地址读取的实战指南

1. 从零开始:为什么电表地址是“敲门砖”?

大家好,我是老张,在智能电表和能源数据采集这个行当里摸爬滚打了十几年。今天咱们不聊那些虚头巴脑的概念,就聊一个最实际、也最让新手头疼的问题:怎么从一台电表里把它的“身份证号”——也就是电表地址——给读出来。不管你是做系统集成的、做运维的,还是自己捣鼓智能家居想接个电表,第一步都得过这一关。

你可能要问了,电表地址不就是印在表壳上的一串数字吗?没错,但那只是物理标签。在通信的世界里,电表需要一个能被协议识别的逻辑地址,用来在一条总线上(比如一个小区单元的所有电表都接在同一根RS485总线上)唯一地标识自己。没有这个地址,你的集中器或采集器就像在一个人山人海的广场上喊“喂!”,没人知道你在叫谁,自然也就读不到任何数据。

所以,读取电表地址,是整个数据采集流程的“握手”环节,是确认通信链路畅通、协议对上的关键一步。国内电表通信,绕不开两个核心协议:DLT645DLT698。DLT645更老牌、更通用,几乎是个电表都支持;而DLT698是后来推出的,功能更强大,面向更高级的用电信息采集系统。很多新电表是两者都支持的。咱们今天的目标,就是手把手教你,用这两个协议,把电表地址“掏”出来。

2. 动手前的准备:硬件连接与软件环境

工欲善其事,必先利其器。在发送任何指令之前,你得先和电表“连上线”。别小看这一步,我见过太多人卡在这里,最后发现是线接反了或者串口没选对。

2.1 硬件连接:RS485 vs. 红外

电表通常提供两种通信接口:RS485红外。你可以把RS485想象成“网线”,稳定、可靠,适合长期固定安装;红外则是“遥控器”,临时抄表、现场调试时用起来很方便。

RS485连接(最常用):你需要准备一个USB转RS485的转换器(市面上几十块钱一个),以及一对双绞线(最好带屏蔽)。电表端子一般标有A(+)、B(-)或485+、485-。连接时务必注意:

  • 你的转换器的A+接电表的A+,B-接电表的B-。接反了通常也能工作,但通信距离和抗干扰能力会大打折扣。
  • 如果总线上挂接了多块电表,所有电表的A+和B-分别并联在一起,形成总线结构。记得在总线的最远端两个电表上,A、B线之间并联一个120欧姆的终端电阻,这个能有效抑制信号反射,是长距离稳定通信的秘诀,很多人会忽略。

红外连接:你需要一个USB转红外串口的适配器(注意是串口红外,不是家电遥控那种)。对准电表上的红外窗口(一般是个黑色或深色的透明罩子),距离最好在几厘米到一米以内,中间不要有遮挡。红外通信对环境光比较敏感,强光直射可能会干扰通信,尽量在室内或背光处操作。

2.2 软件准备:一个顺手的串口调试工具

不需要复杂的开发环境,一个好用的串口调试助手就行。我个人常用的是AccessPort友善串口助手或者开源的CuteCom(Linux下)。关键是要能方便地设置端口参数、发送和接收十六进制(HEX)数据。千万别用那种只能发字符串的玩具软件,我们处理的都是二进制数据帧。

串口参数设置(重中之重!):这是第一个坑点。无论是645还是698协议,默认的串口参数大多是:

  • 波特率24009600bps。这是两个最常用的,我建议先从9600开始试。
  • 数据位8
  • 停止位1
  • 校验位Even(偶校验)

一定要在串口调试工具里准确设置这四项。特别是校验位,设成“无校验”是绝对收不到正确回复的。设置好后,先打开串口,如果软件有“流控制”选项,一律选“无”或“None”。

3. DLT645协议读取地址:经典“广播寻址”法

DLT645-2007版是目前的主流,它的帧结构相对简单直接。读取地址的核心思路是发送一个“广播帧”,这个帧里的地址字段用通配符AA填充,总线上所有支持645协议的电表都会响应,在回复帧中带上自己的真实地址。

3.1 广播指令逐字节解析

咱们把原始文章里的那条指令拿出来,掰开揉碎了讲:FE FE FE 68 AA AA AA AA AA AA 68 13 00 DF 16

  1. 前导帧(唤醒):FE FE FE这不是必须的,但强烈建议加上。你可以把它理解成打电话时的“喂?喂?”,用来唤醒处于低功耗休眠状态的电表。有些电表反应“慢半拍”,多发几个FE能提高成功率。

  2. 帧起始符:68标志一帧数据的开始,固定不变。

  3. 地址域(通配符):AA AA AA AA AA AA这里是关键!6个字节的AA(十进制170)就是广播地址。它告诉所有电表:“不管你们是谁,都请回答我。” 注意,这里是BCD码AA在BCD码里是个无效数字,因此被定义为广播地址。

  4. 帧起始符(再次):68645协议的帧结构是[起始符][地址域][起始符][控制码][数据长度][数据域][校验码][结束符],所以这里又出现一个68

  5. 控制码:130x13这个代码的含义是“读数据”,且是广播读。这是读取地址的固定值。

  6. 数据域长度:00因为我们现在只是问地址,不需要附带任何额外的数据,所以长度是0。

  7. 校验码:DF这是从第一个68开始,到00(数据域长度)为止,所有字节的算术累加和,只取最低的一个字节(和除以256的余数)。68+AA+AA+AA+AA+AA+AA+68+13+00 = 0x01DF,取低8位就是DF。校验码是电表判断帧是否完整、有无传输错误的重要依据。

  8. 结束符:16固定值,标志一帧数据的结束。

发送技巧:在串口调试工具里,选择“HEX发送”模式,把上面这串字节一个不差地输进去,点击发送。记得勾选“发送新行”之类的选项,我们不需要换行符,就发送纯十六进制数据。

3.2 解析返回的地址

如果一切顺利,电表会回复一串数据。我们以示例回复为例:FE FE FE FE 68 14 35 09 03 12 24 68 93 06 47 68 3C 36 45 57 B1 16

  1. 同样,开头的FE是前导帧,电表有时会回送更多。
  2. 找到第一个68,之后紧跟的6个字节14 35 09 03 12 24,就是这块电表的物理地址(通信地址)!注意,这是BCD码,我们需要把它转换成十进制数字来阅读:0x143509031224转换成十进制就是143509031224。这个号码通常和电表外壳上的条形码或编号的后几位对应。
  3. 别急,地址在数据域里又出现了一次。在第二个68之后,控制码93表示“读数据应答”,数据长度06表示后面有6个字节的数据,这6个字节是47 68 3C 36 45 57。这里有个645协议特有的“加33H”规则:数据域中的BCD码,每个字节都加了0x33(即十进制的51)进行混淆。所以,真实的地址需要每个字节减去0x33
    • 47 - 33 = 14
    • 68 - 33 = 35
    • 3C - 33 = 09
    • 36 - 33 = 03
    • 45 - 33 = 12
    • 57 - 33 = 24得到的结果14 35 09 03 12 24,和地址域里的完全一致。这一步验证了地址的正确性。

实战经验:拿到这6字节地址后,请立刻记下来。以后你想读这块电表的电压、电流、电量等数据,就需要用这个真实地址替换掉广播指令里的AA AA AA AA AA AA,进行单点通信。

4. DLT698协议读取地址:更结构化的“服务请求”

DLT698.45协议比645复杂得多,它更像一个完整的物联网通信协议,有明确的客户端、服务器、服务请求的概念。读取地址不再是简单的广播,而是通过一个特定的“对象属性描述符(OAD)”来请求。

4.1 广播指令的构成解析

来看这条698广播指令:68 17 00 43 45 AA AA AA AA AA AA 10 DA 5F 05 01 03 40 01 02 00 00 90 0F 16

  1. 起始符和长度域:68 17 0068是起始符。17 00是长度域,表示后面从控制域开始到帧校验前的字节数。注意这里是低字节在前(Little-Endian),0x0017就是十进制的23个字节。

  2. 控制域和地址域:43 45 AA AA AA AA AA AA 10

    • 43:控制域,这里表示这是一个“发送/确认”帧,由客户端(主站)发往服务器(电表)。
    • 45:服务器地址标志,0x45代表后面的服务器地址是6字节的。
    • AA AA AA AA AA AA:同样是6字节的广播地址,全AA
    • 10:客户机地址(即主站自己的地址),0x10是一个常用默认值。
  3. 帧头校验:DA 5F这是对前面“控制域”到“客户机地址”所有字节计算的一个CRC16校验码,算法是CRC-16/XMODEM。很多开源库都有这个函数。它的作用是确保帧头信息在传输中没有出错。

  4. 服务请求核心 - APDU:05 01 03 40 01 02 00 00从这里开始是协议数据单元,是真正的“业务内容”。

    • 05 01GetRequestNormal,普通读取请求。
    • 03:PIID(调用标识),用来匹配请求和响应,可以自己定义,这里用0x03
    • 40 01 02 00这就是关键!对象属性描述符(OAD)0x40010200这个“魔法数字”在698协议里,就代表“服务器的逻辑设备地址属性”。你可以把它理解为向电表查询“你叫什么名字?”的标准问法。
    • 00:时间标签,没有就填00
  5. 帧校验和结束符:90 0F 1690 0F是整个帧(从长度域到时间标签)的CRC16校验码。16是结束符。

4.2 解读响应并提取地址

电表的响应帧看起来很长,我们抓重点:68 2D 00 ... 05 14 35 09 03 12 24 10 ... 85 01 03 40 01 02 00 01 09 06 24 12 03 09 35 14 ... 16

  1. 找到服务器地址:在控制域C3之后,服务器地址标志05表示地址是6字节,紧接着的14 35 09 03 12 24就是电表的逻辑设备地址!这和645协议读出的地址是同一个东西。698协议在地址域直接给出了明文,不需要加减0x33

  2. 验证数据域:继续往下找到APDU响应部分85 01GetResponseNormal),后面的OAD40 01 02 00和我们发送的请求对应。数据域长度09 06表示后续有6个字节的数据,这6个字节是24 12 03 09 35 14注意看24 12 03 09 35 14这串数字,是不是很眼熟?把它和地址域的14 35 09 03 12 24对比一下。你会发现,数据域里的地址是倒序存放的!这是698协议中OCTET-STRING类型数据的一种常见表现。24 12 03 09 35 14倒过来就是14 35 09 03 12 24。这再次验证了地址的正确性。

698协议的特点:它的回复非常结构化,包含了请求确认、数据、甚至可能的状态信息,信息量比645大得多。解析时一定要有耐心,按照协议文档一层层剥开。

5. 实战排坑指南:当指令发出去没反应时

按照上面步骤操作,大部分标准电表都能读出地址。但如果没反应,别慌,这是常态。我们可以按照以下顺序排查,这也是我踩过无数坑总结的“保姆级”流程:

第一步:检查物理连接与电源

  • RS485:用万用表直流电压档测A、B线间的电压。静态时(不通信)应该有个稳定的电压(通常A>B),发送数据时指针会摆动。如果电压为0或极低,检查接线是否松动、转换器是否损坏、电表通信端子是否有电。
  • 红外:确保红外适配器已正确安装驱动,并被系统识别为串口。尝试稍微调整角度和距离。有些电表的红外接收窗口有保护膜,记得撕掉。
  • 电源:确保电表本身已上电。有些电表在断电后通信模块也不工作。

第二步:确认串口参数与操作

  • 三核对波特率、数据位、停止位、校验位。一个字符都不能错。最常见的就是校验位设成了“无”或“奇校验”。
  • 确认你选择的串口号是对的(在设备管理器里查看),并且没有被其他软件占用。
  • 发送时,务必是HEX格式,而不是文本格式。发送AA和发送字符串“AA”是天壤之别。

第三步:尝试所有可能的波特率

  • 依次尝试1200,2400,4800,9600,19200。645协议常用24009600;698协议常用2400,9600,19200。红外接口有时会用1200这个较低的速率。
  • 每次更换波特率后,重新打开串口,再发送指令。

第四步:调整广播指令细节

  • 前导帧:试试多发几个FE,比如FE FE FE FE FE。也试试不发前导帧,直接发68开头的帧。
  • 指令间隔:连续快速发送指令可能会让电表处理不过来。在两条指令之间手动添加500ms到1秒的间隔。
  • 指令本身:从网上或不同资料里找到的广播指令字节可能略有差异(特别是698协议),可以多找一两个版本试试。

第五步:终极判断如果以上所有方法(两种协议、多种波特率、多种指令变体)都试遍了,依然没有任何回复,那么极有可能:

  1. 电表不支持DLT645/698协议:尤其是一些非常老旧的表,或者某些出口到特殊地区的表。它们可能只支持厂家私有的Modbus RTU协议,或者其他非标协议。这时你必须找到电表的原版说明书,按照它的协议来。
  2. 通信接口硬件故障:可能是电表内部的通信芯片或光耦坏了,也可能是你的转换器坏了。有条件的话,换一个同型号的好电表,或者换一个转换器交叉测试一下。

我遇到过最棘手的一次,是一个工地上的电表,怎么都读不出来。最后发现,电表厂商为了“省事”,把RS485的A、B线定义反了,而且还在内部串了一个非标准的电阻。按照说明书接就不通,把A、B线对调一下,立刻通了。所以,实践出真知,千万别完全迷信说明书。

6. 从地址读取到数据采集:下一步做什么?

恭喜你!当你成功读取到那6字节的地址时,最艰难的一步已经迈过去了。这个地址是你的“通行证”。接下来,你就可以进行真正的数据采集了。

对于DLT645协议,你想读电压,就查协议文档里的“数据标识码”,比如0x02010100代表A相电压。构造一个数据域包含此标识码的帧,用真实地址替换广播地址发送出去,电表就会回复电压值。解析回复时,同样要注意数据域的“减33H”规则和数据的单位(比如电压可能是0.01V/位)。

对于DLT698协议,世界更丰富但也更复杂。你需要查阅它的“对象字典”,找到对应数据项的OAD。比如,总有功电能的OAD可能是00 00 01 00。然后构造类似的GetRequestNormal帧去请求。698协议的数据类型非常丰富,有浮点数、整数、字符串、数组等,解析时需要根据返回的“数据类型标签”来正确处理。

最后给个真心建议:动手操作时,准备一个笔记本,或者建一个Excel表格,记录下每块电表的型号、通信地址、使用的协议、有效的波特率。这些信息在日后维护、扩容时会让你省下大量重复调试的时间。协议通信就像和电表对话,第一次握手成功建立了信任,后面的交流就会顺畅很多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 17:21:00

实战指南:利用CapSolver API高效破解reCAPTCHA v2验证码

1. 为什么你需要一个靠谱的验证码解决方案? 如果你做过网络爬虫,或者开发过需要自动登录、自动提交表单的程序,那你一定对那个小小的“我不是机器人”复选框恨得牙痒痒。没错,我说的就是 reCAPTCHA v2。这个由谷歌推出的验证码系统…

作者头像 李华
网站建设 2026/7/14 17:21:02

C++优先队列priority_queue自定义排序的5种实战方法(附完整代码示例)

C优先队列自定义排序:从基础到实战的深度探索 如果你在算法竞赛或者工程开发中用过C的优先队列,大概率会遇到这样一个场景:默认的大顶堆不够用,需要按照特定规则排序。这时候,自定义排序就成了必须掌握的技能。但很多人…

作者头像 李华
网站建设 2026/7/14 17:21:01

为什么BERT用12层而GPT-3要96层?解密Transformer堆叠层数背后的设计哲学

为什么BERT用12层而GPT-3要96层?解密Transformer堆叠层数背后的设计哲学 当我们翻开一篇篇关于Transformer模型的论文,或者浏览各种开源模型的配置时,一个直观的数字差异常常会引发我们的好奇:为什么同样是基于Transformer架构&am…

作者头像 李华
网站建设 2026/7/14 17:21:03

FunASR纯CPU离线转写实战:Docker+Nginx高并发部署与前端界面优化

1. 环境准备与核心思路 大家好,我是老张,在AI和智能硬件这块摸爬滚打了十来年,今天想和大家聊聊一个非常实用的项目:如何在只有CPU的服务器上,稳稳当当地部署一个高并发的离线语音转写服务。我知道很多朋友的公司或者个…

作者头像 李华
网站建设 2026/7/14 17:21:14

边缘智能:2026年AIoT场景下的轻量化推理框架实战

引言:边缘计算的"最后一公里"困境在2026年的AIoT时代,超过60%的智能设备需要在边缘侧完成实时推理。传统云端推理面临三大核心挑战:网络延迟不可控(平均往返时延>200ms)、数据隐私泄露风险(医…

作者头像 李华