libmodbus 开源库(第一部分)

 

下载地址

libmodbus 开源库地址:https://github.com/stephane/libmodbus

编译方式

安装必要的软件    sudo apt-get install pkg-config autoconf automake make libtool

编译 libmodbus    ./autogen.sh && ./configure --prefix=/usr && && make && sudo make install

测试代码编译需要使用 pkg-config,例如:

gcc random-test-server.c -o random-test-server `pkg-config --libs --cflags libmodbus`

函数说明

modbus_new_tcp

/*
    函数作用:创建一个 modbus_t 结构
    参数说明:
        ip    指定该客户端要建立连接的服务器的IP地址。NULL值可用于侦听服务器模式下的任何地址
        port  TCP端口。将端口设置MODBUS_TCP_DEFAULT_PORT为使用默认端口 (502)。使用大于或等于1024的端口号很方便,因为不需要管理员权限。
    返回值:
        如果成功,该函数应返回一个指向modbus_t结构的指针。否则,它将返回NULL并将errno设置为以下定义的值之一。  
*/
modbus_t *modbus_new_tcp(const char *ip, int port);


示例代码:
modbus_t *ctx;

ctx = modbus_new_tcp("127.0.0.1", 1502);
if (ctx == NULL) {
    fprintf(stderr, "Unable to allocate libmodbus context\n");
    return -1;
}

modbus_connect 

/*
    函数作用:连接到一个 Modbus TCP 服务器
    参数说明:
        ctx    modbus_new_tcp 创建的 modbus_t 结构体
    返回值:
        成功:该函数应返回0
        失败:将返回-1,并将errno设置为基础平台的系统调用所定义的值之一。
*/
int modbus_connect(modbus_t *ctx);

示例代码:
modbus_t *ctx;

ctx = modbus_new_tcp("127.0.0.1", 502);
if (modbus_connect(ctx) == -1) {
    fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
    modbus_free(ctx);
    return -1;
}
/*
    函数作用:关闭 modbus 连接
*/
void modbus_close(modbus_t *ctx);

/*
    函数作用:释放 modbus_t 环境
*/
void modbus_free(modbus_t *ctx);

 modbus_read_bits

/*
    函数作用:读取线圈状态,使用功能码 0x01。地址范围:0区(00001-09999)
    参数说明:
        ctx     modbus_new_tcp 创建的 modbus_t 结构体
        addr    起始地址
        nb      地址长度
        dest    读取结果(必须注意分配足够的内存以将结果存储在dest中,注意数据类型为 uint8_t)
    返回值:
        如果成功,该函数应返回读取位数。否则它将返回-1并设置errno
*/
int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);

示例代码:

int i, rc;
uint8_t bit_reg[32];
memset(bit_reg, 0, sizeof(bit_reg));
rc = modbus_read_bits(mb, 0, 10, bit_reg);
if(rc == -1)
{
     printf("%s\n", modbus_strerror(errno));
}

for(i = 0; i < rc; i++)
{
     printf("reg[%d]=%d\t(0x%X)\n", i, bit_reg[i], bit_reg[i]);
}

modbus_read_input_bits 

/*
    函数作用:读取离散量输入,使用功能码 0x02,地址范围:1区(10001-19999)
    参数说明:
        ctx     modbus_new_tcp 创建的 modbus_t 结构体
        addr    起始地址
        nb      地址长度
        dest    读取结果(必须注意分配足够的内存以将结果存储在dest中,注意数据类型为 uint8_t)
    返回值:
        如果成功,该函数应返回读取位数。否则它将返回-1并设置errno
*/
int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);

示例代码:

int i, rc;
uint8_t bit_reg[32];
memset(bit_reg, 0, sizeof(bit_reg));
rc = modbus_read_input_bits(mb, 0, 10, bit_reg);
if(rc == -1)
{
     printf("%s\n", modbus_strerror(errno));
}

for(i = 0; i < rc; i++)
{
     printf("reg[%d]=%d\t(0x%X)\n", i, bit_reg[i], bit_reg[i]);
}

modbus_read_registers 

/*
    函数作用:读取保持寄存器,使用功能码 0x03,地址范围:4区(40001-49999)
    参数说明:
        ctx     modbus_new_tcp 创建的 modbus_t 结构体
        addr    起始地址
        nb      地址长度
        dest    读取结果(必须注意分配足够的内存以将结果存储在dest中,注意数据类型为 uint16_t)
    返回值:
        如果成功,该函数应返回读取位数。否则它将返回-1并设置errno
*/
int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);

