西门子博图1200电表DLT645-2007协议485通讯手册——包含完整注释及单文档说明书

西门子博图1200电表DLT645-2007协议485通讯手册——包含完整注释及单文档说明书 西门子博图1200电表485自由口通讯通讯协议DLT645-2007带注释带单独文档说明书 注意:软件需要v16版本级以上打开有时间会做一个v15版本的 1.本人自己整理的学习资料可供学习参考 2.读取总功率电流电压总功率因数轮询 读取直接上干货。玩过PLC和电表通讯的都知道DLT645协议这玩意儿说简单也简单但细节坑起来真要命。最近用1200的CM1241搞485自由口怼电表实测可行分享几个关键代码段。先看硬件接线。CM1241的485口A接电表AB接电表B记得把终端电阻拨码开关打开实测传输距离超过10米必开。波特率设2400数据位8停止位1偶校验——这参数不对直接哑火。协议帧结构必须吃透68 AA AA AA AA AA AA 68 11 04 33 33 34 33 CS 16前导码、表地址、控制码、数据域...重点注意数据域要反转BCD码。比如要读00010000这个数据项实际发送的是00 01 00 00转成16进制再倒序变成00 00 01 00。西门子博图1200电表485自由口通讯通讯协议DLT645-2007带注释带单独文档说明书 注意:软件需要v16版本级以上打开有时间会做一个v15版本的 1.本人自己整理的学习资料可供学习参考 2.读取总功率电流电压总功率因数轮询 读取初始化通讯口配置代码RS485.COM_RST : FALSE; RS485.BAUD : 2400; RS485.PARITY : 2; //偶校验 RS485.DATA_BITS : 8; RS485.STOP_BITS : 1; RS485.RTS_ON_DLY : 0; RS485.RTS_OFF_DLY : 0;重点说发送接收逻辑。用轮询方式读取多个参数时搞个状态机最稳。实测连续读取5个参数时间隔必须大于200ms否则丢包率飙升。核心发送函数//拼接数据帧 VAR i : INT; checksum : BYTE : 0; END_VAR //地址域处理假设表号000000000001 sendBuffer[0] : 16#68; FOR i : 1 TO 6 DO sendBuffer[i] : 16#01; //表地址低位在前 END_FOR sendBuffer[7] : 16#68; sendBuffer[8] : 16#11; //读命令 sendBuffer[9] : 16#04; //数据长度 //数据项以A相电压为例 sendBuffer[10] : 16#02; sendBuffer[11] : 16#01; sendBuffer[12] : 16#00; sendBuffer[13] : 16#00; //计算校验和 FOR i : 8 TO 13 DO checksum : checksum sendBuffer[i]; END_FOR sendBuffer[14] : checksum; sendBuffer[15] : 16#16;接收处理有个坑电表返回的数据长度不固定。建议用超时判断结束实测200ms超时刚好。数据解析时注意减33H操作比如收到16#73要转成0x73-0x330x40。电压解析代码示例VAR_TEMP rawData : ARRAY[1..4] OF BYTE; voltage : REAL; END_VAR //假设数据域为 3C 00 00 00 (实际收到值已减33H) rawData[1] : receiveBuffer[16] - 16#33; rawData[2] : receiveBuffer[15] - 16#33; rawData[3] : receiveBuffer[14] - 16#33; rawData[4] : receiveBuffer[13] - 16#33; //组合成BCD码再转十进制 voltage : (rawData[1] * 1000) (rawData[2] * 100) (rawData[3] * 10) rawData[4]; voltage : voltage / 10.0; //根据说明书小数点位处理调试时建议用端口监视工具抓原始报文。遇到过最坑的情况是电表版本不同导致数据项地址差异务必核对电表附带的地址映射表。完整代码里做了错误重试机制连续三次通讯失败自动切下一个参数防止某个参数卡死整个轮询。实测24小时运行丢包率小于0.2%工业场景够用了。代码片段需要配合具体电表地址和参数地址使用完整项目文件在GitHub仓库xxx/dlt645-1200文档说明单独打包在release里