目录
步骤:
(1)创建实例
(2)设置从机id
(3)建立连接
(4)寄存器操作
(5)释放mudbus 实例
(6)关闭套接字
1.通用函数
1.创建实例
modbus_t* modbus_new_tcp(const char *ip, int port)
功能:以TCP方式创建Modbus实例,并初始化
参数:
ip :ip地址
port :端口号
返回值:成功:Modbus实例
失败:NULL
2.设置从机id
int modbus_set_slave(modbus_t *ctx, int slave)
功能:设置从机ID
参数:
ctx :Modbus实例
slave :从机ID
返回值:成功:0
失败:-1
3.建立连接
int modbus_connect(modbus_t *ctx)
功能:和从机(slave)建立连接
参数:
ctx :Modbus实例
返回值 :成功:0
失败:-1
4.释放关闭
void modbus_free(modbus_t *ctx)
功能:释放Modbus实例
参数:ctx:Modbus实例
void modbus_close(modbus_t *ctx)
功能:关闭套接字
参数:ctx:Modbus实例
2.寄存器操作
2.1读线圈
int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
功能:读取线圈状态,可读取多个连续线圈的状态(对应功能码为0x01)
参数:
ctx :Modbus实例
addr :寄存器起始地址
nb :寄存器个数
dest :得到的状态值
2.2读离散
int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
功能:读取输入状态,可读取多个连续输入的状态(对应功能码为0x02)
参数:
ctx :Modbus实例
addr :寄存器起始地址
nb :寄存器个数
dest :得到的状态值
返回值:成功:返回nb的值
2.3读保持
int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
功能:读取保持寄存器的值,可读取多个连续保持寄存器的值(对应功能码为0x03)
参数:
ctx :Modbus实例
addr :寄存器起始地址
nb :寄存器个数
dest :得到的寄存器的值
返回值:成功:读到寄存器的个数
失败:-1
2.4读输入
int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
功能:读输入寄存器的值,可读取多个连续输入寄存器的值(对应功能码为0x04)
参数:
ctx :Modbus实例
addr :寄存器起始地址
nb :寄存器个数
dest :得到的寄存器的值
返回值:成功:读到寄存器的个数
失败:-1
2.5写单个线圈
int modbus_write_bit(modbus_t *ctx, int addr, int status);
功能:写入单个线圈的状态(对应功能码为0x05)
参数:
ctx :Modbus实例
addr :线圈地址
status :线圈状态
返回值 :成功:0
失败:-1
2.6写多个线圈寄存器
int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src);
功能:写入多个连续线圈的状态(对应功能码为15)
参数:
ctx :Modbus实例
addr :线圈地址
nb :线圈个数
src :多个线圈状态
返回值:成功:0
失败:-1
2
2.7写单个保持寄存器
int modbus_write_register(modbus_t *ctx, int addr, int value);
功能: 写入单个寄存器(对应功能码为0x06)
参数:
ctx :Modbus实例
addr :寄存器地址
value :寄存器的值
返回值:成功:0
失败:-1
2.8写多个保持寄存器
int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src);
功能:写入多个连续寄存器(对应功能码为16)
参数:
ctx :Modbus实例
addr :寄存器地址
nb :寄存器的个数
src :多个寄存器的值
返回值:成功:0
失败:-1
3.练习
练习一
实现 03功能:读当或多个保持寄存器
#include <stdio.h>
#include <modbus.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
int res;
modbus_t *ctx;
// 创建实例
ctx = modbus_new_tcp(argv[1], atoi(argv[2]));
// ctx = modbus_new_tcp("192.168.0.100", 502);
if (ctx == NULL)
{
perror("ctx mew error");
return -1;
}
// 设置从机id
int id;
printf("请输入从机id:");
scanf("%d", &id);
res = modbus_set_slave(ctx, id);
if (res < 0)
{
perror("id set error");
return -1;
}
// 建立连接
res = modbus_connect(ctx);
if (res < 0)
{
perror("connect error");
return -1;
}
// 寄存器操作
// 实现03功能,读保持寄存器
uint16_t data[128] = {0};
int addr, nb;
printf("请输入地址: ");
scanf("%d", &addr);
printf("请输入数量: ");
scanf("%d", &nb);
modbus_read_registers(ctx, addr, nb, data);
for (int i = 0; i < nb; i++)
{
printf("%04x ", data[i]);
}
printf("\n");
// 释放寄存器
modbus_free(ctx);
// 关闭套接字
modbus_close(ctx);
return 0;
}
练习二
任务:编程实现采集传感器数据和控制硬件设备(传感器和硬件通过slave模拟)
传感器:2个,温度传感器、湿度传感器
硬件设备:2个,led灯、蜂鸣器
要求:
1.多任务编程:多线程
2.循环1s采集一次数据,并将数据打印至终端
3.同时从终端输入指令控制硬件设备
0 1 :led灯打开
0 0:led灯关闭
1 1:蜂鸣器开
1 0 : 蜂鸣器关
#include <stdio.h>
#include <modbus.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
// 接收温湿度
void *handler(void *arg)
{
uint8_t buf[12] = {0};
uint16_t data[128] = {0};
while (1)
{
memset(buf, 0, sizeof(buf));
memset(data, 0, sizeof(data));
// 接收温度
modbus_read_input_registers(arg, 0, 1, data);
printf("温度: %d\n", data[0]);
// 接收湿度
modbus_read_input_registers(arg, 1, 1, data);
printf("湿度: %d\n", data[0]);
sleep(2);
}
return;
}
int main(int argc, char const *argv[])
{
// 连接modbusalave
int res;
modbus_t *ctx;
// 创建实例
ctx = modbus_new_tcp(argv[1], atoi(argv[2]));
// ctx = modbus_new_tcp("192.168.0.100", 502);
if (ctx == NULL)
{
perror("ctx mew error");
return -1;
}
// 设置从机id
int id;
printf("请输入从机id:");
scanf("%d", &id);
res = modbus_set_slave(ctx, id);
if (res < 0)
{
perror("id set error");
return -1;
}
printf("set scuess\n");
// 建立连接
res = modbus_connect(ctx);
if (res < 0)
{
perror("connect error");
return -1;
}
printf("connect scuess\n");
// 创建从线程
// 主线程发送,从线程接收
pthread_t tid;
res = pthread_create(&tid, NULL, handler, ctx);
if (res != 0)
{
perror("creat error");
return -1;
}
printf("pthread scuess\n");
uint8_t buf[32] = {0};
// 发送控制灯
while (1)
{
memset(buf, 0, sizeof(buf));
scanf("%d %d", &buf[0], &buf[1]);
if (buf[0] == 0)
{
modbus_write_bit(ctx, 0, buf[1]);
}
if (buf[0] == 1)
{
modbus_write_bit(ctx, 1, buf[1]);
}
}
// 回收从线程
pthread_detach(&tid);
// 释放寄存器
modbus_free(ctx);
// 关闭套接字
modbus_close(ctx);
return 0;
}