libmodbus编程笔记

news2024/10/9 14:23:26

一 基础知识

地址映射值 

Modbus寄存器

 Modbus寄存器地址分配

 Modbus ASCII消息帧格式

Modbus RTU帧格式

 Modbus RTU相邻帧间隔

 Modbus寻址范围

  PDU与ADU的关系

 Modbus TCP/IP ADU与PDU的关系

 Modbus TCP/IP与Modbus串行消息构成对比

Modbus TCP/IP协议最大帧数据长度为260字节,其中字节0~6构成MBAP报头,各字段意义如下表所示。 

MBAP报头说明

 二 查询与响应报文例

对于Modbus TCP消息帧格式,下面举例说明各部分的含义。

• 查询报文:00 00 00 00 00 06 09 03 00 04 00 010

x06:后续还有6个字节

0x09:单元标识符为9

0x03:功能码3,即读保持寄存器的值

0x00 0x04:Modbus起始地址4(即40005)

0x00 0x01:读取寄存器个数为1

• 响应报文:00 00 00 00 00 05 09 03 02 00 05

0x05:表示后续还有5个字节

0x09:同查询报文,单元标识符

0x03:功能码,同查询报文

0x02:返回数据字节数

0x00 0x05:寄存器的值

可见,在Modbus TCP模式下,差错校验字段已不复存在。但在某些特殊场合,例如串行Modbus协议转Modbus TCP的情况下,串行协议数据可以完整地装载到Modbus TCP协议的数据字段,这时CRC或者LRC差错校验字段仍然存在。例如,Modbus RTU Over TCP/IP或Modbus ASCII Over TCP/IP等。

 三 Modbus部分功能码

 从表可知01、05、15操作相同的数据段,02单独操作一组数据,03、06、16共同操作一组数据。

04操作一组数据,在某些资料上15和16也写作十六进制的0x0f和0x10。

01(0x01)读取线圈/离散量输出状态

该功能码用于读取从设备的线圈或离散量输出的状态,即各DO(Discrete Output,离散输出)的ON/OFF状态。消息帧中指定了需读取的线圈起始地址和线圈数目。需要注意的一点是,在Modbus协议规定的PDU中,规定所有线圈或寄存器地址从0开始计算。

查询报文:

如表所示,查询帧的消息里,定义了从设备地址为3,并读取从设备的Modbus地址00019~00055(线圈地址00020~00056)共计37个状态值。起始线圈地址为0x13(即十进制00019),因为线圈地址从0开始计数。 

功能码01查询报文例 

 Modbus协议规定,起始地址由2个字节构成,取值范围为0x0000~0xFFFF;线圈数量由2个字节构成,取值范围为0x0001~0x07D0(即十进制1~2000)。另外,注意观察ASCII模式和RTU模式的区别,ASCII模式中直接按每4个位拆分为对应的字符表示。

响应报文

响应报文的数据字段中,每一个线圈占用1个位(bit),状态被表示为1=ON和0=OFF两种类型。第1个数据字节的LSB(最低有效位)标识查询报文中的起始地址线圈的状态值,其他线圈依次类推,一直到这个字节的MSB(最高有效位)为止,并在后续字节中按照同样的方式(由低到高)排列。例如,下表中线圈20~27的状态值分别是ON-ON-OFF-OFF-ON-OFF-ON-OFF,表示为二进制则为01010011(0x53),注意观察对应的顺序。一个字节可以表示8个线圈的状态,如果最后的数据字节中不能填满8个线圈的状态,则由0填充。对应于查询报文中需要读取37个线圈的状态,则共需要5个字节保存状态值。

 功能码01响应报文例

02(0x02)读取离散量输入值 

 该功能码用于读取从设备的离散输入即DI(Discrete Input)的ON/OFF状态。消息帧中指定了需读取的离散输入寄存器起始地址和数目,可读取1~2000个连续的离散量输入状态。如果从设备接受主设备的请求则回复功能码02,并返回离散量输入各变量的当前状态。如果返回的离散输入数量的个数不是8的整数倍,将用0填充最后数据字节的剩余位。

 03(0x03)读取保持寄存器值

