libmodbus 软件包的使用记录 -- 基于 rs485 通讯

一、libmodbus的介绍

libmodbus 的链接网址
关于 rtu 功能,libmodbus 库的相关 API 如下:
在这里插入图片描述

二、测试代码

测试代码的网址链接
测试代码如下:
在这里插入图片描述

modbus_t *ctx;
uint16_t tab_reg[10];
ctx = modbus_new_rtu("/dev/ttyS0", 115200, 'N', 8, 1);
modbus_set_slave(ctx, 1);
modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485);
modbus_rtu_set_rts(ctx, MODBUS_RTU_RTS_UP);
if (modbus_connect(ctx) == -1) {


    fprintf(stderr, "Connexion failed: %s\n", modbus_strerror(errno));


    modbus_free(ctx);


    return -1;
}
rc = modbus_read_registers(ctx, 0, 7, tab_reg);
if (rc == -1) {


    fprintf(stderr, "%s\n", modbus_strerror(errno));


    return -1;
}
modbus_close(ctx);
modbus_free(ctx);

三、问题描述

按照上面代码,测试通过 rs485 获取 modbus 数据是有问题的。
问题1
modbus_rtu_set_serial_mode 函数涉及到了串口操作
在这里插入图片描述
如果在未连接前,ctx->s 的值是有问题的。此时会报错。
将此函数放在 connect 后面即可。
在这里插入图片描述
问题2
报错提示

MODBUS RTU Error Connection Time Out: select

在这里插入图片描述
修改方法参考如下:
参考链接1
在这里插入图片描述
参考链接2

官方默认的 rts 操作函数如下
在这里插入图片描述
需要使用设置函数

int modbus_rtu_set_custom_rts(modbus_t *ctx, void (*set_rts) (modbus_t *ctx, int on))

在这里插入图片描述

调用自己的 rts 相关函数。

四、验证测试

修改代码如下:

	if (modbus_connect(ctx) == -1) 
    {
        fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }

    modbus_set_debug(ctx,TRUE);

    if (modbus_connect(ctx) == -1) 
    {
        fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }

    if (modbus_rtu_set_serial_mode(ctx,MODBUS_RTU_RS485) == -1) 
    {
        fprintf(stderr, "set rs485 mod failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }
    if(modbus_rtu_set_rts(ctx,MODBUS_RTU_RTS_UP ) == -1)
    {
        fprintf(stderr, "set rs485 rts up failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }  
    // if(modbus_rtu_set_rts_delay(ctx,15000 ) == -1)
    // {
    //     fprintf(stderr, "set rs485 rts delay us failed: %s\n", modbus_strerror(errno));
    //     modbus_free(ctx);
    //     return -1;
    // }   
    if(modbus_rtu_set_custom_rts(ctx, custom_rts_rtu) == -1)
    {
        fprintf(stderr, "set custom rts fun failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }

自定义的rts功能相关函数

#include <fcntl.h>
#define SERVER_GPIO_INDEX   "110"

//  static int custom_rts_ioctl_init(void)
//  {
//      int fd;
//      //index config
//      fd = open("/sys/class/gpio/export", O_WRONLY);
//      if(fd < 0)
//          return 1;
 
//      write(fd, SERVER_GPIO_INDEX, strlen(SERVER_GPIO_INDEX));
//      close(fd);
 
//      //direction config
//      fd = open("/sys/class/gpio/gpio" SERVER_GPIO_INDEX "/direction", O_WRONLY);
//      if(fd < 0)
//          return 2;
 
//      write(fd, "out", strlen("out"));
//      close(fd);
 
//      return 0;
//  }

static int custom_rts_rtu_ioctl_on(void)
 {
	int fd;

 
	fd = open("/sys/class/gpio/gpio" SERVER_GPIO_INDEX "/value", O_WRONLY);
	if(fd < 0)
		return 1;
 
	write(fd, "1", 1);
	close(fd);
	return 0;
 }
 
 static int custom_rts_rtu_ioctl_off(void)
 {
     int fd;
 
     fd = open("/sys/class/gpio/gpio" SERVER_GPIO_INDEX "/value", O_WRONLY);
     if(fd < 0)
         return 1;
 
     write(fd, "0", 1);
     close(fd);
     return 0;
 }

static void custom_rts_rtu(modbus_t *ctx, int on)
{
     if (on) 
     {
         custom_rts_rtu_ioctl_on();
     } 
     else 
     {
         custom_rts_rtu_ioctl_off();
     }
 }

重新编译,下载即可。最终测试,模拟软件的log日志可以看到通信信息,如下:
在这里插入图片描述

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值