Parcourir la source

2019-09-23 第二次更新
1、修改文件结构
2、增加sample

WKJay il y a 6 ans
Parent
commit
58337d8aee
9 fichiers modifiés avec 157 ajouts et 65 suppressions
  1. 2 0
      inc/dlt645_private.h
  2. 35 27
      port/dlt645_port.c
  3. 10 0
      port/dlt645_port.h
  4. 0 4
      sample/dlt645_port.h
  5. 57 0
      sample/sample.c
  6. 4 3
      src/dlt645.c
  7. 4 10
      src/dlt645_1997.c
  8. 10 20
      src/dlt645_2007.c
  9. 35 1
      src/dlt645_data.c

+ 2 - 0
inc/dlt645_private.h

@@ -72,4 +72,6 @@ extern int dlt645_send_msg(dlt645_t *ctx, uint8_t *msg, int len);
 extern uint32_t dec2bcd(uint32_t val);
 //将接收到的dlt645数据包中的数据转化为整数
 extern int data_package_translate_to_int(uint8_t *read_data, uint16_t len);
+//根据数据格式将645协议读取的数据转换为真实数据并存储
+extern int dlt645_data_parse_by_format_to_float(uint8_t *read_data, uint16_t read_len, const char *data_format, uint8_t *store_address);
 #endif

+ 35 - 27
sample/dlt645_port.c → port/dlt645_port.c

@@ -15,8 +15,6 @@
 
 //DLT645采集使用的串口名
 #define DLT645_SERIAL_NAME "uart4"
-//dlt645 采集测试标识符 (A相电压)
-#define DLT645_READ_TEST_CODE 0x2010100
 
 //DL/T 645硬件拓展结构体
 typedef struct
@@ -27,70 +25,79 @@ typedef struct
 
 static dlt645_port_t dlt645_port = {
     .dlt645_sem = RT_NULL,
-    .byte_timeout = 20,
+    .byte_timeout = 10, //接收字节间超时时间
 };
 //dlt645 采集设备句柄
 static rt_device_t dlt645_device = RT_NULL;
 //dlt645 采集接收信号量
 static struct rt_semaphore dlt645_receive_sem;
-//dlt645 环境结构体
-dlt645_t dlt645;
 //串口配置参数
 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+//dlt645 环境结构体
+dlt645_t dlt645;
 
 //串口接收数据回调函数
 rt_err_t uart_handler(rt_device_t dev, rt_size_t size)
 {
+    //接收到一个数据释放信号量
     rt_sem_release(&dlt645_receive_sem);
     return RT_EOK;
 }
 
-//硬件层接收函数
+/**
+ * Name:    dlt645_hw_read
+ * Brief:   dlt645 硬件层接收数据
+ * Input:
+ *  @ctx:   645运行环境
+ *  @msg:   接收数据存放地址
+ * Output:  None
+ */
 static int dlt645_hw_read(dlt645_t *ctx, uint8_t *msg)
 {
     int read_len = 0;
+    //等待串口接收到数据
     if(rt_sem_take(&dlt645_receive_sem, 1000) == -RT_ETIMEOUT)
     {
         return 0;
     }
+    //每次读取一个字节的数据
     while (rt_device_read(dlt645_device, 0, msg + read_len, 1) == 1)
     {
         read_len ++;
-        //读取超时标志一读取完成
+        //读取超时标志一帧数据读取完成
         if (rt_sem_take(&dlt645_receive_sem, ((dlt645_port_t *)(ctx->port_data))->byte_timeout) == -RT_ETIMEOUT)
         {
             break;
         }
     }
-
     return read_len;
 }
 
-//硬件层发送函数
+/**
+ * Name:    dlt645_hw_write
+ * Brief:   dlt645 硬件层发送数据
+ * Input:
+ *  @ctx:   645运行环境
+ *  @buf:   待发送数据
+ *  @len:   发送长度
+ * Output:  None
+ */
 static int dlt645_hw_write(dlt645_t *ctx, uint8_t *buf, uint16_t len)
 {
+    //串口发送数据
     return rt_device_write(dlt645_device,0,buf,len);
 }
 
-static void dlt645_read_test(void)
-{
-    uint8_t read_buf[4];
-    rt_memset(read_buf, 0, 4);
-
-    if(dlt645_read_data(&dlt645,1,DLT645_READ_TEST_CODE,read_buf,DLT645_2007) > 0)
-    {
-        printf("读取成功,A相电压值为: %.1f \r\n",*(float *)read_buf);
-    }
-    else
-    {
-        rt_kprintf("读取失败\r\n");
-    }
-    
-}
-MSH_CMD_EXPORT(dlt645_read_test , dlt645 protocal read test);
 