该功能码用于读取从设备保持寄存器的内容,不支持广播模式。消息帧中指定了需读取的保持寄存器的起始地址和数目。而保持寄存器中各地址的具体内容和意义,则由设备开发者自行规定。

函数实现

主机

• 01:Read coil status读线圈状态;

对应函数:

 MODBUS_API int modbus_read_bits(modbus_t * ctx, int addr, int nb,uint8_t * dest)

此函数对应于功能码01(0x01)读取线圈/离散量输出状态(Read Coil Status/DOs),其中,所读取的值存放于参数uint8_t * dest指向的数组空间,因此dest指向的空间必须足够大,其大小至少为nb * sizeof(uint8_t)个字节。

• 02:Read input status读输入状态;

 MODBUS_API int modbus_read_input_bits(modbus_t * ctx, int addr, int nb, uint8_t *dest)

 此函数对应于功能码02(0x02)读取离散量输入值(Read Input Status/DIs),各参数的意义与用法,类似于函数modbus_read_bits()。

• 03:Read holding register读保持寄存器;

 MODBUS_API int modbus_read_registers(modbus_t * ctx, int addr, int nb, uint16_t *dest)

此函数对应于功能码03(0x03)读取保持寄存器(Read Holding Register),其中,所读取的值存放于参数uint16_t * dest指向的数组空间,因此dest指向的空间必须足够大,其大小至少为nb *sizeof(uint16_t)个字节。当读取成功后,返回值为读取的寄存器个数;若读取失败,则返回-1。此函数调用依赖关系如下图所示。 

 函数modbus_read_registers()的调用依赖关系

• 04:Read input registers读输入寄存器;

MODBUS_API int modbus_read_input_registers(modbus_t * ctx, int addr, int nb,uint16_t * dest)

此函数对应于功能码04(0x04)读取输入寄存器(Read Input Register),各参数的意义与用法,类似于函数modbus_read_registers()。此函数的调用依赖关系如下图所示。 

 函数modbus_read_input_registers()的调用依赖关系

• 05:Force single coil强制写入单线圈;

MODBUS_API int modbus_write_bit(modbus_t * ctx, int coil_addr, int status)

该函数对应于功能码05(0x05)写单个线圈或单个离散输出(Force Single Coil)。其中参数coil_addr代表线圈地址;参数status代表写入值,取值只能是TRUE(1)或FALSE(0)。 

• 06:Preset single register预置单寄存器;

MODBUS_API int modbus_write_register(modbus_t * ctx, int reg_addr, int value)

该函数对应于功能码06(0x06)写单个保持寄存器(Preset Single Register)。 

• 15:Force multiple coils强制写入多线圈;

MODBUS_API int modbus_write_bits(modbus_t * ctx, int addr, int nb, const uint8_t *data)

该函数对应于功能码15(0x0F)写多个线圈(Force Multiple Coils)。参数addr代表寄存器起始地址,参数nb表示线圈个数,而参数const uint8_t * data表示待写入的数据块。一般情况下,可以使用数组存储写入数据,数组的各元素取值范围只能是TRUE(1)或FALSE(0)。 

• 16:Preset multiple registers预置多寄存器;

MODBUS_API int modbus_write_registers(modbus_t * ctx, int addr, int nb, const uint16_t * data)

该函数对应于功能码16(0x10)写多个保持寄存器(Preset Multiple Registers)。参数addr代表寄存器起始地址,参数nb表示寄存器的个数,而参数const uint16_t * data表示待写入的数据块。一般情况下,可以使用数组存储写入数据,数组的各元素取值范围是0~0xFFFF,即数据类型uint16_t的取值范围。 

• 17:Report slave ID报告从设备ID;

MODBUS_API int modbus_report_slave_id(modbus_t * ctx, int max_dest, uint8_t *dest)

