Modbus库开发笔记之七:Modbus其他辅助功能开发
前面开发了各种应用,但是却一直没有提到一个问题,你就是对具体的数据进行读写操作。对于Modbus来说标准的数据有4种:线圈数据(地址:0000x)、输入状态量数据(地址:1000x)、保持寄存器数据(地址:4000x)和输入寄存器数据(地址:3000x)。我们通讯的目的就是为了对这些数据进行操作,可是我们前面的封装中并没有提到数据处理。事实上,也没办法考虑这一点,因为具体的应用数据千差万别,是没办法封装的。那我们怎么解决这一问题呢?接下来我们将解决这一类问题。
1、数据处理函数的封装
我们考虑到,不论是在RTU主站、RTU从站、TCP客户端、还是在TCP服务器对数据的处理本质上是一样的,只要具体应用的数据结构确定后处理方法也就确定了。鉴于此,我们采用的方法是定义弱化类型的函数。如下:
/*获取想要读取的Coil量的值*/
__weak void GetCoilStatus(uint16_t startAddress,uint16_t quantity,bool *statusList)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
/*获取想要读取的InputStatus量的值*/
__weak void GetInputStatus(uint16_t startAddress,uint16_t quantity,bool *statusValue)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
/*获取想要读取的保持寄存器的值*/
__weak void GetHoldingRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
/*获取想要读取的输入寄存器的值*/
__weak void GetInputRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
/*设置单个线圈的值*/
__weak void SetSingleCoil(uint16_t coilAddress,bool coilValue)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
/*设置单个寄存器的值*/
__weak void SetSingleRegister(uint16_t registerAddress,uint16_t registerValue)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
/*设置多个线圈的值*/
__weak void SetMultipleCoil(uint16_t startAddress,uint16_t quantity,bool *statusValue)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
/*设置多个寄存器的值*/
__weak void SetMultipleRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
/*更新读回来的线圈状态*/
__weak void UpdateCoilStatus(uint16_t startAddress,uint16_t quantity,bool *stateValue)
{
//在客户端(主站)应用中实现
}
/*更新读回来的输入状态值*/
__weak void UpdateInputStatus(uint16_t startAddress,uint16_t quantity,bool *stateValue)
{
//在客户端(主站)应用中实现
}
/*更新读回来的线圈状态*/
__weak void UpdateHoldingRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)
{
//在客户端(主站)应用中实现
}
/*更新读回来的线圈状态*/
__weak void UpdateInputResgister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)
{
//在客户端(主站)应用中实现
}
在开发具体应用时,我们只需要在应用中实现对应的函数就可以使功能完整,至于具体的数据如何处理,就要看具体应用中的数据格式了。当然这些函数并非都需要实现,只需要根据自己的需要实现就可以了。
2、关于大小端的问题
提到数据通讯,有一个问题是没有办法回避的,那就是大小端的问题。对于Modbus协议来说,采用的是大端模式,就是低位地址存高位字节数据,高位地址存低位字节数据。
在进行多字节数据通讯时,大小端的问题就明显了,比如一个浮点数在不同的系统中存储的顺序是有差别的,你读上来或者写下去的数据就会出现错误的解析。所以我们在处理数据报文时是必须考虑这一点的。
Modbus库开发笔记之七:Modbus其他辅助功能开发的更多相关文章
- Modbus库开发笔记:Modbus ASCII Master开发
这一节我们来封装Modbus ASCII Master应用,Modbus ASCII主站的开发与RTU主站的开发是一致的.同样的我们也不是做具体的应用,而是实现ASCII主站的基本功能.我们将ASCI ...
- CoolBlog开发笔记第2课:搭建开发环境
教程目录 1.1 CoolBlog开发笔记第1课:项目分析 前言 今天是CoolBlog开发笔记的第2课,我们将要讲解的是开发环境的搭建.俗话说"工欲善其事必先利其器",Djang ...
- Bytom Dapp 开发笔记(二):开发流程
简介 这章的内容详细分析一下涉及智能合约Dapp的整个开发流程,注意是涉及只能合约,如果你只要一些基本转BTM功能没有太大意义,本内容补充一下官方提供的 比原链DAPP开发流程,详细实践过好踩到的一些 ...
- Modbus库开发笔记:Modbus ASCII Slave开发
与Modbus RTU在串行链路上分为Slave和Master一样,Modbus ASCII也分为Slave和Master,这一节我们就来开发Slave.对于Modbus ASCII从站来说,需要实现 ...
- LwIP应用开发笔记之七:LwIP无操作系统HTTP服务器
前面我们实现了TCP服务器和客户端的简单应用,接下来我们实现一个基于TCP协议的应用协议,那就是HTTP超文本传输协议 1. HTTP协议简介 超文本传输协议(Hyper Text Transf ...
- PID控制器开发笔记之七:微分先行PID控制器的实现
前面已经实现了各种的PID算法,然而在某些给定值频繁且大幅变化的场合,微分项常常会引起系统的振荡.为了适应这种给定值频繁变化的场合,人们设计了微分先行算法. 1.微分先行算法的思想 微分先行PID控制 ...
- STM32F412应用开发笔记之七:片上ADC的应用测试
在我们的应用项目中需要采集一些模拟量,这些量使用MCU自带的ADC就可以满足要求.在NUCLEO-F412ZG实验板上的STM32F412ZG有一个16通道的ADC,我们试验用它采集几个数据. 在NU ...
- Modbus库开发笔记之十一:关于Modbus协议栈开发的说明
对于Modbus协议栈的整个开发内容,前面已经说得很清楚了,接下来我们说明一下与开发没有直接关系的内容. 首先,关于我为什么开发这个协议栈的问题.我们的初衷只是想能够在开发产品时不用每次都重写这一部分 ...
- firefox 扩展开发笔记(三):高级ui交互编程
firefox 扩展开发笔记(三):高级ui交互编程 前言 前两篇链接 1:firefox 扩展开发笔记(一):jpm 使用实践以及调试 2:firefox 扩展开发笔记(二):进阶开发之移动设备模拟 ...
随机推荐
- 20155324 2016-2017-2 《Java程序设计》第8周学习总结
20155324 2016-2017-2 <Java程序设计>第8周学习总结 教材学习内容总结 通用API -** 日志API** 1.~java.util.logging~包提供了日志功 ...
- ThinkPHP5.0.21&5.1.* 代码执行和命令执行漏洞利用
ThinkPHP5.0.21&5.1.* 代码执行和命令执行漏洞利用 ThinkPHP5.0.21&5.1.* exploit code execution and command ...
- 【译】第五篇 SQL Server安全架构和安全
本篇文章是SQL Server安全系列的第五篇,详细内容请参考原文. 架构本质上是一个数据库对象,其他对象的一个容器,在复杂的数据库中它能够很容易的管理各组对象.架构具有重要的安全功能.在这一篇你会学 ...
- 昨天看了一个大神的fix类,清晰了然
.fix::after{ content:''; display:table; clear:both; }
- Hibernate持久化
一.主键生成策略 1)主键分类:1.自然主键:主键本身就是表中的某一个字段,实体中的一个具体属性,对象本身唯一的特性. 例如:创建一个学生,把其身份证号设为主键 2.代理主键:本身不是表中的一个必须的 ...
- Kotlin中三元运算符
int a = 10;int b = 11;int c = a > b ? a : b; 到了 kotlin中 val a = 10val b = 11val c = if (a > b) ...
- HashSet、TreeSet和LinkedHashSet分别基于HashMap、TreeMap和LinkedHashMap
1.如果你需要一个访问快速的Set,你应该使用HashSet: 当你需要一个排序的Set,你应该使用TreeSet: 当你需要记录下插入时的顺序时,你应该使用LinedHashSet. 2.因为Tre ...
- MySql cmd下的学习笔记 —— 有关select的操作(in, and, where, like等等)
为方便本节学习, 请先自行建立本表: 建一个商品表: create table goods ( -> goods_id mediumint(8) unsigned not null auto_i ...
- Redis protected-mode属性解读
redis3.2版本后新增protected-mode配置,默认是yes,即开启.设置外部网络连接redis服务,设置方式如下: 1.关闭protected-mode模式,此时外部网络可以直接访问 2 ...
- openstack Q版部署-----Cinder云存储服务(10)
一.cinder介绍 一般 cinder-api 和 cinder-scheduler 安装在控制节点上, cinder-volume 安装在存储节点上. 二.数据库配置 # 在任意控制节点创建数据库 ...