+/**
+ * Name:    dlt645_port_init
+ * Brief:   645采集硬件层初始化
+ * Input:   None
+ * Output:  None
+ */
 int dlt645_port_init(void)
 {
+    //串口初始化
     dlt645_device = rt_device_find(DLT645_SERIAL_NAME);
     if (dlt645_device == RT_NULL)
     {
@@ -113,6 +120,7 @@ int dlt645_port_init(void)
         rt_kprintf("device %s open success \r\n", DLT645_SERIAL_NAME);
     }
 
+    //信号量初始化
     if (rt_sem_init(&dlt645_receive_sem, "receive_sem", 0, RT_IPC_FLAG_FIFO) == RT_EOK)
     {
         dlt645_port.dlt645_sem = &dlt645_receive_sem;
@@ -122,12 +130,12 @@ int dlt645_port_init(void)
         return -RT_ERROR;
     }
 
-    /* 设置接收回调函数 */
+    //设置串口接收回调函数
     rt_device_set_rx_indicate(dlt645_device, uart_handler);
+    //485控制引脚初始化
     rt_pin_mode(GET_PIN(A,15),PIN_MODE_OUTPUT);
     return  RT_EOK;
 }
-INIT_APP_EXPORT(dlt645_port_init);
 
 //645结构体注册
 static dlt645_t dlt645 = {

+ 10 - 0
port/dlt645_port.h

@@ -0,0 +1,10 @@
+#ifndef __DLT645_PORT_H
+#define __DLT645_PORT_H
+#include "dlt645.h"
+
+//对外提供环境声明
+extern dlt645_t dlt645;
+//645采集硬件层初始化
+int dlt645_port_init(void);
+
+#endif

+ 0 - 4
sample/dlt645_port.h

@@ -1,4 +0,0 @@
-#ifndef __DLT645_PORT_H
-#define __DLT645_PORT_H
-
-#endif

+ 57 - 0
sample/sample.c

@@ -0,0 +1,57 @@
+/*************************************************
+ Copyright (c) 2019
+ All rights reserved.
+ File name:     sample.c
+ Description:   DLT645 软件包使用样例
+ History:
+ 1. Version:    
+    Date:       2019-09-23
+    Author:     wangjunjie
+    Modify:     
+*************************************************/
+#include "dlt645.h"
+#include "dlt645_port.h"
+
+//dlt645 采集测试标识符 (A相电压)
+#define DLT645_2007_READ_TEST_CODE 0x02010100
+#define DLT645_1997_READ_TEST_CODE 0xB611
+
+/**
+ * Name:    dlt645_read_test
+ * Brief:   dlt645协议采集测试程序
+ * Input:   None
+ * Output:  None
+ */
+static void dlt645_read_test(void)
+{
+    uint8_t read_buf[4];
+    rt_memset(read_buf, 0, 4);
+    
+    //if(dlt645_read_data(&dlt645,1,DLT645_1997_READ_TEST_CODE,read_buf,DLT645_1997) > 0) //1997采集测试
+    if(dlt645_read_data(&dlt645,1,DLT645_2007_READ_TEST_CODE,read_buf,DLT645_2007) > 0)  //2007采集测试
+    {
+        printf("读取成功,A相电压值为: %.2f \r\n",*(float *)read_buf);
+    }
+    else
+    {
+        rt_kprintf("读取失败\r\n");
+    }
+}
+
+/**
+ * Name:    main
+ * Brief:   主函数
+ * Input:   None
+ * Output:  None
+ */
+int main(void)
+{
+    //dlt645 硬件层初始化
+    dlt645_port_init();
+    while(1)
+    {
+        //采集测试
+        dlt645_read_test();
+        rt_thread_mdelay(1000);
+    }
+}

+ 4 - 3
src/dlt645.c

@@ -108,18 +108,19 @@ int dlt645_read_data(dlt645_t *ctx,
                      uint8_t *read_data,
                      dlt645_protocal protocal)
 {
+    int rs = -1;
     switch (protocal)
     {
     case DLT645_1997:
-        return dlt645_1997_read_data(ctx, addr, code, read_data);
+        rs = dlt645_1997_read_data(ctx, addr, code, read_data);
         break;
     case DLT645_2007:
-        return dlt645_2007_read_data(ctx, addr, code, read_data);
+        rs = dlt645_2007_read_data(ctx, addr, code, read_data);
         break;
     default:
         DLT645_LOG("unrecognized protocal!\r\n");
         break;
     }
-    return -1;
+    return rs;
 }
 

+ 4 - 10
src/dlt645_1997.c

@@ -66,19 +66,14 @@ static int dlt645_1997_parsing_data(uint32_t code, uint8_t *read_data, uint16_t
     case DIC_B692:
     case DIC_B693:
     {
-        int ival = data_package_translate_to_int(read_data,2);
-        float fval = ival / 1.0;
-        memcpy(real_val, &fval, 4);
+        dlt645_data_parse_by_format_to_float(read_data, 2, "XXX", real_val);
         break;
     }
     case DIC_B621:
     case DIC_B622:
     case DIC_B623:
     {
-        int ival = data_package_translate_to_int(read_data,2);
-        float fval = ival / 100.00;
-        memcpy(real_val, &fval, 4);
-
+        dlt645_data_parse_by_format_to_float(read_data, 2, "XX.XX", real_val);
         break;
     }
     case DIC_B630:
@@ -86,9 +81,8 @@ static int dlt645_1997_parsing_data(uint32_t code, uint8_t *read_data, uint16_t
     case DIC_B632:
     case DIC_B633:
     {
-        int ival = data_package_translate_to_int(read_data,3);
-        float fval = ival / 10000.0;
-        memcpy(real_val, &fval, 4);
+        dlt645_data_parse_by_format_to_float(read_data, 3, "XX.XXXX", real_val);
+        break;
     }
     default:
     {

+ 10 - 20
src/dlt645_2007.c

@@ -82,10 +82,7 @@ int dlt645_2007_parsing_data(uint32_t code, uint8_t *read_data, uint16_t len, ui
     case DIC_80000:
     case DIC_90000:
     {
-        int ival = data_package_translate_to_int(read_data,4);
-        float fval = ival / 100.00;
-        memcpy(real_val, &fval, 4);
-
+        dlt645_data_parse_by_format_to_float(read_data,4,"XXXXXX.XX",real_val);
         break;
     }
     case DIC_2010100:
@@ -95,20 +92,14 @@ int dlt645_2007_parsing_data(uint32_t code, uint8_t *read_data, uint16_t len, ui
     case DIC_20C0200:
     case DIC_20C0300:
     {
-        int ival = data_package_translate_to_int(read_data,2);
-        float fval = ival / 10.0;
-        memcpy(real_val, &fval, 4);
-
+        dlt645_data_parse_by_format_to_float(read_data,2,"XXX.X",real_val);
         break;
     }
     case DIC_2020100:
     case DIC_2020200:
     case DIC_2020300:
     {
-        int ival = data_package_translate_to_int(read_data,3);
-        float fval = ival / 1000.0;
-        memcpy(real_val, &fval, 4);
-
+        dlt645_data_parse_by_format_to_float(read_data,3,"XXX.XXX",real_val);
         break;
     }
     case DIC_2030000:
@@ -124,10 +115,7 @@ int dlt645_2007_parsing_data(uint32_t code, uint8_t *read_data, uint16_t len, ui
     case DIC_2050200:
     case DIC_2050300:
     {
-        int ival = data_package_translate_to_int(read_data,3);
-
-        float fval = ival / 10000.00;
-        memcpy(real_val, &fval, 4);
+        dlt645_data_parse_by_format_to_float(read_data,3,"XX.XXXX",real_val);
         break;
     }
     case DIC_2060000:
@@ -135,10 +123,12 @@ int dlt645_2007_parsing_data(uint32_t code, uint8_t *read_data, uint16_t len, ui
     case DIC_2060200:
     case DIC_2060300:
     {
-        int ival = data_package_translate_to_int(read_data,2);
-        float fval = ival / 1000.0;
-        memcpy(real_val, &fval, 4);
-
+        dlt645_data_parse_by_format_to_float(read_data,2,"X.XXX",real_val);
+        break;
+    }
+    case DIC_2800002:
+    {
+        dlt645_data_parse_by_format_to_float(read_data,2,"XX.XX",real_val);
         break;
     }
     case DIC_4000403:

+ 35 - 1
src/dlt645_data.c

@@ -10,6 +10,7 @@
     Modify:     
 *************************************************/
 #include "dlt645_private.h"
+#include <string.h>
 #include <math.h>
 
 //字节位置枚举类型
@@ -191,7 +192,40 @@ int data_package_translate_to_int(uint8_t *read_data, uint16_t len)
                 break;
             }
         } while (current_byte_part != BYTE_RESET);
-        current_index ++;
+        current_index++;
     }
     return i_value;
 }
+
+/**
+ * Name:    dlt645_data_parse_by_format_to_float
+ * Brief:   根据数据格式将645协议读取的数据转换为真实数据并存储
+ *          !真实数据为浮点数据,需要注意的是无论读取数据长度是多少,存储数据长度都应是4字节
+ * Input:
+ *  @read_data:     645协议读取的数据
+ *  @read_len:      读取数据的长度
+ *  @data_format:   转换的数据格式,如 XX.XX,XX.XXX
+ * Output:  转换成功返回0,失败返回-1
+ */
+int dlt645_data_parse_by_format_to_float(uint8_t *read_data, uint16_t read_len, const char *data_format, uint8_t *store_address)
+{
+    //权值
+    int num_weight = 0;
+    int ival = data_package_translate_to_int(read_data, read_len);
+
+    for (int i = 0; i < strlen(data_format); i++)
+    {
+        if (*(data_format + i) == '.')
+        {
+            num_weight = strlen(data_format) - i - 1;
+            if(num_weight < 0)
+            {
+                return -1;
+            }
+            break;
+        }
+    }
+    float fval = ival / pow(10,num_weight);
+    memcpy(store_address, &fval, 4);
+    return 0;
+}