该函数对应于功能码17(0x11)报告从站ID。参数max_dest代表最大的存储空间,参数dest用于存储返回数据。返回数据可以包括如下内容:从站ID、状态值(0x00 = OFF状态,0xFF=ON状态)以及其他附加信息,具体的各参数意义由开发者指定。 

• 22:Mask write register屏蔽写寄存器;

• 23:Read/Write registers读/写寄存器。

小结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/623042.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人工智能-实验四

第四次实验 一.实验目的 ​ 了解深度学习的基本原理。能够使用深度学习开源工具。学习使用深度学习算法求解实际问题。 二.实验原理 1.深度学习概述 ​ 深度学习源于人工神经网络,本质是构建多层隐藏层的人工神经网络,通过卷积,池化&…

【2 微信小程序学习 - 小程序的架构.配置.app与page】

1 小程序的架构模型 为了避免卡顿,优化性能,小程序使用双线程模型. 可以理解为创建了两个webview,一个负责渲染界面,一个负责js脚本处理,通过微信客户端的native进行中转交互. 2 小程序的配置文件 在多人开发中,一般不修改project.config.json避免冲突 ,而是单人修改project…

Intradeco通过适用于Excel的Liquid UI自动执行SAP MM并节省80%的处理时间

背景 Intradeco为服装制造提供整体方法,涵盖所有阶段:从构思阶段到最终产品分销。它已发展成为一家全球垂直制造公司,客户遍布美国、墨西哥和加拿大。 挑战 提高运营效率 原因:人员必须浏览多个 SAP 事务才能为新材料创建采购订单…

2023年牛客网最新Java面试八股文附答案整理(不管工作几年都可以看看)

很多人都说今年对于 IT 行业根本没有所谓的“金三银四”“金九银十”。在各大招聘网站或者软件上不管是大厂还是中小公司大多都是挂个招聘需求,实际并不招人;在行业内的程序员基本都已经感受到了任老前段时间口中所谓的“寒气”。 虽然事实确实是如此&a…

学顶教育:初级会计师领取证书有关事项

初级会计师职称证书是国家组织考试后颁发的专业技术资格证书,与纸质证书和电子证书具有同等法律效力。 考取初级会计师职称证书的有关事项如下: 1、领取方式 初级会计职称证书的领取方式有两种:现场领取和邮寄领取。 考生可任选其一。 部分…

浪涌保护器和避雷器的区别

线路在使用过程中,由于短路或雷击,会突然产生巨大的能量。一旦这种能量通过线路进入家庭或其他电力线,就会造成设备烧毁,造成生命和财产损失。直流电涌保护器可以通过保护组件立即将巨大的能量吸入地面端子,从而保护您…

[架构之路-207]- 常见的需求分析技术:实用的需求分析与建模详解过程(实操性强)

目录 1.1 需求分析建模的要点与误区 1.1.1 需求分析到底做什么 1.1.1.1 分解的方法 1.1.1.2 提炼、合并、重组 1.1.1.3 消除矛盾 1.1.2 建模的目标和要点 1.1.2.1 建模的目的 1.1.2.2 建模的要点与原则 1.1.3 选择建模工具的要点 1.1.3.1 正确认识建模方法论 1.1.3.…

肠道菌群检测在临床感染判别中的应用

谷禾健康 感染是人类面临的健康威胁之一。各种病原体,如细菌、病毒、真菌、寄生虫等,存在于我们日常接触的环境、物品、食物等中。一些常见的感染病例包括感冒、流感、腹泻、组织器官或血液感染等,在全球范围内广泛传播。这些疾病的传播方式多…

MAYA活塞动画

给组打关键 让下面带动上面一起运动 创建定位器 放在中间 创建两个定位器 一个定位器放在连动秆下面,让定位跟物体一块动 创建目标约束 完成

python基础----07-----异常、模块、包

一 了解异常 当检测到一个错误时,Python解释 器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常”,也就是我们常说的BUG。 二 异常的捕获 当我们的程序遇到了BUG,那么接下来有两种情况: …

AcWing算法提高课-1.3.14开心的金明

