Modbus协议

百度解释

Modbus协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络(例如以太网)和其它设备之间可以通信。它已经成为一种通用工业标准。有了它,不同厂商生产的控制设备可以连成工业网络,进行集中监控。此协议定义了一个控制器能认识使用的消息结构,而不管它们是经过何种网络进行通信的。它描述了一个控制器请求访问其它设备的过程,如何回应来自其它设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共格式。

当在同一Modbus网络上通信时,此协议决定了每个控制器需要知道它们的设备地址,识别按地址发来的消息,决定要产生何种行动。如果需要回应,控制器将生成反馈信息并用Modbus协议发出。在其它网络上,包含了Modbus协议的消息转换为在此网络上使用的帧或包结构。这种转换也扩展了根据具体的网络解决节地址、路由路径及错误检测的方法。

此协议支持传统的RS-232、RS-422、RS-485和以太网设备。许多工业设备,包括PLC,DCS,智能仪表等都在使用Modbus协议作为他们之间的通信标准。

应用场景

项目中经常需要和各式各样的PLC进行通讯,开始的时候是三菱Q系列的5u,用的是SLMP协议,后面又对接了安川的PLC,指不定以后会用哪家的PLC,所以考虑到是不是应该换一个通用性比较强的接口协议,可以省去大量时间和精力。
网上搜了一下,发现Modbus算是比较通用的协议了,也搜到了很多资料,因为对C++ 比较熟悉,所以搜的都是C++ 的Modbus资源。正好找到了libmodbus这个开源库,通读了一遍代码,觉得很不错,很强大,所以有了这篇文章。

libmodbus配置

在官网下载了代码,用vs2013编译了一下,我自己编译生成的libCSDN下载地址(2分),Gitee下载地址(免积分)。还是很容易的。

  • 编译:
    libmodbus/src/win32目录下的 modbus-9.sln 文件,直接用vs打开编译就可以了。

  • 生成:
    libmodbus/src/win32目录下生成了
    modbus.dllmodbus.lib文件

  • 引用:
    工程包含头文件:modbus.h
    modbus-rtu.h

    modbus-tcp.h
    modbus-version.h
    库文件:
    modbus.lib
    程序目录下放入文件:
    modbus.dll

libmodbus函数说明

引入到工程之后,就需要了解几个主要的函数了。

  • 初始化与释放
/* 以TCP的方式创建libmobus实例char *ip:连接的IP地址int port: 连接的IP端口
*/
modbus_t *modbus_new_tcp(const char *ip, int port);/* 以串口的方式创建libmobus实例onst char *device:连接的串口号,类似是这样'\\\\.\\COM10'int baud: 波特率char parity:奇偶校验int data_bit:数据位int stop_bit:停止位
*/
modbus_t *modbus_new_rtu(const char *device, int baud, char parity, int data_bit, int stop_bit);/* 释放libmodbus实例,使用完libmodbus需要释放掉modbus_t *ctx:libmodbus实例
*/
void modbus_free(modbus_t *ctx);
  • 读取
/* 读取线圈状态,可读取多个连续线圈的状态modbus_t *ctx:Modbus实例int addr: 线圈地址int nb:读取线圈的个数uint8_t *dest: 传出的状态值
*/
int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);/* 读取输入状态,可读取多个连续输入的状态modbus_t *ctx:Modbus实例int addr:输入地址int nb:读取输入的个数uint8_t *dest:传出的状态值
*/
int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);/* 读取输入寄存器的值,可读取多个连续输入输入寄存器modbus_t *ctx:Modbus实例int addr:输入地址int nb:读取输入寄存器的个数uint8_t *dest:传出的寄存器值
*/
int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);/* 读取保持寄存器的值,可读取多个连续输入保持寄存器modbus_t *ctx:Modbus实例int addr:输入地址int nb:读取保持寄存器的个数uint8_t *dest:传出的寄存器值
*/
int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);
  • 写入
/*写入单个线圈的状态modbus_t *ctx:Modbus实例int addr:线圈地址int status:线圈状态
*/
int modbus_write_bit(modbus_t *ctx, int addr, int status);/*写入多个连续线圈的状态modbus_t *ctx:Modbus实例int addr:线圈地址int nb:线圈个数const uint8_t *src:多个线圈状态
*/
int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src);/*写入单个寄存器modbus_t *ctx:Modbus实例int addr:寄存器地址int value:寄存器的值
*/
int modbus_write_register(modbus_t *ctx, int addr, int value);/*写入多个连续寄存器int addr:寄存器地址int nb:寄存器的个数const uint16_t *src:多个寄存器的值
*/
int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src);
  • float 浮点数

libmodbus下处理浮点型真的是异常方便,我之前用的协议都是需要我自己转换的,在得到的寄存器的数据后,发现PLC的数解析的时候,可能分16位和32位的,拿16位举例,每4位一组就像ABCD,我们需要解析出来的是DCBA。
后来我发现了libmodbus里面有这两个函数

float modbus_get_float(const uint16_t *src);void modbus_set_float(float f, uint16_t *dest)

这个两个函数主要是将整型数据转换成float,和将float转换成整型的。
在用modbus_read_registers或者modbus_read_input_registers得到寄存器的值int16_t *dest,如果里面存的是浮点数,把dest当做参数传入到modbus_get_float里面,如果得到的值不对,你需要弄清楚PLC对应传出数据的模式是DCBA还是BADC,CDAB,ABCD。

