热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

phpdlt645,RTThreadMirror

DLT645采集软件包使用说明本软件包用于DLT645协议的采集与数据处理。在硬件层的移植(主要针对于串口收发数据)完成之后,用户仅需调用一个API即可完成针对于特定

DL/T 645 采集软件包使用说明

本软件包用于 DL/T 645 协议的采集与数据处理。在硬件层的移植(主要针对于串口收发数据)完成之后, 用户仅需调用一个API即可完成针对于特定协议(DL/T 1997 或 DL/T 2007)的标识符数据读取、处理与存储。 使用户无需关注请求数据的封包与接收数据的解包等复杂的协议内部操作,真正做到 一键采集 。

当然,由于本人精力有限,无法第一时间考虑并编写所有可能的情况与功能,所以在软件包的初期其功能只是根据我所用到的功能进行编写,无法涵盖所有的需求。并且可能会有一些小问题。但本文档今后会加入详细的功能开发指南,供开发成员们能够很方便地根据自己的需求进行功能的添加与修改。随着时间的推移,本软件包会逐步趋向于完善,也希望使用本软件包的开发人员们能够加入到软件包的完善中来,为该软件包的成长提供一份宝贵的力量!

目前支持的功能:

DL/T 645 1997 版数据采集与部分标识符数据解析

DL/T 645 2007 版数据采集与部分标识符数据解析

标识符的解析提供了便捷的接口,用户可以调用该接口实现自己所需标识符的解析功能

目前还不支持数据写入功能

一、软件包使用说明

在使用软件包之前, 需要把 src 目录下的所有源文件加入工程,将 inc 添加到头文件目录,并且参照 port 路径下的 dlt645_port.c 源文件实现基于用户使用的硬件平台的底层硬件操作的移植。scons现在默认不会将port文件加入到工程中,使用时需在工程的其他目录下手动加入。(详细的移植方法会在下文进行描述)

当完成硬件接口移植后,可以参照以下步骤进行对软件包的使用:

调用用户实现的硬件接口初始化用于DLT645采集的硬件,并注册645环境结构体。

调用 dlt645_set_addr() 函数设置需要采集的从机设备地址。(函数详细说明请阅读 API详解 )

调用 dlt645_read_data() 函数进行具体标识符数据的读取并存储到用户指定的地址下。(函数详细说明请阅读 API详解 )

二、软件包移植指南

软件包提供了完备的基于DL/T 645协议的数据包封包与解包操作,而用户则需要根据自己的平台给软件包提供底层数据的发送与接收接口,让软件包能够接收到数据并且成功发送出去。下面就来详细介绍一下软件包的移植操作。如文字描述有概念模糊或者不理解的地方可以参考本节下方的移植案例。

移植步骤

初始化用于dlt645协议通信的硬件。(如串口)

定义一个dlt645结构体作为dlt645通信的环境结构体。

实现数据发送与接收函数。(发送和接收单位为一个数据包)

将数据发送与接收函数注册到dlt645环境结构体中。

环境结构体:

环境结构体是本软件包运行时的内核对象,内核在工作中会调用其中的数据及接口,因此,用户提供的接口也需要注册到该结构体中。其结构如下:

typedef struct dlt645

{

uint8_t addr[6]; //从机地址

uint8_t debug; //调试标志

int (*write)(struct dlt645 *ctx, uint8_t *buf, uint16_t len); //底层写函数

int (*read) (struct dlt645 *ctx, uint8_t *msg, uint16_t len); //底层读函数

void *port_data; //移植层拓展接口

} dlt645_t;

成员

说明

addr

从机六位地址数组

debug

内核调试开关标志

write

硬件层写数据接口(用户提供)

read

硬件层读数据接口(用户提供)

port_data

用户拓展接口

数据发送接口:

接口格式:

int (*write)(struct dlt645 *ctx, uint8_t *buf, uint16_t len);

详细介绍:

在用户想要 读/写 从机设备时软件包内核需要调用该接口发送相应的指令帧,用户需要针对于自己的硬件平台来实现该函数。该函数会传入三个参数:

ctx: 为dlt645环境结构体;

buf: 为待发送的数据首地址;

len: 为要发送的长度。

数据接收接口:

接口格式:

int (*read) (struct dlt645 *ctx, uint8_t *msg, uint16_t len);

详细介绍:

当内核成功发送一个命令后,会立刻调用该接口进行从机设备回应数据的读取,调用时会传入三个参数:

ctx: 为dlt645环境结构体;

msg: 为接收到数据的存储地址;

len: 为允许接收数据的最大长度。

其中 len 参数标志着本次接收的最大长度,用户要注意对接收数据长度进行判断,若实际接收长度大于传入的允许接收数据最大长度,用户应该 视本次数据接收无效,返回0。

拓展接口

在 dlt645 结构体中提供了一个 port_data 成员字段,其类型为 void * ,用户可以利用此字段创建针对于自身应用的结构体,从而拓展更多的接口和数据字段,实现更为复杂的硬件操作。

移植案例

/*************************************************

Copyright (c) 2019

All rights reserved.

File name: dlt645_port.c

Description: DLT645 移植&使用例程文件

History:

1. Version:

Date: 2019-09-19

Author: wangjunjie

Modify:

*************************************************/

#include "dlt645.h"

#include "rtthread.h"

#include "drv_gpio.h"

//DLT645采集使用的串口名

#define DLT645_SERIAL_NAME "uart4"