宣传一下算法提高课整理 <— CSDN个人主页&#xff1a;更好的阅读体验 <— 本题链接&#xff08;AcWing&#xff09; 点这里 题目描述 金明今天很开心&#xff0c;家里购置的新房就要领钥匙了&#xff0c;新房里有一间他自己专用的很宽敞的房间。 更让他高兴的是&…

Vue.js中的Render函数和模板语法

Vue.js中的Render函数和模板语法 在Vue.js中&#xff0c;有两种主要的方式来构建组件&#xff1a;使用模板和使用render函数。模板语法是Vue.js中最常见的方式&#xff0c;它是一种基于HTML的语法&#xff0c;能够直接在HTML文件中定义组件的结构和行为。而render函数则是一种…

公司新来一00后,真让人崩溃...

2022年已经结束结束了&#xff0c;最近内卷严重&#xff0c;各种跳槽裁员&#xff0c;相信很多小伙伴也在准备今年的金九银十的面试计划。 在此展示一套学习笔记 / 面试手册&#xff0c;年后跳槽的朋友可以好好刷一刷&#xff0c;还是挺有必要的&#xff0c;它几乎涵盖了所有的…

设计模式(五):创建型之建造者模式

设计模式系列文章 设计模式(一)&#xff1a;创建型之单例模式 设计模式(二、三)&#xff1a;创建型之工厂方法和抽象工厂模式 设计模式(四)&#xff1a;创建型之原型模式 设计模式(五)&#xff1a;创建型之建造者模式 设计模式(六)&#xff1a;结构型之代理模式 目录 一、…

让ChatGPT来写今年的高考作文,会得几分?

使用最新的ChatGPT4模型&#xff0c;做2023年全国甲卷的高考作文。 作文考试题目如下 人们因技术发展得以更好地掌控时间&#xff0c;但也有人因此成了时间的仆人。这句话引发了你怎样的联想与思考?请写一篇文章。 要求&#xff1a;选准角度&#xff0c;确定立意&#xff0…

promise、async事件循环机制,你是CV工程师?

在面试的过程中如果不了解promise、async事件循环机制基本就会认为你是CV工程师 首先分析 async/await 其实是基于promise实现的&#xff0c;async 函数其实就是把 promise 做了一个包装 promise 是es6的语法&#xff0c;async/await 是es7的语法糖&#xff0c;所以我们先来分析…

​即将开幕!​2023 年金融营销科技价值发现论坛亮点前瞻

由神策数据主办 Hi-Finance、爱设计、亚马逊云科技 协办和支持的 开放融合 引领营销 5.0 新纪元 暨 2023 年金融营销科技价值发现论坛 即将于 6 月 9-10 日在中国杭州开幕 届时百余位金融数字化从业者将共聚一堂 探讨金融业发展的新思路、新路径、新趋势 2023 年&#xff0c;数…

Windows电脑怎么加密文件?文件加密方法介绍

Windows作为目前使用人数最多的电脑系统&#xff0c;是很多人办公、生活的必要工具。那么你知道在Windows系统中该怎么样加密文件吗&#xff1f;下面我们就来一起了解一下。 方法一&#xff1a;文件夹加密超级大师 想要做好文件加密并不容易&#xff0c;需要保障文件加密的安全…

APP外包开发第三方登录

APP开发过程中往往需要对接第三方的登录&#xff0c;国内的有微信、QQ、微博等&#xff0c;国外的有google、facebook等账号。对接第三方账号登录SDK可以方便用户快捷登录&#xff0c;是APP登录功能里一项重要的特性。今天和大家分享对接流程和注意事项&#xff0c;希望对大家有…

三维数字沙盘交互大数据可视化GIS地理信息系统第十课

三维电子沙盘交互无人机倾斜摄影大数据可视化GIS地理信息系统第十课 设置system.ini 如下内容 Server122.112.229.220 userGisTest Passwordchinamtouch.com 该数据库中只提供 成都市火车南站附近的数据请注意&#xff0c;104.0648,30.61658 在SDK中自带了一个自定义的基础面…