玩转Libmodbus(二) 写代码体验
libmodbus在线文档
https://www.jianshu.com/p/d93c17485c0a
原创篇
参考上一篇转载的博客,我的ubuntu上的最终生成的动态库的路径,下图所示

我的linux板子上( 权限最好 777):

我的ubuntu主机上的C语言源代码的路径,四个头文件modbus.h、modbus-rtu.h、modbus-tcp.h、modbus-version.h也都放在了这里

我的C源代码:
/*************************
**
** modbus-rtu-test.c
** 移植libmodbus库到ARM开发板,并测试成功
**
**************************/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "modbus.h" //modbus动态库文件 unsigned char log[6] = {0x11,0x12,0x13,0x14,0x15,0x16};
#define Path_dat "/root/Test_Data_Dir/record.dat" #define Path_log1 "/root/Test_Data_Dir/log1.dat"
#define Path_log2 "/root/Test_Data_Dir/log2.dat"
#define Path_log3 "/root/Test_Data_Dir/log3.dat"
#define Path_log4 "/root/Test_Data_Dir/log4.dat" /*
int read_data_hex(unsigned char *buf, int length, char *string)
{
FILE *fp;
fp = fopen(string, "rb");
if (NULL == fp)
{
// printf("read: file open Fail!\n");
return -1;
}
fread(buf, sizeof(unsigned char), length, fp); fclose(fp);
fp = NULL;
return 0;
}
*/ int write_data_hex(unsigned char *my_array, int length, char *string)
{
int i = 0;
FILE *fp;
fp = fopen(string, "wb+"); // b 二进制操作
if (NULL == fp)
{
// printf("write: file open Fail!\n");
return -1;
}
while (i < length)
{
fwrite(&my_array[i], sizeof(unsigned char), 1, fp);
i++;
} fclose(fp);
fp = NULL;
return 0;
} //如果手边只有一根USB转串口线,那么只能连接板子的modbus串口和PC机,就不能
//连接PC机和板子的串口调试口了。如何调试?使用write_data_hex()写log观察过程。 int main(int argc, char *argv[])
{
struct timeval t;
uint16_t tab_reg[64] = {0}; //定义存放数据的数组
modbus_t *ctx = NULL; int rc;
int i;
//以串口的方式创建libmodbus实例,并设置参数
//ttySAC0 /dev/ttyS1
ctx = modbus_new_rtu("/dev/ttySAC0", 115200, 'N', 8, 1);
if (ctx == NULL)
{
fprintf(stderr, "Unable to allocate libmodbus contex\n");
return -1;
} printf("MY_Debug: usleep begin! \n"); //这里我给了40秒延时,在这个时间内:你把串口线从板子的串口调试口转为
//连接到板子的modbus串口,打开一个事先设置好串口参数的PC机上的模拟modbus从机的软件
//(我使用的是和modsim32)
//注意:如果前后接的是同一个电脑com口,注意还要把之前的串口调试口对应的上位机软件
// 关闭一下,以便modsim32能够顺利打开该com口。
usleep(40000000); modbus_set_debug(ctx, 0); //设置1可看到调试信息
modbus_set_slave(ctx, 1); //设置slave ID t.tv_sec = 0;
t.tv_usec = 50000;
// 50ms超时时间,下位机回复帧的限制时间:主机发完后,下位机需要在50ms内回应
// *** 必须设置从站的响应超时 小于 主站的响应超时 ***
// 总之,在确保速度满足你所需应用的情况下,把主站的响应超时适当设置大一点,是保险措施
modbus_set_response_timeout(ctx,&t); if (modbus_connect(ctx) == -1) //连接设备
{
write_data_hex(&log[0], 1, Path_log1);
printf("MY_Debug: modbus_connect Fail! \n");
fprintf(stderr, "Connection failed:%s\n", modbus_strerror(errno)); modbus_close(ctx); //关闭modbus连接
modbus_free(ctx); //释放modbus资源,libmodbus需要释放掉
}
else{
printf("MY_Debug: modbus_connect Success! \n");
} while (1)
{
printf("\n 这里的代码只执行一次 return -1,或者 break \n"); rc = modbus_read_registers(ctx, 0, 10, tab_reg);
if (rc == -1) //读取保持寄存器的值,可读取多个连续输入保持寄存器
{
write_data_hex(&log[1], 1, Path_log2);
fprintf(stderr,"%s\n", modbus_strerror(errno));
printf("MY_Debug: modbus_read_registers Fail! \n");
return -1;
} // 这里保存为文件,如果你只有一根串口线,方便你观察结果。
write_data_hex(&log[2], 1, Path_log3); write_data_hex(tab_reg, 10, Path_dat); for (i=0; i<10; i++)
{
printf("reg[%d] = %d(0x%x)\n", i, tab_reg[i], tab_reg[i]);
} break;
} write_data_hex(&log[3], 1, Path_log4); //标记代码已顺利结束
modbus_close(ctx); //关闭modbus连接
modbus_free(ctx); //释放modbus资源,使用完libmodbus需要释放掉 return 0;
}
我的makefile:
CC = arm-none-linux-gnueabi-gcc #CFLAGS += -I../include -std=gnu99 -lm -lpthread -O3 -lstdc++ LIBS += -L /home/aston/LibModbus_Study/installHere/lib -lmodbus TARGET=main.out SRCS = Lib_Modbus_test.c OBJS = $(SRCS:.c=.o) $(TARGET):$(OBJS)
$(CC) $(LDFLAGS) $^ -o $@ $(LIBS) clean:
rm -rf $(TARGET) $(OBJS)
我使用到的工具软件: ModSim32
D:\Study_2019\LibModbus\使用到的工具软件\ModSim32 v1.A00-04
软件使用介绍:
先点击New, 就可以出现‘’2’的界面,并配置好参数,以便后面使用