//DL/T 645硬件拓展结构体

typedef struct

{

rt_sem_t dlt645_sem; //用于串口接收的信号量

uint32_t byte_timeout; //字节间的超时时间

} dlt645_port_t;

static dlt645_port_t dlt645_port = {

.dlt645_sem = RT_NULL,

.byte_timeout = 10, //接收字节间超时时间

};

//dlt645 采集设备句柄

static rt_device_t dlt645_device = RT_NULL;

//dlt645 采集接收信号量

static struct rt_semaphore dlt645_receive_sem;

//串口配置参数

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: 接收数据存放地址

* @len: 数据最大接收长度

* Output: 读取数据的长度

*/

static int dlt645_hw_read(dlt645_t *ctx, uint8_t *msg ,uint16_t len)

{

//实际接收长度

int read_len = 0;

//清缓存变量

uint8_t buf = 0;

//清空缓存

while(rt_device_read(dlt645_device,0,&buf,1));

//等待串口接收到数据

if(rt_sem_take(&dlt645_receive_sem, 1000) == -RT_ETIMEOUT)

{

return 0;

}

//每次读取一个字节的数据

while (rt_device_read(dlt645_device, 0, msg + read_len, 1) == 1)

{

if(read_len > len)

{

return 0;

}

else

{

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: 实际发送的字节数,错误返回-1

*/

static int dlt645_hw_write(dlt645_t *ctx, uint8_t *buf, uint16_t len)

{

//串口发送数据

return rt_device_write(dlt645_device,0,buf,len);

}

/**

* 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)

{

rt_kprintf("cannot find device %s\r\n", DLT645_SERIAL_NAME);

return -RT_ERROR;

}

if (rt_device_open(dlt645_device, RT_DEVICE_FLAG_INT_RX) != RT_EOK)

{

rt_kprintf("cannot open device %s\r\n", DLT645_SERIAL_NAME);

return -RT_ERROR;

}

else

{

config.baud_rate = BAUD_RATE_9600;

config.data_bits = DATA_BITS_8;

config.stop_bits = STOP_BITS_1;

config.parity = PARITY_NONE;

/* 打开设备后才可修改串口配置参数 */

rt_device_control(dlt645_device, RT_DEVICE_CTRL_CONFIG, &config);

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;

}

else

{

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;

}

//645结构体注册

static dlt645_t dlt645 = {

{0},

0,

dlt645_hw_write,

dlt645_hw_read,

(void *)&dlt645_port};

三、API详解

1、设置从机地址

简介: 用户在通过645协议读取某设备的数据时,首先要通过该接口设置想要读取的从机的地址。

API格式:

void dlt645_set_addr(dlt645_t *ctx, uint8_t *addr);

参数:

参数名

介绍

ctx

645结构句柄

addr

6位地址数组

使用示例

//dlt645 环境结构体

extern dlt645_t dlt645;

//从机地址为111

uint8_t slave_addr[6] = {0x00,0x00,0x00,0x00,0x01,0x11};

dlt645_set_addr(&dlt645,slave_addr);

2、读取数据

简介: 用户通过调用该接口读取从机指定标识符的数据

API格式:

int dlt645_read_data(dlt645_t *ctx, uint32_t code, uint8_t *read_data, dlt645_protocal protocal);

参数:

参数名

描述

ctx

645结构句柄

code

标识符

read_data

读取数据的存储地址(注意地址长度为4字节)

protocal

指定协议类型(可选 DLT645_2007 或 DLT645_1997 )

返回值

描述

整数

读取数据长度

-1

读取失败

read_data 参数为读取数据的存储地址,目前的版本中将所有的数据都转换为浮点数保存,(尚不支持超过4字节大小的数据,若有需要可以修改内核)因此 read_data 大小必须为4字节。后续版本会进行修改,从而支持任意大小。

protocal 参数指定了读取的协议类型,可选值为:DLT645_1997 和 DLT645_2007 ,分别对应1997版与2007版。

使用示例

//dlt645 环境结构体

extern dlt645_t dlt645;

//dlt645 采集测试标识符 (A相电压)

#define DLT645_2007_READ_TEST_CODE 0x02010100

//用于存放读取数据的数组

uint8_t read_buf[4];

//读取数据

if (dlt645_read_data(&dlt645,DLT645_2007_READ_TEST_CODE,read_buf,DLT645_2007) > 0)

{

printf("读取成功,A相电压值为: %.2f\r\n",*(float *)read_buf);

}

else

{

rt_kprintf("读取失败\r\n");

}

四、使用案例

/*************************************************

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

uint8_t test_addr[6] = {0x00,0x00,0x00,0x00,0x00,0x01};

/**

* 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);

//设置从机地址

dlt645_set_addr(&dlt645,test_addr);

//if(dlt645_read_data(&dlt645,DLT645_1997_READ_TEST_CODE,read_buf,DLT645_1997) > 0) //1997采集测试

if(dlt645_read_data(&dlt645,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);

}

}



推荐阅读
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • CentOS 6.5安装VMware Tools及共享文件夹显示问题解决方法
    本文介绍了在CentOS 6.5上安装VMware Tools及解决共享文件夹显示问题的方法。包括清空CD/DVD使用的ISO镜像文件、创建挂载目录、改变光驱设备的读写权限等步骤。最后给出了拷贝解压VMware Tools的操作。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
author-avatar
网吧b国漫救星
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有