本文主要是介绍1.3 DLT645,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、简介
目前市面的大部分的电表,通信都是遵循该协议。因为物理层使用RS-485,故为半双工通信,主站指终端设备,从站指多功能电能表。
数据链路层,默认波特率2400,偶校验,8bit数据,1bit停止位。先传低位,后传高位。D0是字节最低有效位,D7是字节最高有效位,如下图所示
帧格式如下表所示
说明 | 帧起始符 | 地址域 | 帧起始符 | 控制码 | 数据域长度 | 数据域 | 校验码 | 结束符 |
---|---|---|---|---|---|---|---|---|
字节 | 0x68 | A0~A5 | 0x68 | C | L | DATA | CS | 0x16 |
1、帧起始符 | ||||||||
固定0x68。 | ||||||||
2、地址域 | ||||||||
由6个字节A0~A5构成,每个字节2位BCD码,故地址长度为12位十进制数,当地址码长度不足6字节时,高位用0补足。通讯地址0x9999 9999 9999时,为广播地址。特殊的是,地址域支持锁位寻址,从若干低位起,剩余高位补0xAA,作为通配符进行读表操作,从站应答帧会返回实际通信地址。 | ||||||||
什么是BCD码,我们知道,正常情况下,二进制、十进制、十六进制之间有一套转化的算法,例如18=0x12=10010。但是BCD码不同,它用四位二进制来表示十进制,最常用的是8421BCD码,例如8=1000,7=0111,为了方便,还是习惯把二进制用十六进制来表示,故8=0x8,7=0x7,但是问题来了,10怎么用BCD码表示,0xA?不是的,10用BCD表示是0x10。因为1的BCD码是0001,0的BCD码是0000,故10的BCD码是0001 0000,为了方便,表示为16进制,故为0x10。显然,9876的BCD码是0x9876。所以用BCD码的好处就是直观,这在工业领域大量的被应用。 | ||||||||
上面讲的是BCD码是压缩BCD码,它使用4位标识一个十进制数,1个字节可以表示2位十进制数。而非压缩BCD码使用1个字节来表示,故其高4位永远是0,1个字节只能表示1位十进制数。 | ||||||||
3、控制码C | ||||||||
用来表示帧的功能,具体如下所示: | ||||||||
例如,0x11代表读电表的数据, | ||||||||
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | |
– | – | – | – | – | – | – | – | |
0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | |
0x91代表电表返回的数据 | ||||||||
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | |
– | – | – | – | – | – | – | – | |
1 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | |
4、数据域长度L | ||||||||
表示数据域的字节数,读数据时,L<=200,写数据时,L<=50。L=0,表示没有数据域。 | ||||||||
5、数据域DATA | ||||||||
数据域并不仅仅只包括数据,它还包括数据标识、密码、操作者代码、帧序号等。它的结构随着控制码而改变。在传输过程中,发送方需要对数据域的字节加0x33,再发送,接收方接收到数据域之后,需要对字节减0x33,方才得到原始数据。 | ||||||||
6、校验码CS | ||||||||
校验码是把从帧起始符开始算起,到校验码之前的所有字节求和,然后再取模256。即求和后,只取结果的最低1字节的数据。例如,假设地址为0xAAAA AAAA AAAA,控制码为0x11,数据域长度0x04,数据域0x33,0x34,0x34,0x35。那么该帧的校验码为0x68+0xAA*6+0x68+0x11+0x04+0x33+0x34+0x34+0x35=0x5B1。再取模256,即0xB1,则CS=0xB1。注意,其中的数据域0x33,0x34,0x34,0x35都是已经加上了0x33,原始数据其实是0x00,0x01,0x01,0x02。 | ||||||||
7、结束符 | ||||||||
固定0x16。 |
二、实例
power:{0xFE,0xFE,0xFE,0xFE,0x68,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x68,0x11,0x04,0x33,0x33,0x33,0x33,0xAD,0x16};
volt:{0xFE,0xFE,0xFE,0xFE,0x68,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x68,0x11,0x04,0x33,0x34,0x34,0x35,0xB1,0x16};
curr:{0xFE,0xFE,0xFE,0xFE,0x68,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x68,0x11,0x04,0x33,0x34,0x35,0x35,0xB2,0x16};
energy:{0xFE,0xFE,0xFE,0xFE,0x68,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x68,0x11,0x04,0x33,0x33,0x36,0x35,0xB2,0x16};
上面是4个获取数据的命令,分别是功率、电压、电流和电能。根据协议依次来分析。
curr:{0xFE,0xFE,0xFE,0xFE,0x68,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x68,0x11,0x04,0x33,0x34,0x35,0x35,0xB2,0x16};
开头的4个0xFE是唤醒命令,目的为了唤醒电表。
地址域为6个0xAA,表明这是广播地址。
控制码为0x11,表明是从主站发出的,读数据的命令。
数据域长度为0x04,表明后面跟的数据域有4个字节。
数据域为0x33,0x34,0x35,0x35,注意该协议传送数据时是低字节在前,高字节在后。因为传送时,数据域要加0x33,故实际的数据为DI0:0x00,DI1:0x01,DI2:0x02,DI3:0x02。
由下表可知,显然它对应着获取电流,同时为A相电流。
从机返回,以获取电压为例,
68 47 73 00 03 16 00 68 11 04 33 32 34 35 86 16
68 47 73 00 03 16 00 68 91 0A 33 32 34 35 74 56 85 56 7C 56 83 16
第一行是主机向从机发送了获取电压的命令,一共获取A、B、C三相电压。
第二行是从机返回主机的数据,注意数据长度是0A,这其中不仅只包括A、B、C三相电压,同时还包括,数据标识,千万别忘了这一点。
三、DLT645扩展协议
因为DLT645标准的计量范围只能到999.9,无法超过1000V,故诞生了扩展协议,扩大了计量范围。
这篇关于1.3 DLT645的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!