玩转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框架需要写哪些东西.这周粗看了一下,感觉也没多少工作量,所以就计划一天时间来完成.周末的时间,哪会那 ...
随机推荐
- Inno Setup Compiler 中文使用教程
一.概要 该文章主要解决,Inno Setup Compiler工具的使用问题. 如有什么建议欢迎提出,本人及时修改.[如有任何疑惑可以加Q群:580749909] 二.步骤 (1)下载地址:http ...
- DevExpress的WidgetView的使用介绍
很多程序可能都会有一个首页综合展示系统的相关信息,如汇总信息,图表统计.待办业务.提醒信息等内容,在Web上可能叫做Dashboard仪表板,或者首页页面,不管哪种叫法,都是综合展示一些信息,提供一些 ...
- 热更新 && 增量更新
Unity中SLua.Tolua.XLua和ILRuntime效率评测 http://blog.csdn.net/u011467512/article/details/72716376 如何阅读lua ...
- slua中,绑定lua文件到Monobehavior的一种方法
slua本身并不提供如何把一个lua文件绑定到一个预制中,就像一个普通的继承自monobehavior的自定义脚本那样,而tolua的框架却采用了拙劣的做法: public class LuaBeha ...
- java初探(1)之登录补充
在登录之后,可能服务器是分布式的,因此不能通过一个本地的session来管理登录信息,导致登录的信息不能传递,即在这台服务器上可以得到用户登录信息,但在那台就得不到.因此,需要设置分布式的sessio ...
- PHP弱类型hash比较缺陷
成因分析: == 在进行比较的时候,会先将两边的变量类型转化成相同的,再进行比较 0e在比较的时候会将其视作为科学计数法,所以无论0e后面是什么,0的多少次方还是0. 因此CTF比赛中需要用到弱类型H ...
- HTTP协议中的提交方式和解释POST、GET、HEAD、PUT等
最基本的方法有4种,分别是GET,POST,PUT,DELETE HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作 GET一般用于获取/查询资源信息,而PO ...
- 浅谈HASH长度拓展攻击
前言 最近在做CTF题的时候遇到这个考点,想起来自己之前在做实验吧的入门CTF题的时候遇到过这个点,当时觉得难如看天书一般,现在回头望去,仔细琢磨一番感觉也不是那么难,这里就写篇文章记录一下自己的学习 ...
- 【Flutter 实战】各种各样形状的组件
老孟导读:Flutter中很多组件都有一个叫做shape的属性,类型是ShapeBorder,比如Button类.Card等组件,shape表示控件的形状,系统已经为我们提供了很多形状,对于没有此属性 ...
- Spring Boot 整合Redis 实现缓存
本文提纲 一.缓存的应用场景 二.更新缓存的策略 三.运行 springboot-mybatis-redis 工程案例 四.springboot-mybatis-redis 工程代码配置详解 ...