单片机/MCU论坛
直播中

xiaopeng

11年用户 224经验值
擅长:嵌入式技术,处理器/DSP
私信 关注
[文章]

【HD-G2UL-EVM开发板体验】Modbus通讯之Modbus从机实现

说明

在上一篇文章中已经使用libmodbus库实现了Modbus的主机并实现了与从机(Modbus Slave)的通讯。详见帖子:https://bbs.elecfans.com/jishu_2328461_1_1.html

本次将使用libmodbus库实现modbus的从机,并测试与主机的通讯。

编写测试程序

关于libmodbus库的安装和使用方法已经在上一篇文章中进行了详细说明,详见:https://bbs.elecfans.com/jishu_2328461_1_1.html。这里直接编写slave测试程序进行测试。

编写好的slave程序如下:

modbus_slave_test.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "modbus.h"
#define PORT_NAME "/dev/ttySC1"
int main(int argc, char *argv[])
{
    int ret = 0;
    uint8_t device = 1;
    uint8_t query[50];
    modbus_t *mb;
    modbus_mapping_t *mb_mapping;
    char port[20];
    printf("argc = %d, argv[1] = %s\n", argc, argv[1]);
    if(argc == 2)
        strcpy(port, argv[1]);
    else 
        strcpy(port, PORT_NAME);
    printf("libmodbus modbu-rtu slave demo: %s, 9600, N, 8, 1\n", port);
    mb = modbus_new_rtu(port, 9600, 'N', 8, 1);
    if (mb == NULL)
    {
        modbus_free(mb);
        printf("new rtu failed: %s\n", modbus_strerror(errno));
        return 0;
    }
    //register: 15/16/17
    mb_mapping = modbus_mapping_new_start_address(0, 0, 0, 0, 15, 3, 0, 0);
    if(mb_mapping == NULL)
    {
        modbus_free(mb);
        printf("new mapping failed: %s\n", modbus_strerror(errno));
        return 0;
    }
    //保持寄存器数据
    mb_mapping->tab_registers[0] = 0x1001;
    mb_mapping->tab_registers[1] = 0x1002;
    mb_mapping->tab_registers[2] = 0x1003;
    modbus_set_debug(mb, 1);//设置1可以看到调试信息
    modbus_set_slave(mb, 1);
    ret = modbus_connect(mb);
    if(ret == -1)
    {
        modbus_free(mb);
        printf("connect failed: %s\n", modbus_strerror(errno));
        return 0;
    }
    printf("create modbus slave success\n");
    while(1)
    {
        do {
            ret = modbus_receive(mb, query);    //轮询串口数据,
        } while (ret == 0);
        if(ret > 0) //接收到的报文长度
        {
            printf("len=%02d: ", ret);
            for(int idx = 0; idx < ret; idx++)
            {
                printf(" %02x", query[idx]);
            }
            printf("\n");
            modbus_reply(mb, query, ret, mb_mapping);
        }
        else
        {
            printf("quit the loop: %s", modbus_strerror(errno));
            modbus_mapping_free(mb_mapping);
            break;
        }
    }
    modbus_close(mb);
    modbus_free(mb);
    return 0;
}

编写makefile文件并编译

makefile文件:

modbus_slave_test:modbus_slave_test.c 
	$(CC) -Iinclude -o modbus_slave_test modbus_slave_test.c -L /usr/lib/ -lmodbus

clean:
	rm *.o modbus_slave_test

编译生成可执行文件:

图片.png

运行

将生成的可执行文件modbus_slave_test拷贝的开发板中,添加执行权限并运行。

使用PC端工具Modbus Poll模拟主机与开发板之间进行通讯,结果如下:

图片.png

结论

根据测试结果来看,Modbus从机的功能实现了,能够实现对主机数据请求的正确响应。

更多回帖

发帖
×
20
完善资料,
赚取积分