modbus 函数

目录

1.通用函数

1.创建实例

 2.设置从机id

3.建立连接

4.释放关闭

2.寄存器操作

2.1读线圈

2.2读离散

2.3读保持

2.4读输入

2.5写单个线圈

2.6写多个线圈寄存器

2.7写单个保持寄存器

2.8写多个保持寄存器

3.练习

练习一

练习二


步骤:

(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;
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值