示例代码:

int i, rc;
uint16_t tab_reg[32];
memset(tab_reg, 0, sizeof(tab_reg));
rc = modbus_read_input_bits(mb, 0, 10, tab_reg);
if(rc == -1)
{
     printf("%s\n", modbus_strerror(errno));
}

for(i = 0; i < rc; i++)
{
     printf("reg[%d]=%d\t(0x%X)\n", i, tab_reg[i], tab_reg[i]);
}

modbus_read_registers 

/*
    函数作用:读取输入寄存器,使用功能码 0x04,地址范围:3区(30001-39999)
    参数说明:
        ctx     modbus_new_tcp 创建的 modbus_t 结构体
        addr    起始地址
        nb      地址长度
        dest    读取结果(必须注意分配足够的内存以将结果存储在dest中,注意数据类型为 uint16_t)
    返回值:
        如果成功,该函数应返回读取位数。否则它将返回-1并设置errno
*/
int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);

示例代码:

int i, rc;
uint16_t tab_reg[32];
memset(tab_reg, 0, sizeof(tab_reg));
rc = modbus_read_input_registers(mb, 0, 10, tab_reg);
if(rc == -1)
{
     printf("%s\n", modbus_strerror(errno));
}

for(i = 0; i < rc; i++)
{
     printf("reg[%d]=%d\t(0x%X)\n", i, tab_reg[i], tab_reg[i]);
}

modbus_write_bit 

/*
    函数说明:写单个线圈,使用功能码 0x05,地址范围:0区(00001-09999)
    参数说明:
        ctx         modbus_new_tcp 创建的 modbus_t 结构体
        addr        线圈地址
        status      线圈状态。(线圈状态只有 ON 和 OFF 两种值,所以 status 传入非 0 值,线圈状态被设置为 ON,status 传入 0 值,线圈状态被设置为 OFF)
    返回值:
        如果成功,该函数应返回1。否则它将返回-1并设置errno。
*/
int modbus_write_bit(modbus_t *ctx, int addr, int status);

示例代码:
for(i = 0; i < 10; i++)
{
	rc = modbus_write_bit(mb, i, 1);
	if(rc == -1)
	{
		printf("addr %d write failed\n", i);
	}
	sleep(1);
}

modbus_write_register 

/*
    函数作用:写单个保持寄存器,使用功能码 0x06,地址范围:4区(40001-49999)
    参数说明:
        ctx         modbus_new_tcp 创建的 modbus_t 结构体
        addr        线圈地址
        value       要设置的寄存器值
*/
int modbus_write_register(modbus_t *ctx, int addr, const uint16_t value);

示例代码:

for(i = 0; i < 10; i++)
{
	rc = modbus_write_register(mb, i, i*16);
	if(rc == -1)
	{
		printf("addr %d write failed\n", i);
	}
	sleep(1);
}

modbus_write_bits 

/*
    函数作用:写多个线圈,使用功能码 0x0F,地址范围:0区(00001-09999)
    参数说明:
        ctx     modbus_new_tcp 创建的 modbus_t 结构体
        addr    起始地址
        nb      地址长度
        src     存储要设置的线圈值的数组
    返回值:
        如果成功,该函数应返回已写入的位数。否则它将返回-1并设置errno。
*/
int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src);

示例代码:

const uint8_t src8_t[10] = {0, 1, 1, 0, 1, 0, 1, 0, 1, 1};
rc = modbus_write_bits(mb, 0, 10, src8_t);
if(rc == -1)
{
	printf("write bits failed, %s\n", modbus_strerror(errno));
}

 modbus_write_registers

/*
    函数作用:写多个保持寄存器,使用功能码 0x10,地址范围:4区(40001-49999)
    参数说明:
        ctx     modbus_new_tcp 创建的 modbus_t 结构体
        addr    起始地址
        nb      地址长度
        src     存储要设置的寄存器值的数组
    返回值:
        如果成功,该函数应返回已写寄存器的数量。否则它将返回-1并设置errno。
*/
int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src);

示例代码:

const uint16_t src16_t[10] = {100, 200, 179, 213, 3254, 322, 432, 311, 442, 797};
rc = modbus_write_registers(mb, 0, 10, src16_t);
if(rc == -1)
{
	printf("write registers failed, %s\n", modbus_strerror(errno));
}

 

你可能感兴趣的:(Modbus,专题,modbus)