首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Modbus主机-slave通信

Modbus主机-slave通信
EN

Stack Overflow用户
提问于 2019-04-23 14:56:29
回答 1查看 921关注 1票数 3

要求:通过Modbus从串行端口收集数据,在串行端口-2上镜像相同的数据。

我可以在Master和slave之间通信,但无法将数据镜像到串口2。请建议我如何实现这一点。

代码:

代码语言:javascript
运行
复制
Master : 
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>   /* File Control Definitions           */
#include <termios.h> /* POSIX Terminal Control Definitions */
#include <unistd.h>  /* UNIX Standard Definitions      */
#include <errno.h>   /* ERROR Number Definitions           */
#include <sys/ioctl.h>
#include "modbus.h"

int main()
{
    uint8_t req[MODBUS_RTU_MAX_ADU_LENGTH];// request buffer
    int len;// length of the request/response
    printf("Modbus server example.\n");

    //Create a new RTU context with proper serial parameters (in this example,
    //device name /dev/ttyS0, baud rate 9600, no parity bit, 8 data bits, 1 stop bit)
    modbus_t *ctx = modbus_new_rtu("/dev/ttyUSB3", 9600, 'N', 8, 1);
    if (!ctx) {
        fprintf(stderr, "Failed to create the context: %s\n", modbus_strerror(errno));
        exit(1);
    }

    if (modbus_connect(ctx) == -1) {
        fprintf(stderr, "Unable to connect: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        exit(1);
    }
    else
    {
        printf("Modbus server connected successfully\n");
    }

    //Set the Modbus address of the remote slave (to 3)
    int rc=modbus_set_slave(ctx, 3);
    printf("Modbus set remote slave return code : %d\n",rc);


    uint16_t reg[5];// will store read registers values

    //Read 5 holding registers starting from address 10
    int num = modbus_read_registers(ctx, 10, 5, reg);
    printf("Result of modbus_read_registers : %d\n",num);
    for(int i=10;i<=15;i++)
    {
         printf("reg [%d] : %X\t",i,reg[i]);
    }
    printf("\n");
        if (num != 5) 
    {// number of read registers is not the one expected
        fprintf(stderr, "Failed to read: %s\n", modbus_strerror(errno));
    }



    modbus_close(ctx);
    modbus_free(ctx);
}

====从机:

代码语言:javascript
运行
复制
#include <stdio.h>
#include <fcntl.h>   /* File Control Definitions           */
#include <termios.h> /* POSIX Terminal Control Definitions */
#include <unistd.h>  /* UNIX Standard Definitions      */
#include <errno.h>   /* ERROR Number Definitions           */
#include <sys/ioctl.h>
#include "modbus/modbus.h"
int main()
{

    int len1=-1;
    printf("Modbus slave example");
    //Prepare a Modbus mapping with 30 holding registers
    //(plus no output coil, one input coil and two input registers)
    //This will also automatically set the value of each register to 0
    modbus_mapping_t *mapping = modbus_mapping_new(0, 1, 30, 2);
    if (!mapping) {
        fprintf(stderr, "Failed to allocate the mapping: %s\n", modbus_strerror(errno));
        exit(1);
    }
    else
    {
        printf("Mapping allocated successfully.\n");
    }


    //Example: set register 12 to integer value 623
    mapping->tab_registers[12] = 623;


    modbus_t *ctx = modbus_new_rtu("/dev/ttyHSL1", 9600, 'N', 8, 1);
    if (!ctx) {
        fprintf(stderr, "Failed to create the context: %s\n", modbus_strerror(errno));
        exit(1);
    }

    //Set the Modbus address of this slave (to 3)
   int rc= modbus_set_slave(ctx, 3);
   printf("Result code of Modbus set slave address :%d\n",rc);


    if (modbus_connect(ctx) == -1) {
        fprintf(stderr, "Unable to connect: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        exit(1);
    }
    else
    {
        printf("Modbus slave connected successfully\n");
    }


    uint8_t req[MODBUS_RTU_MAX_ADU_LENGTH];// request buffer
    int len;// length of the request/response

    while(1) {
        len = modbus_receive(ctx, req);
        printf("Modbus receive len : %d\n",len);
        if (len == -1)
            break;

        len1 = modbus_reply(ctx, req, len, mapping);
        printf("req: %X\n",*req);
        printf("len : %d\n",len);
        printf("mapping->tab_registers[12] : %d\n",mapping->tab_registers[12]);

        printf("Result Modbus reply len : %d\n",len1);
        if (len == -1) break;
    }
    printf("Exit the loop: %s\n", modbus_strerror(errno));

    modbus_mapping_free(mapping);
    modbus_close(ctx);
    modbus_free(ctx);
}

o/p : Master:

代码语言:javascript
运行
复制
shilpa@RT:~/Desktop/Modbus_master/Modbus_masterComponent/src$ sudo ./Modbus_masterComponent 
Modbus server example.
Modbus server connected successfully
Modbus set remote slave return code : 0
Result of modbus_read_registers : 5
reg [10] : 0    reg [11] : 0    reg [12] : AAC6 reg [13] : CDB5 reg [14] : 7F6D reg [15] : 0

从设备:

代码语言:javascript
运行
复制
root@swi-mdm9x15:~# /legato/systems/current/apps/Modbus_slave/read-only/bin/modbus_slave 
Modbus slave exampleMapping allocated successfully.
Result code of Modbus set slave address :0
Modbus slave connected successfully
Modbus receive len : 8
req: 3
len : 8
mapping->tab_registers[12] : 623
Result Modbus reply len : 15
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-24 00:44:33

您不能像在for循环中那样简单地索引10 - 15之间的5个插槽数组。不这是错的。它的索引将从0到4。

代码语言:javascript
运行
复制
uint16_t reg[5];// will store read registers values

//Read 5 holding registers starting from address 10
int num = modbus_read_registers(ctx, 10, 5, reg);
printf("Result of modbus_read_registers : %d\n",num);
for(int i=10;i<=15;i++)
{
     printf("reg [%d] : %X\t",i,reg[i]);
}

For循环应该看起来像这样。另外,%X用于打印十六进制的内容。如果您想看到存储在从机端的623 (十进制)在主机端以十进制打印,则使用%d,如下所示。

代码语言:javascript
运行
复制
for(int i=0;i<5;i++)
{
     printf("reg [%d] : %d\t",i+10, reg[i]);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55805817

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档