【嵌入式】Libmodbus之TCP模式Master端程序示例
00. 目录
文章目录
- 00. 目录
- 01. TCP模式Master开发流程
- 02. 读写单个线圈程序示例
- 03. 读写多个线圈程序示例
- 04. 读写单个保持寄存器程序示例
- 05. 读写多个保持寄存器程序示例
- 06. 读写多个寄存器测试(功能码0X17)
- 07. 附录
01. TCP模式Master开发流程
Modbus结合libmodbus开发库可以自由开发主设备端或从设备端的应用程序,而且支持RTU和TCP两种常用的模式。
开发主设备端(Master或者Client)程序的基本流程如下图所示:
02. 读写单个线圈程序示例
程序示例
#include <stdio.h>#ifndef _MSC_VER
#include <unistd.h>
#endif#include <string.h>
#include <stdlib.h>
#include <errno.h>//包含Modbus相关头文件
#include "modbus.h"//相关参数设置
#define LOOP 1 //循环次数
#define ADDRESS_START 0 //测试寄存器起始地址
#define ADDRESS_END 99 //测试寄存器结束地址int main(void)
{modbus_t* ctx = NULL;int ret = -1;int nums = 0;int addr = 0;int i = 0;int tmp = 0;uint8_t* tab_rq_bits = NULL;uint8_t* tab_rp_bits = NULL;//设置随机种子srand((int)time(0));//1. 创建一个TCP类型的变量ctx = modbus_new_tcp("192.168.1.90", 10086);if (NULL == ctx){fprintf(stderr, "Error: %s\n", modbus_strerror(errno));return 1;}else{printf("设置TCP成功\n");}//2. 设置Debug模式ret = modbus_set_debug(ctx, TRUE);if (-1 == ret){fprintf(stderr, "Error: 设置Debug模式失败");modbus_free(ctx);return 1;}//3. 连接Serverret = modbus_connect(ctx);if (-1 == ret){fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));modbus_free(ctx);return 1;}//4. 计算需测试的寄存器个数nums = ADDRESS_END - ADDRESS_START;//5. 申请内存 保存发送和接收的数据tab_rq_bits = (uint8_t*)malloc(nums * sizeof(uint8_t));if (NULL == tab_rq_bits){fprintf(stderr, "malloc failed\n");modbus_free(ctx);return 1;}else{memset(tab_rq_bits, 0, nums * sizeof(uint8_t));}tab_rp_bits = (uint8_t*)malloc(nums * sizeof(uint8_t));if (NULL == tab_rp_bits){fprintf(stderr, "malloc failed\n");modbus_free(ctx);return 1;}else{memset(tab_rp_bits, 0, nums * sizeof(uint8_t));}//6. 写单个线圈addr = ADDRESS_START;tmp = rand() / 100;tab_rq_bits[0] = tmp % 2;ret = modbus_write_bit(ctx, addr, tab_rq_bits[0]);if (1 != ret){printf("Error modbus_write_bit: %d\n", ret);printf("Address: %d value: %d\n", addr, tab_rq_bits[0]);}else{//读取单个线圈ret = modbus_read_bits(ctx, addr, 1, tab_rp_bits);if (1 != ret){printf("Error modbus_read_bits: %d\n", ret);}else{printf("tab_rp_bits[0]: %d tab_rq_bits[0]: %d\n", tab_rp_bits[0], tab_rq_bits[0]);}}//8. 释放内存free(tab_rp_bits);free(tab_rq_bits);//9. 断开连接modbus_close(ctx);modbus_free(ctx);return 0;
}
执行结果
03. 读写多个线圈程序示例
程序示例
#include <stdio.h>#ifndef _MSC_VER
#include <unistd.h>
#endif#include <string.h>
#include <stdlib.h>
#include <errno.h>//包含Modbus相关头文件
#include "modbus.h"//相关参数设置
#define LOOP 1 //循环次数
#define ADDRESS_START 0 //测试寄存器起始地址
#define ADDRESS_END 99 //测试寄存器结束地址int main(void)
{modbus_t* ctx = NULL;int ret = -1;int nums = 0;int addr = 0;int i = 0;int tmp = 0;uint8_t* tab_rq_bits = NULL;uint8_t* tab_rp_bits = NULL;//设置随机种子srand((int)time(0));//1. 创建一个TCP类型的变量ctx = modbus_new_tcp("192.168.1.90", 10086);if (NULL == ctx){fprintf(stderr, "Error: %s\n", modbus_strerror(errno));return 1;}else{printf("设置TCP成功\n");}//2. 设置Debug模式ret = modbus_set_debug(ctx, TRUE);if (-1 == ret){fprintf(stderr, "Error: 设置Debug模式失败");modbus_free(ctx);return 1;}//3. 连接Serverret = modbus_connect(ctx);if (-1 == ret){fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));modbus_free(ctx);return 1;}//4. 计算需测试的寄存器个数nums = ADDRESS_END - ADDRESS_START;//5. 申请内存 保存发送和接收的数据tab_rq_bits = (uint8_t*)malloc((nums + 1) * sizeof(uint8_t));if (NULL == tab_rq_bits){fprintf(stderr, "malloc failed\n");modbus_free(ctx);return 1;}else{memset(tab_rq_bits, 0, (nums + 1) * sizeof(uint8_t));}tab_rp_bits = (uint8_t*)malloc((nums + 1) * sizeof(uint8_t));if (NULL == tab_rp_bits){fprintf(stderr, "malloc failed\n");modbus_free(ctx);return 1;}else{memset(tab_rp_bits, 0, (nums + 1) * sizeof(uint8_t));}//7. 写多个线圈//随机数字for (i = 0; i < nums; i++){tmp = rand() % 100;tab_rq_bits[i] = tmp % 2;if (0 == i){printf("写入的值: ");}printf("%hd ", tab_rq_bits[i]);}//换行printf("\n");addr = ADDRESS_START;ret = modbus_write_bits(ctx, addr, nums + 1, tab_rq_bits);if (nums + 1 != ret){printf("Error modbus_write_bit: %d\n", ret);printf("Address: %d nums: %d\n", addr, nums);}else{//读取多个线圈ret = modbus_read_bits(ctx, addr, nums + 1, tab_rp_bits);if (nums + 1 != ret){printf("Error modbus_read_bits: %d\n", ret);}else{//输出for (i = 0; i < nums; i++){if (0 == i){printf("读取到的值: ");}printf("%hd ", tab_rp_bits[i]);}//换行printf("\n");}}//8. 释放内存free(tab_rp_bits);free(tab_rq_bits);//9. 断开连接modbus_close(ctx);modbus_free(ctx);return 0;
}
执行结果
04. 读写单个保持寄存器程序示例
程序示例
#include <stdio.h>#ifndef _MSC_VER
#include <unistd.h>
#endif#include <string.h>
#include <stdlib.h>
#include <errno.h>//包含Modbus相关头文件
#include "modbus.h"//相关参数设置
#define LOOP 1 //循环次数
#define ADDRESS_START 0 //测试寄存器起始地址
#define ADDRESS_END 99 //测试寄存器结束地址int main(void)
{modbus_t* ctx = NULL;int ret = -1;int nums = 0;int addr = 0;int i = 0;int tmp = 0;uint16_t* tab_rq_registers = NULL;uint16_t* tab_rp_registers = NULL;//设置随机种子srand((int)time(0));//1. 创建一个TCP类型的变量ctx = modbus_new_tcp("192.168.1.90", 10086);if (NULL == ctx){fprintf(stderr, "Error: %s\n", modbus_strerror(errno));return 1;}else{printf("设置TCP成功\n");}//2. 设置Debug模式ret = modbus_set_debug(ctx, TRUE);if (-1 == ret){fprintf(stderr, "Error: 设置Debug模式失败");modbus_free(ctx);return 1;}//3. 连接Serverret = modbus_connect(ctx);if (-1 == ret){fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));modbus_free(ctx);return 1;}//4. 计算需测试的寄存器个数nums = ADDRESS_END - ADDRESS_START;//5. 申请内存 保存发送和接收的数据tab_rq_registers = (uint16_t*)malloc((nums + 1) * sizeof(uint16_t));if (NULL == tab_rq_registers){fprintf(stderr, "malloc failed\n");modbus_free(ctx);return 1;}else{memset(tab_rq_registers, 0, (nums + 1) * sizeof(uint16_t));}tab_rp_registers = (uint16_t*)malloc((nums + 1) * sizeof(uint16_t));if (NULL == tab_rp_registers){fprintf(stderr, "malloc failed\n");modbus_free(ctx);return 1;}else{memset(tab_rp_registers, 0, (nums + 1) * sizeof(uint16_t));}//7. 测试保持寄存器的单个读写//随机数字tab_rq_registers[0] = rand() % 100;printf("写入的值为: %hd\n", tab_rq_registers[0]);//换行printf("\n");addr = ADDRESS_START;ret = modbus_write_register(ctx, addr, tab_rq_registers[0]);if (1 != ret){printf("Error modbus_write_register: %d\n", ret);}else{//读取数据ret = modbus_read_registers(ctx, addr, 1, tab_rp_registers);if (1 != ret){printf("Error modbus_read_registers: %d\n", ret);}else{//输出printf("读取到的值为: %hd\n", tab_rp_registers[0]);}}//8. 释放内存free(tab_rp_registers);free(tab_rq_registers);//9. 断开连接modbus_close(ctx);modbus_free(ctx);return 0;
}
执行结果
05. 读写多个保持寄存器程序示例
程序示例
#include <stdio.h>#ifndef _MSC_VER
#include <unistd.h>
#endif#include <string.h>
#include <stdlib.h>
#include <errno.h>//包含Modbus相关头文件
#include "modbus.h"//相关参数设置
#define LOOP 1 //循环次数
#define ADDRESS_START 0 //测试寄存器起始地址
#define ADDRESS_END 99 //测试寄存器结束地址int main(void)
{modbus_t* ctx = NULL;int ret = -1;int nums = 0;int addr = 0;int i = 0;int tmp = 0;uint16_t* tab_rq_registers = NULL;uint16_t* tab_rp_registers = NULL;//设置随机种子srand((int)time(0));//1. 创建一个TCP类型的变量ctx = modbus_new_tcp("192.168.1.90", 10086);if (NULL == ctx){fprintf(stderr, "Error: %s\n", modbus_strerror(errno));return 1;}else{printf("设置TCP成功\n");}//2. 设置Debug模式ret = modbus_set_debug(ctx, TRUE);if (-1 == ret){fprintf(stderr, "Error: 设置Debug模式失败");modbus_free(ctx);return 1;}//3. 连接Serverret = modbus_connect(ctx);if (-1 == ret){fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));modbus_free(ctx);return 1;}//4. 计算需测试的寄存器个数nums = ADDRESS_END - ADDRESS_START;//5. 申请内存 保存发送和接收的数据tab_rq_registers = (uint16_t*)malloc((nums + 1) * sizeof(uint16_t));if (NULL == tab_rq_registers){fprintf(stderr, "malloc failed\n");modbus_free(ctx);return 1;}else{memset(tab_rq_registers, 0, (nums + 1) * sizeof(uint16_t));}tab_rp_registers = (uint16_t*)malloc((nums + 1) * sizeof(uint16_t));if (NULL == tab_rp_registers){fprintf(stderr, "malloc failed\n");modbus_free(ctx);return 1;}else{memset(tab_rp_registers, 0, (nums + 1) * sizeof(uint16_t));}//7. 测试保持寄存器的单个读写
//随机数字for (i = 0; i < nums; i++){tmp = rand() % 100;tab_rq_registers[i] = tmp;if (0 == i){printf("写入的值: ");}printf("%hd ", tab_rq_registers[i]);}//换行printf("\n");addr = ADDRESS_START;ret = modbus_write_registers(ctx, addr, nums + 1, tab_rq_registers);if (nums + 1 != ret){printf("Error modbus_write_registers: %d\n", ret);printf("Address: %d nums: %d\n", addr, nums + 1);}else{//读取ret = modbus_read_registers(ctx, addr, nums + 1, tab_rp_registers);if (nums + 1 != ret){printf("Error modbus_read_registers: %d\n", ret);}else{//输出for (i = 0; i < nums; i++){if (0 == i){printf("读取到的值: ");}printf("%hd ", tab_rp_registers[i]);}//换行printf("\n");}}//8. 释放内存free(tab_rp_registers);free(tab_rq_registers);//9. 断开连接modbus_close(ctx);modbus_free(ctx);return 0;
}
执行结果
06. 读写多个寄存器测试(功能码0X17)
程序示例
#include <stdio.h>#ifndef _MSC_VER
#include <unistd.h>
#endif#include <string.h>
#include <stdlib.h>
#include <errno.h>//包含Modbus相关头文件
#include "modbus.h"//相关参数设置
#define LOOP 1 //循环次数
#define ADDRESS_START 0 //测试寄存器起始地址
#define ADDRESS_END 99 //测试寄存器结束地址int main(void)
{modbus_t* ctx = NULL;int ret = -1;int nums = 0;int addr = 0;int i = 0;int tmp = 0;uint16_t* tab_rq_registers = NULL;uint16_t* tab_rp_registers = NULL;//设置随机种子srand((int)time(0));//1. 创建一个TCP类型的变量ctx = modbus_new_tcp("192.168.1.90", 10086);if (NULL == ctx){fprintf(stderr, "Error: %s\n", modbus_strerror(errno));return 1;}else{printf("设置TCP成功\n");}//2. 设置Debug模式ret = modbus_set_debug(ctx, TRUE);if (-1 == ret){fprintf(stderr, "Error: 设置Debug模式失败");modbus_free(ctx);return 1;}//3. 连接Serverret = modbus_connect(ctx);if (-1 == ret){fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));modbus_free(ctx);return 1;}//4. 计算需测试的寄存器个数nums = ADDRESS_END - ADDRESS_START;//5. 申请内存 保存发送和接收的数据tab_rq_registers = (uint16_t*)malloc((nums + 1) * sizeof(uint16_t));if (NULL == tab_rq_registers){fprintf(stderr, "malloc failed\n");modbus_free(ctx);return 1;}else{memset(tab_rq_registers, 0, (nums + 1) * sizeof(uint16_t));}tab_rp_registers = (uint16_t*)malloc((nums + 1) * sizeof(uint16_t));if (NULL == tab_rp_registers){fprintf(stderr, "malloc failed\n");modbus_free(ctx);return 1;}else{memset(tab_rp_registers, 0, (nums + 1) * sizeof(uint16_t));}//7. 测试保持寄存器的单个读写//随机数字for (i = 0; i < nums; i++){tmp = rand() % 100;tab_rq_registers[i] = tmp;if (0 == i){printf("写入的值: ");}printf("%hd ", tab_rq_registers[i]);}//换行printf("\n");addr = ADDRESS_START;//先写入,后读取该数据到指定的内存中ret = modbus_write_and_read_registers(ctx, addr, nums + 1, tab_rq_registers,addr, nums + 1, tab_rp_registers);if (nums + 1 != ret){printf("Error modbus_write_and_read_registers: %d\n", ret);printf("Address: %d nums: %d\n", addr, nums + 1);}else{//输出for (i = 0; i < nums; i++){if (0 == i){printf("读取到的值: ");}printf("%hd ", tab_rp_registers[i]);}//换行printf("\n");}//再次读取数据memset(tab_rp_registers, 0, (nums + 1) * sizeof(uint16_t));ret = modbus_read_registers(ctx, addr, nums + 1, tab_rp_registers);if (nums + 1 != ret){printf("Error modbus_read_registers: %d\n", ret);}else{//输出for (i = 0; i < nums; i++){if (0 == i){printf("读取到的值: ");}printf("%hd ", tab_rp_registers[i]);}//换行printf("\n");}//8. 释放内存free(tab_rp_registers);free(tab_rq_registers);//9. 断开连接modbus_close(ctx);modbus_free(ctx);return 0;
}
执行结果
07. 附录
程序下载:TCP模式Master端程序.rar
【嵌入式】Libmodbus之TCP模式Master端程序示例相关推荐
- 【嵌入式】Libmodbus之RTU模式Master端程序示例
00. 目录 文章目录 00. 目录 01. 软件开发流程 02. 获取版本信息 03. 读写单个线圈程序示例 04. 读写多个线圈程序示例 05. 读写单个保持寄存器程序示例 06. 读写多个保持寄 ...
- 【嵌入式】Libmodbus之TCP模式Slave端程序示例
00. 目录 文章目录 00. 目录 01. 开发TCPSlave端程序流程 02. TCP Slave端程序示例 03. TCP Slave端程序说明 04. 预留 05. 附录 01. 开发TCP ...
- 【嵌入式】Libmodbus之RTU模式Slave端程序示例
00. 目录 文章目录 00. 目录 01. 开发RTU Slave端程序流程 02. RTU Slave端程序示例 03. RTU Slave端程序说明 04. 预留 05. 附录 01. 开发RT ...
- python多线程tcp客户端_基于Python多线程的TCP客户端/服务端应用示例
每个连接都必须创建新线程(或进程)来处理,否则,单线程在处理连接的过程中,无法接受其他客户端的连接. 服务端:server.py # -*- coding:utf-8 -*- import sys i ...
- TCP服务端程序开发
TCP服务端程序开发 1. 开发 TCP 服务端程序开发步骤回顾 创建服务端端套接字对象 绑定端口号 设置监听 等待接受客户端的连接请求 接收数据 发送数据 关闭套接字 2. socket 类的介绍 ...
- 网络编程之TCP服务端程序开发
TCP服务端程序开发 学习目标 能够写出TCP服务端应用程序接收和发送消息 1. 开发 TCP 服务端程序开发步骤回顾 创建服务端端套接字对象 绑定端口号 设置监听 等待接受客户端的连接请求 接收数据 ...
- OSI七层模型以及TCP/UDP客户端/服务端程序实例
OSI七层模型以及TCP/UDP客户端/服务端程序实例 一.前言 二.OSI简介 2.1 OSI概念 2.2 划分原则 2.3 OSI七层模型 2.4 模型举例 三.Linux下TCP/UDP程序开发 ...
- 【Qt】modbus之TCP模式写操作
00. 目录 文章目录 00. 目录 01. 概述 02. 开发环境 03. 读Coils程序示例 04. 读HoldingRegisters程序示例 07. 综合示例 08. 程序下载 09. 附录 ...
- 【Qt】modbus之TCP模式读操作
00. 目录 文章目录 00. 目录 01. 概述 02. 开发环境 03. 读Coils程序示例 04. 读DiscreteInputs程序示例 05. 读InputRegisters程序示例 06 ...
最新文章
- (详细)Hibernate框架的搭建,Hibernate的CRUD操作(一)
- J.U.C系列(一)CountDownLatch的使用
- Codeforces Round #528 (Div. 2) - D. Minimum Diameter Tree
- 数据结构 - 单调栈、单调队列
- 前端学习(3181):ant-design的button介绍
- 一套 SQL 搞定数据仓库?Flink有了新尝试
- Google Chrome 最新市场份额
- FastReport.Net使用:[23]图表(Chart)控件
- Cox回归和HR值理解要点难点,实例讲解
- unity text颜色渐变
- 使用Windows优化大师或其他注册表清理软件导致NVIDIA控制面板打不开的解决方法
- Mysql基础篇(4)—— 创建和管理表
- 网易互娱耗时最长的活动
- JavaScript入门 Day1
- ad怎么修改栅格_AD 10怎么设置栅格?
- 对比学习Contrastive Learning
- 企业微信如何退出之前的公司
- R语言可视化散点图、使用ggrepel包的geom_text_repel函数避免数据点之间的标签互相重叠(设置min.segment.length参数为Inf不添加标签线段)
- 构造方法的作用和特点
- 全新8.6版本SEO快排系统(可源码级搭建)
热门文章
- Windows常见宏的使用
- VSX-5 VSXMusic 编码听音乐
- HTTP 知识点之一:头部解释(转)
- mooc构建结构数组的笔记
- code ./打不开vscode编辑器
- 8.36人一次搬36块砖,男搬4,女搬2,两个小孩抬一块,要一次搬完。问:男、女、小孩各多少?
- android 百度地图 在线建议查询,Android 百度地图 SDK v3_3_0 (五) ---POI搜索和在线建议查询功能...
- 在VS2008中使用Qt编程
- numpy---one
- LintCode 402: Continuous Subarray Sum