查看: 6290|回复: 1

[i.MX6ULL竞赛专区] 【我的项目666】+通讯管理(5)modbus-RTU主机

[复制链接]
  • TA的每日心情
    开心
    2024-4-5 11:15
  • 签到天数: 1061 天

    连续签到: 1 天

    [LV.10]以坛为家III

    29

    主题

    1517

    帖子

    31

    金牌会员

    Rank: 6Rank: 6

    积分
    4979
    最后登录
    2024-5-31
    发表于 2018-6-4 12:33:04 | 显示全部楼层 |阅读模式
    本帖最后由 story_xjj 于 2018-6-4 12:34 编辑

    试用5 Modbus-RTU主机代码测试

    在试用4中,我已经成功的将串口设备引出了,接下来可以使用这些串口与外设通讯了。

    本次试用的主题

    在ttymxc1接口上运行Modbus-RTU主机代码,管理外部Modbus-RTU子站


    1、 Libmodbus库

    通过网络搜索,linux下比较推崇的modbus库是libmodbus,他支持主站和子站两种模式,我准备采用这个库来测试一下。

    下载libmodbus源代码 http://libmodbus.org/download/

    本次采用稳定版libmodbus-3.0.6.tar.gz

    解压后的基本目录结构为

    libmodbus.JPG



    我准备在windows下开发,所以其它文件对我来说没什么用。

    2、 测试modbus-client代码与仿真子站通讯

    Windows下通过eclipse建立开发环境这里不介绍了,大家自己网上搜索吧。

    建立一个工程,将tests目录下的modbus-client.c文件添加进入,把src目录下的所有文件添加进去。

    注意修改modbus-client.c文件中的SERVERID,他是我们准备操作的子站地址,原文中为17,我这里修改为1.

    /*The goal of this program is to check all major functions of

       libmodbus:

       - write_coil

       - read_bits

       - write_coils

       - write_register

       - read_registers

       - write_registers

       - read_registers


       All these functions are called with randomvalues on a address

       range defined by the following defines.

    */

    #define LOOP            1

    #define SERVER_ID      1

    #define ADDRESS_START   0

    #define ADDRESS_END    10


    接下来介绍几个函数,用来写入和读取相关寄存器的内容。

    1) 写1位线圈函数 int modbus_write_bit(modbus_t *ctx, int addr, int status)

    ctx — 用来执行modbus操作的设备指针

    addr— 写入子站的寄存器地址

    status — 写入子站的线圈状态

    使用例子:

            rc =modbus_write_bit(ctx,addr, tab_rq_bits[0]);

            if (rc != 1) {

                printf("ERROR modbus_write_bit(%d)\n", rc);

                printf("Address = %d, value =%d\n", addr, tab_rq_bits[0]);

                nb_fail++;

             }


    2) 写多线圈函数

    /* Write the bits of the array inthe remote device */

    int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src)


    ctx — 用来执行modbus操作的设备指针

    addr— 写入子站的寄存器地址

    nb —— 写子站线圈个数

    src — 写入子站的线圈状态指针


    使用例子:

            rc =modbus_write_bits(ctx,addr, nb, tab_rq_bits);

            if (rc != nb) {

               printf("ERROR modbus_write_bits(%d)\n", rc);

               printf("Address = %d, nb =%d\n", addr, nb);

            }


    3) 读取多线圈函数

    /* Reads the boolean status ofbits and sets the array elements

      in the destination to TRUE or FALSE (single bits). */

    int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)


    ctx — 用来执行modbus操作的设备指针

    addr— 读取子站的寄存器地址

    nb —— 读取子站线圈个数

    dest — 读取子站的线圈状态保存指针


    使用例子:

            rc = modbus_read_bits(ctx, addr, nb, tab_rp_bits);

                if (rc != nb) {

                     printf("ERRORmodbus_read_bits\n");

                     printf("Address = %d, nb =%d\n", addr, nb);

                 }


    4) 写单寄存器

    /* Writes a value in one registerof the remote device */

    int modbus_write_register(modbus_t *ctx, int addr, int value)

          

    ctx — 用来执行modbus操作的设备指针

    addr— 写入子站的寄存器地址

    value — 写入子站的寄存器值

    使用例子:

               rc = modbus_write_register(ctx,addr, tab_rq_registers[0]);

                if (rc != 1) {

                   printf("ERRORmodbus_write_register (%d)\n", rc);

                   printf("Address = %d, value = %d(0x%X)\n",

                           addr, tab_rq_registers[0],tab_rq_registers[0]);

                }


    5) 写多寄存器

    /* Write the values from the arrayto the registers of the remote device */

    int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src)

          

    ctx — 用来执行modbus操作的设备指针

    addr— 写入子站的寄存器地址

    nb —— 写子站寄存器个数

    src — 写入子站的整型字数组指针


    使用例子:

               rc = modbus_write_registers(ctx, addr, nb, tab_rq_registers);

                if (rc != nb) {

                   printf("ERRORmodbus_write_registers (%d)\n", rc);

                   printf("Address = %d, nb =%d\n", addr, nb);

                }


    6) 读取多寄存器函数

    /* Reads the holding registers ofremote device and put the data into an array */

    int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)


    ctx — 用来执行modbus操作的设备指针

    addr— 读取子站的寄存器地址

    nb —— 读取子站寄存器个数

    dest — 读取子站的寄存器保存指针


    使用例子:

               rc= modbus_read_registers(ctx,addr, nb, tab_rp_registers);

               if (rc != nb) {

                   printf("ERRORmodbus_read_registers (%d)\n", rc);

                   printf("Address = %d, nb =%d\n", addr, nb);

                }



    7) 读写多寄存器函数

    /* Write multiple registers from “src”array to remote device and read multiple registers from remote device to “dest”array. */

    int modbus_write_and_read_registers(modbus_t *ctx,

                       int write_addr, int write_nb, const uint16_t *src,

                       int read_addr, int read_nb, uint16_t *dest

    )


    ctx — 用来执行modbus操作的设备指针

    write_addr—写子站的寄存器地址

    write_nb ——写子站寄存器个数

    src — 写子站的数据指针

    read_addr—读子站的寄存器地址

    read_nb ——读子站寄存器个数

    dest — 读子站的数据保存指针


    使用例子:

               rc = modbus_write_and_read_registers(ctx,

                                          addr, nb,tab_rw_rq_registers,

                                          addr, nb,tab_rp_registers);

                if (rc != nb) {

                   printf("ERRORmodbus_read_and_write_registers (%d)\n", rc);

                   printf("Address = %d, nb =%d\n", addr, nb);

                }


    3、 modbusslave模拟子站软件

    网上搜索可以找到modbus的子站仿真软件,用来配合调试比较方便。

    modbus子站.JPG



    评分

    参与人数 1 +3 收起 理由
    doatello + 3

    查看全部评分

    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-5 11:15
  • 签到天数: 1061 天

    连续签到: 1 天

    [LV.10]以坛为家III

    29

    主题

    1517

    帖子

    31

    金牌会员

    Rank: 6Rank: 6

    积分
    4979
    最后登录
    2024-5-31
     楼主| 发表于 2018-6-4 14:59:34 | 显示全部楼层
    本帖最后由 story_xjj 于 2018-6-4 15:01 编辑

    没有做细节测试 ,目前是功能性测试。我测试的主要是主机功能,巡检间隙可以控制,这个应该不是问题。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-8-21 11:42 , Processed in 0.090428 second(s), 21 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表