libmodbus还提供了其他函数

modbus_get_float_abcd
modbus_get_float_badc
modbus_get_float_cdab
modbus_get_float_dcba

modbus_set_float_abcd
modbus_set_float_badc
modbus_set_float_cdab
modbus_set_float_dcba

下图是我在工作中常用的三菱5u PLC Modbus对应寄存器线圈输入等的地址。

libmodbus使用说明相关推荐

  1. abaqus高性能服务器怎么用,高性能计算平台ABAQUS任务调度使用说明作者陈林E-Mailchenlin.PDF...

    高性能计算平台ABAQUS任务调度使用说明作者陈林E-Mailchenlin.PDF 高性能计算平台ABAQUS 任务调度使用说明 作者:陈林 E-Mail:chenlin@ 日期:2017-1-10 ...

  2. linux 文件拷贝并替换,Linux_cmd replace 文件替换使用说明,帮助信息: 复制代码 代码如 - phpStudy...

    cmd replace 文件替换使用说明 帮助信息: 复制代码 代码如下: 替换文件. REPLACE [drive1:][path1]filename [drive2:][path2] [/A] [ ...

  3. Simple Dynamic Strings(SDS)源码解析和使用说明二

    在<Simple Dynamic Strings(SDS)源码解析和使用说明一>文中,我们分析了SDS库中数据的基本结构和创建.释放等方法.本文将介绍其一些其他方法及实现.(转载请指明出于 ...

  4. 【modbus】libmodbus库的移植与使用

    一.源码下载 1.libmodbus官网     http://libmodbus.org/download/ 2.选择长期稳定版本libmodbus-3.0.6.tar.gz     下载链接:ht ...

  5. Delphi开发的IOCP测试Demo以及使用说明。

    Delphi开发的IOCP,此为压力测试Demo和使用说明.

  6. oracle database link mysql_oracle database link使用说明

    oracle database link使用说明 作用: 将多个oracle数据库逻辑上看成一个数据库,也就是说在一个数据库中可以操作另一个数据库中的对象. 简易语法: CREATE [PUBLIC] ...

  7. 序列拼接工具Bowtie使用说明

    序列拼接工具Bowtie使用说明 2011-06-08 ~ ADMIN Bowtie是一个超级快速的,较为节省内存的短序列拼接至模板基因组的工具.它在拼接35碱基长度的序列时,可以达到每小时2.5亿次 ...

  8. benchmarksql测试mysql_数据库压力测试工具 -- BenchmarkSQL 使用说明

    关于数据库的压力测试,之前写过3篇Blog: 数据库基准测试(Database Benchmarking) 说明 数据库压力测试工具 -- Hammerdb 使用说明 数据库压力测试工具 -- Swi ...

  9. 计算机网页基础课专业,关于《计算机应用基础》课程网页下的学习资源使用说明....

    关于<计算机应用基础>课程网页下的学习资源使用说明. 关于<计算机应用基础>课程网页下的学习资源使用说明 各位同学:大家好! 07春学期已接近一半的时间了,新生对课程还需要更多 ...

最新文章

  1. android webview详情,Android中的WebView详细介绍
  2. 2019BATJ面试题汇总详解:MyBatis+MySQL+Spring+Redis+多线程
  3. gcc编译c文件_Linux下C语言程序的编译过程
  4. openwrt 系统日志配置_Openwrt 之 Samba配置
  5. matlab 边缘光滑,如何使用matlab来平滑图片的边缘
  6. vue 附件上传获取附近内容_vue实现文件上传功能
  7. 基于Nexys4 DDR的VGA显示图片
  8. 获取计算机最大磁盘,Qt获取电脑磁盘容量(示例代码)
  9. 【Flink】Flink 报错 exited with a non-zero exit code 1
  10. php快速排序空间复杂度,PHP 算法基础----时间复杂度和空间复杂度(转载)
  11. python 字符串编码 str和unicode 区别以及相互转化 decode('utf-8') encode('utf-8')
  12. 命令行启动mysql闪退
  13. maven项目中:java.io.IOException: java.io.FileNotFoundException--- (文件名、目录名或卷标语法不正确。)
  14. 从技术问题变成RPWT
  15. Java 匿名类热更新失败的原因
  16. 微信开放平台授权java_微信开放平台授权登录(java版)
  17. 微信template模板
  18. 计算机一级wps必背知识点,计算机一级WPSoffice考前复习题
  19. 罗斯蒙特PH电极1056-01-22-32-AN智能型四线制变送器规格及特点
  20. 搭建DNF台服之配置客户端

热门文章

  1. 红底证件照背景怎么弄?试试这几种方法非常简单
  2. 戏谑五大互联网巨头“打工人”气质
  3. 二叉树的层序创建和层序遍历(c++,c)
  4. vwap 公式_【IB交易者词汇】交易量加权平均价格(VWAP )
  5. 登录失败 12306服务器不稳定,12306官方再次出现服务器故障 无法购票
  6. 多闪付、岁岁通...字节跳动的支付业务终上正轨,但“逐梦金融圈”谈何容易...
  7. SIFT特征提取实现地理位置的标注
  8. 算法——音乐播发器中考虑已听次数的随机播放算法
  9. 基于SpringBoot的CSGO游戏比赛赛事管理系统设计与实现-计算机毕业设计源码和LW文档
  10. Visio保存图片不清晰