libmodbus,是一个基于C语言实现的Modbus驱动库,作者是Stephane,支持Linux, Mac OS X, FreeBSD, QNX and Win32操作系统。
主要应用在PC上,用来开发上位机,也可以对源代码进行交叉编译,以适配更多的平台,比如ARM Linux。源代码开源,遵循 LGPL-2.1许可。
开源地址:github.com/stephane/...
官方网站:www.libmodbus.org

libmodbus源码文件

  • win32: 定义在Windows下使用Visual Studio编译时的项目文件和工程文件以及相关配置选项等。其中,modbus-9.sln默认使用Visual Studio 2008。

  • Makefile.am: Makefile.am是Linux下AutoTool编译时读取相关编译参数的配置文件,用于生成Makefile文件,因为用于Linux下开发,所以在这里暂时忽略

  • modbus.c: 核心文件,实现Modbus协议层,定义共通的Modbus消息发送和接收函数各功能码对应的函数。

  • modbus.h: libmodbus对外暴露的接口API头文件。

  • modbus-data.c: 数据处理的共通函数,包括大小端相关的字节、位交换等函数

  • modbus-private.h: libmodbus内部使用的数据结构和函数定义。

  • modbus-rtu.c: 通信层实现,RTU模式相关的函数定义,主要是串口的设置、连接及消息的发送和接收等。

  • modbus-rtu.h: RTU模式对外提供的各API定义

  • modbus-rtu-private.h: RTU模式的私有定义。

  • modbus-tcp.c: 通信层实现,TCP模式下相关的函数定义,主要包括TCP/IP网络的设置连接、消息的发送和接收等。

  • modbus-tcp.h: 定义TCP模式对外提供的各API定义

  • modbus-tcp-private.h: TCP模式的私有定义。

  • modbus-version.h.in: 版本定义文件。

编译

下面是交叉编译,编译前配置好对应平台的编译工具链。

git clone https://github.com/stephane/libmodbus

cd libmodbus

./configure --host=${TOOLCHAIN_PREFIX} --prefix=$INSTALL_PREFIX

make
make install

应用例子

串口主站master应用

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "modbus.h"  //modbus动态库文件
 
int main(int argc, char *argv[])
{
	uint16_t tab_reg[64] = {0}; //定义存放数据的数组
    modbus_t *ctx = NULL;
 
    int rc;
	int i;
							        
	//以串口的方式创建libmobus实例,并设置参数
	//使用UART1,对应的设备描述符为ttyS1
	ctx = modbus_new_rtu("/dev/ttyS1", 115200, 'N', 8, 1);					
	if (ctx == NULL)
	{
    	fprintf(stderr, "Unable to allocate libmodbus contex\n");
    	return -1;
	}
	
	//设置1可看到调试信息
	modbus_set_debug(ctx, 1);
	//设置slave ID
	modbus_set_slave(ctx, 1);
	
	 //等待连接设备
	if (modbus_connect(ctx) == -1)
	{
    	fprintf(stderr, "Connection failed:%s\n", modbus_strerror(errno));
    	return -1;
	}
	
	while (1)
	{
    	printf("\n----------------\n");
		//读取保持寄存器的值,可读取多个连续输入保持寄存器
    	rc = modbus_read_registers(ctx, 0, 10, tab_reg);
    	if (rc == -1)
    	{
			fprintf(stderr,"%s\n", modbus_strerror(errno));
			return -1;
    	}
    	for (i=0; i<10; i++)
    	{
			printf("reg[%d] = %d(0x%x)\n", i, tab_reg[i], tab_reg[i]);
    	}
		
    	usleep(3000000);
	}
    modbus_close(ctx);
	modbus_free(ctx);
 
	return 0;
}

网口master应用

#include <modbus.h>
#include <stdio.h>
#include <stdlib.h>

int main() {

    modbus_t *ctx;
    modbus_mapping_t *mb_mapping;
    int rc;
    int s;


    // 创建一个Modbus TCP上下文
    ctx = modbus_new_tcp("127.0.0.1", 502);

    if (ctx == NULL) {
        fprintf(stderr, "Unable to allocate libmodbus contextn");
        return -1;
    }


    // 创建一个Modbus寄存器映射
    mb_mapping = modbus_mapping_new(0, 0, 100, 100);
    if (mb_mapping == NULL) {
        fprintf(stderr, "Failed to allocate the mapping: %sn", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }


    // 初始化寄存器值
    for (int i = 0; i < 100; i++) {
        mb_mapping->tab_registers[i] = i;
    }


    // 绑定并监听端口
    s = modbus_tcp_listen(ctx, 1);
    if (s == -1) {
        fprintf(stderr, "Unable to listen TCP: %sn", modbus_strerror(errno));

        modbus_free(ctx);
        modbus_mapping_free(mb_mapping);

        return -1;
    }

    while (1) {
        // 接受主机连接
        modbus_t *client_ctx = modbus_tcp_accept(ctx, &s);

        if (client_ctx == NULL) {
            fprintf(stderr, "Unable to accept the client: %sn", modbus_strerror(errno));
            continue;
        }

        // 处理主机请求
        while ((rc = modbus_receive(client_ctx, mb_mapping)) != -1) {
            modbus_reply(client_ctx, mb_mapping, rc);
        }

        // 关闭客户端连接
        modbus_close(client_ctx);
        modbus_free(client_ctx);
    }

    // 释放资源
    modbus_mapping_free(mb_mapping);

    modbus_close(ctx);
    modbus_free(ctx);

    return 0;

}
作者:SteveChen  创建时间:2025-06-15 21:27
最后编辑:SteveChen  更新时间:2025-06-16 09:11
上一篇:
下一篇: