瀏覽代碼

1、DLT645-2007加入前导码,只需根据修改DL645_PREMBLE_LEN长度即刻;
2、新增6个0xAA为万能地址,该地址可以直接操作各个功能码;

liangzohar 2 年之前
父節點
當前提交
a24b91b5ee
共有 8 個文件被更改,包括 43 次插入17 次删除
  1. 2 1
      inc/dlt645_2007_private.h
  2. 10 5
      inc/dlt645_private.h
  3. 5 2
      port/dlt645_port.c
  4. 8 0
      readme.md
  5. 1 1
      sample/dlt645_sample.c
  6. 3 3
      src/dlt645.c
  7. 3 1
      src/dlt645_2007.c
  8. 11 4
      src/dlt645_data.c

+ 2 - 1
inc/dlt645_2007_private.h

@@ -1,8 +1,9 @@
 #ifndef __DLT645_2007_PRIVATE_H
 #define __DLT645_2007_PRIVATE_H
 
+#include "dlt645_private.h"
 
-#define DL645_2007_RD_CMD_LEN 16 //读取数据命令的长度
+#define DL645_2007_RD_CMD_LEN (DL645_PREMBLE_LEN + 16) //读取数据命令的长度
 
 //功能码
 #define C_2007_CODE_BRC 0x08    //广播校时

+ 10 - 5
inc/dlt645_private.h

@@ -12,13 +12,18 @@
 #define DL645_START_CODE 0x68
 #define DL645_STOP_CODE 0x16
 
-#define DL645_PREMBLE_ENABLE 0 //前导码使能标记
-#define DL645_PREMBLE 0xFE     //前导码
+#define DL645_GADDR_CODE 0xAA   //万能地址码
+#define DL645_PREMBLE_CODE 0xFE //前导码
 
+#define DL645_PREMBLE_LEN 0 //前导码长度
 #define DL645_ADDR_LEN 6    //设备地址长度
-#define DL645_CONTROL_POS 8 //控制码位置
-#define DL645_LEN_POS 9     //长度位置
-#define DL645_DATA_POS 10   //数据位置
+
+#define DL645_START_POS (DL645_PREMBLE_LEN + 0)
+#define DL645_ADDR_POS (DL645_PREMBLE_LEN + 1)    //设备地址
+#define DL645_CONTROL_POS (DL645_PREMBLE_LEN + 8) //控制码位置
+#define DL645_LEN_POS (DL645_PREMBLE_LEN + 9)     //长度位置
+#define DL645_DATA_POS (DL645_PREMBLE_LEN + 10)   //数据位置
+
 #define DL645_WR_LEN 50     //写入数据命令的长度
 #define DL645_RESP_LEN 60   //读取数据命令的长度
 

+ 5 - 2
port/dlt645_port.c

@@ -99,7 +99,10 @@ static int dlt645_hw_read(dlt645_t *ctx, uint8_t *msg ,uint16_t len)
 static int dlt645_hw_write(dlt645_t *ctx, uint8_t *buf, uint16_t len)
 {
     //串口发送数据
-    return rt_device_write(dlt645_device,0,buf,len);
+    rt_pin_write(GET_PIN(A,15), PIN_HIGH);
+    int ret = rt_device_write(dlt645_device,0,buf,len);
+    rt_pin_write(GET_PIN(A,15), PIN_LOW);
+    return ret;
 }
 
 
@@ -152,7 +155,7 @@ int dlt645_port_init(void)
 }
 
 //645结构体注册