待linux板子上的程序跑起来以后,用USB转串口线连接好板子的MODBUS串口和PC机的USB口,再点击下图所示的‘3’的Connect

代码中读取到的寄存器的值展示:


实验成功。注意,modbus一个寄存器占两个字节。大小端有区分。
玩转Libmodbus(二) 写代码体验的更多相关文章
- 让 AI 为你写代码 - 体验 Github Copilot
前几天在群里看到有大神分享 Copoilot AI 写代码,看了几个截图有点不敢相信自己的眼睛.今天赶紧自己也来体验一下 Copoilot AI 写代码到底有多神奇. 申请 现在 Copoilot 还 ...
- [转]<版本二>写代码的小女孩
天冷极了,下着雪,又快黑了.这是一年的最后一天——大年夜.在这又冷又黑的晚上,一个乖巧的小女孩在机房里调试程序.她从家里出来的时候还穿着一件外套,但是有什么用呢?那是一双很大的外套——那么大,不知是哪 ...
- 亮瞎你狗眼的写代码体验狂拽酷炫效果 activate-power-mode
年末了,整理一些收藏的资料,没想到发现一个敲代码的装逼神器; 话不多说上图 我是用idea装的,其他编辑器请自行查找 Preferences -> Plugins -> Install p ...
- vs2022+resharper C++ = 拥有一个不输clion的代码体验
这篇文章详细讲一下resharper C++在vs2022中的配置,让他拥有跟clion一样好用的代码补全功能. 为什么clion写代码体验很好好用为啥还要用vs呢,因为网上很多教程都是基于visua ...
- 如何结合整洁架构和MVP模式提升前端开发体验(二) - 代码实现篇
上一篇文章介绍了整体架构,接下来说说怎么按照上图的分层结构实现下面的增删改查的功能. 代码结构 vue userManage └── List ├── api.ts ├── EditModal │ ├ ...
- SQL强化(二) 在Oracle 中写代码
一 : 关于查询中的转换 -- 字符串转换 一 : decode 函数 转换 SELECT DECODE ( PROTYPE.PRO_TYPE_DATE, 'L', '长', 'm', '短', ' ...
- 有个AI陪你一起写代码,是种怎样的体验?| 附ICLR论文
从前,任何程序的任何功能,都需要一行一行敲出来. 后来,程序猿要写的代码越来越多,世界上便有了各种各样的API,来减少大家的工作量.有些功能,可以让API来帮我们实现. 不过,人类写下的话,API并不 ...
- Qt侠:像写诗一样写代码,玩游戏一样的开心心情,还能领工资!
[软]上海-Qt侠 2017/7/12 16:11:20我完全是兴趣主导,老板不给我钱,我也要写好代码!白天干,晚上干,周一周五干,周末继续干!编程已经深入我的基因,深入我的骨髓,深入我的灵魂!当我解 ...
- 手写MVC框架(二)-代码实现和使用示例
--------上一篇:手写MVC框架(一)-再出发----- 背景 书接上文,之前整理了实现MVC框架需要写哪些东西.这周粗看了一下,感觉也没多少工作量,所以就计划一天时间来完成.周末的时间,哪会那 ...
随机推荐
- 力扣Leetcode 50. 实现Pow(x, n)
实现Pow(x, n) 实现 pow(x, n) ,即计算 x 的 n 次幂函数. 示例 1: 输入: 2.00000, 10 输出: 1024.00000 示例 2: 输入: 2.10000, 3 ...
- shader变体
unity shader 变种(多重编译 multi_compile) https://www.jianshu.com/p/f34d896dde5d Unity Shader - Making mul ...
- Go测试开发(一) 怎么写Go代码
安装过程略过,网上搜一大把. 介绍 本文会在一个module中开发一个简单的Go package. 同时介绍go tool(也就是go命令行). 以及如何fetch,build和install Go的 ...
- 使用vuepress搭建GitHub pages静态博客页面
vuepress官网 vuepress是尤大开发来写文档的静态页面.可以用Markdown 语法,并且也可以使用vue模块化的方式开发页面. vuepress-theme-reco 是另外的开发者开发 ...
- Nginx小功能合集
13.1. 跨域处理 问题由来:浏览器拒绝执行其它域名下的ajax运作 ---如果浏览器在static.enjoy.com对应的html页面内,发起ajax请求偷盗www.enjoy.com域名下的内 ...
- fake_useragent.errors.FakeUserAgentError: Maximum amount of retries reached解决方法!
UserAgent 就是用户代理,又叫报头,是一串字符串,相当于浏览器的身份证号,在利用爬虫爬取网站数据时,频繁更换它可以避免触发相应的反爬机制. fake-useragent对频繁更换UserAge ...
- jmeter连接websocket wss
注:域名的默认端口号是443 1.先添加 WebSocket Open Connection:连接请求 2.再添加 WebSocket request-response Sampler:发送数据请求 ...
- jmeter压测以及用Badboy录脚本
一.压测时的基本配置: 1.设置线程数.延迟几秒.循环次数打勾表示一直去循环.调度器打勾可以填写持续时间.启动时间等 线程数:就是并发的用户数 N Ramp-Up Period(in second ...
- range如何倒序
for j in range(3,-2,-1): 表示对3进行每次加-1的操作,直到-2,但不包括-2 print(j) 打印出3 2 1 0 -1都换行展示的
- 测试软件—禅道BUG管理工具
入禅 目录 入禅 1.禅道的基本使用 1.禅道的基本使用 admin(管理员) 部门:创建部门(需求部门,开发部门,测试部门,项目部门,产品部门) 组织:创建用户(产品经理,项目经理,开发人员,测试人 ...