-static dlt645_t dlt645 = {
+dlt645_t dlt645 = {
     {0},
     0,
     dlt645_hw_write,

+ 8 - 0
readme.md

@@ -416,3 +416,11 @@ int main(void)
 }
 
 ```
+
+## 五、注意事项
+
+1. 目前插件不支持自动识别前导码,不会自动拼包或者过滤处理;
+2. 如果串口有数据输出和输入但是打印读取失败,考虑是前导码的问题,不同厂商的仪表会有长度不一的前导码。
+ - 可以用PC工具发送68开头的数据:68 AA AA AA AA AA AA 68  11 04 33 34 34 35 B1 16
+ - 返回的报文68开头前的FE个数就是前导码的长度,然后配置DL645_PREMBLE_LEN即刻。
+

+ 1 - 1
sample/dlt645_sample.c

@@ -17,7 +17,7 @@
 //dlt645 采集测试标识符 (A相电压)
 #define DLT645_2007_READ_TEST_CODE 0x02010100
 #define DLT645_1997_READ_TEST_CODE 0xB611
-uint8_t test_addr[6] = {0x00,0x00,0x00,0x00,0x00,0x01};
+uint8_t test_addr[6] = {0xAA,0xAA,0xAA,0xAA,0xAA,0xAA};
 
 /**
  * Name:    dlt645_read_test

+ 3 - 3
src/dlt645.c

@@ -55,10 +55,10 @@ int dlt645_receive_msg(dlt645_t *ctx, uint8_t *msg, uint16_t len, uint32_t code,
  */
 int dlt645_send_msg(dlt645_t *ctx, uint8_t *msg, int len)
 {
-    msg[0] = DL645_START_CODE;
-    msg[DL645_ADDR_LEN + 1] = DL645_START_CODE;
+    msg[DL645_START_POS] = DL645_START_CODE;
+    msg[DL645_START_POS + DL645_ADDR_LEN + 1] = DL645_START_CODE;
     msg[len - 1] = DL645_STOP_CODE;
-    msg[len - 2] = _crc(msg, len - 2);
+    msg[len - 2] = _crc(msg + DL645_PREMBLE_LEN, len - DL645_PREMBLE_LEN - 2);
 
     return ctx->write(ctx, msg, len);
 }

+ 3 - 1
src/dlt645_2007.c

@@ -170,7 +170,8 @@ int dlt645_2007_read_data(dlt645_t *ctx,
     memset(read_buf, 0, sizeof(read_buf));
     memset(send_buf, 0, sizeof(send_buf));
 
-    memcpy(send_buf + 1, ctx->addr, DL645_ADDR_LEN);
+    memset(send_buf, DL645_PREMBLE_CODE, DL645_PREMBLE_LEN);
+    memcpy(send_buf + DL645_ADDR_POS, ctx->addr, DL645_ADDR_LEN);
 
     send_buf[DL645_CONTROL_POS] = C_2007_CODE_RD;
     send_buf[DL645_LEN_POS] = 4;
@@ -182,6 +183,7 @@ int dlt645_2007_read_data(dlt645_t *ctx,
     send_code[3] = ((code >> 24) & 0xff) + 0x33;
 
     memcpy(send_buf + DL645_DATA_POS, send_code, 4);
+
     if (dlt645_send_msg(ctx, send_buf, DL645_2007_RD_CMD_LEN) < 0)
     {
         DLT645_LOG("send data error!\n");

+ 11 - 4
src/dlt645_data.c

@@ -56,15 +56,15 @@ int dlt645_common_check(uint8_t *msg, int len, uint8_t *addr)
         return -1;
     }
     //数据帧标志校验
-    if (msg[0] != DL645_START_CODE ||
-        msg[DL645_ADDR_LEN + 1] != DL645_START_CODE ||
+    if (msg[DL645_START_POS] != DL645_START_CODE ||
+        msg[DL645_START_POS + DL645_ADDR_LEN + 1] != DL645_START_CODE ||
         msg[len - 1] != DL645_STOP_CODE)
     {
         DLT645_LOG("check code error!\n");
         return -1;
     }
     //CRC校验
-    uint8_t crc = _crc(msg, len - 2);
+    uint8_t crc = _crc(msg + DL645_PREMBLE_LEN, len - DL645_PREMBLE_LEN - 2);
     if (crc != msg[len - 2])
     {
         DLT645_LOG("check crc error!\n");
@@ -85,7 +85,14 @@ int dlt645_common_check(uint8_t *msg, int len, uint8_t *addr)
     //从站地址校验
     if (memcmp(msg + 1, addr, 6) != 0)
     {
-        return -1;
+        // 万能地址无需校验
+        for(int i = 0; i < 6; i++)
+        {
+            if(addr[i] != DL645_GADDR_CODE)
+            {
+                return -1;
+            }
+        }
     }
 
     return 0;