Modbus通信接口

头文件: cpp/interface/nrc_modbus.h 及 cpp/parameter/nrc_interface_parameter.h

1. modbus_set_master_parameter - 设置Modbus RTU主站参数

方法: int modbus_set_master_parameter(SOCKETFD socket_fd, int id, const ModbusMasterParameter& param);

功能描述: 配置Modbus RTU或TCP主站参数。此接口用于设置通信协议栈参数。

参数:

  • socket_fd:已连接的句柄
  • id:主站通道编号(0~8)
  • param:ModbusMasterParameter结构体,包含type("RTU"或"TCP"),startAddress,以及嵌套的RTU或TCP子结构

返回值:

  • int
    • 0:成功
    • 负值:失败

使用示例:

C++
bool test_set_modbus_master_rtu(int id, int slaveId, int port, int baudrate, const std::string& checkBit = "None", int dataBit = 8, int stopBit = 1) {
    if (socket_fd_6001_ <= 0) return false;
    // 实例化Modbus主站参数结构体并配置RTU串行通信核心参数
    ModbusMasterParameter param;
    param.type            = "RTU";    // 指定通信协议类型为串行链路RTU模式
    param.startAddress    = true;     // 激活/使能该主站配置
    param.RTU.slaveId     = slaveId;   // 目标从站设备物理ID号
    param.RTU.port        = port;      // 控制器物理串口号(如RS485端口号)
    param.RTU.baudrate    = baudrate;  // 通信波特率(如9600,115200等)
    param.RTU.checkBit    = checkBit;  // 校验位("None", "Odd", "Even")
    param.RTU.dataBit     = dataBit;   // 数据位(通常为8)
    param.RTU.stopBit     = stopBit;   // 停止位(通常为1或2)
    // 传入控制端口句柄、主站索引ID以及配置好的参数结构体,调用底层接口改写Modbus配置
    int ret = modbus_set_master_parameter(socket_fd_6001_, id, param);
    CHECK_RET(ret, "设置Modbus RTU主站 ID=" + std::to_string(id));
    return ret == SUCCESS;
}

2. modbus_open_master - 打开Modbus主站

方法: int modbus_open_master(SOCKETFD socket_fd, int id);

功能描述: 激活指定的Modbus主站通道,开始总线通信。

参数:

  • socket_fd:已连接的句柄
  • id:主站通道编号(0~8)

返回值:

  • int
    • 0:成功
    • 负值:失败

使用示例:

C++
bool test_open_modbus_master(int id) {
    if (socket_fd_6001_ <= 0) return false;
    // 传入控制端口句柄和目标主站索引ID,调用底层接口正式建立并启动该Modbus主站的通信线程
    int ret = modbus_open_master(socket_fd_6001_, id);
    CHECK_RET(ret, "打开Modbus主站 ID=" + std::to_string(id));
    return ret == SUCCESS;
}

3. modbus_write_multiple_holding_registers - 写多个保持寄存器

方法: int modbus_write_multiple_holding_registers(SOCKETFD socket_fd, int id, int address, const std::vector<int>& data);

功能描述: 使用功能码16(0x10)向从站批量写入寄存器。

参数:

  • socket_fd:已连接的句柄
  • id:主站通道编号
  • address:起始寄存器地址
  • data:待写入的16位整型数据列表

返回值:

  • int
    • 0:成功
    • 负值:失败(从站无响应、地址越界等)

使用示例:

C++
bool test_modbus_write_multiple_registers(int id, int address, const std::vector<int>& data) {
    if (socket_fd_6001_ <= 0) return false;
    // 校验传入的数据包,确保待写入的寄存器数值序列不为空
    if (data.empty()) {
        std::cout << "[提示] 写入的寄存器数据不能为空" << std::endl;
        return false;
    }
    // 传入控制端口句柄、主站ID、起始寄存器物理地址以及数据向量,调用底层接口执行Modbus批量保持寄存器写入
    int ret = modbus_write_multiple_holding_registers(socket_fd_6001_, id, address, data);
    if (ret != SUCCESS) {
        std::cout << "[失败] Modbus批量写入寄存器失败,错误码: " << ret << std::endl;
        return false;
    }
    std::cout << "[成功] Modbus ID=" << id << " 从地址 " << address
              << " 开始成功写入 " << data.size() << " 个寄存器值" << std::endl;
    return true;
}

4. modbus_read_holding_registers - 读取多个保持寄存器

方法: int modbus_read_holding_registers(SOCKETFD socket_fd, int id, int address, int quantity, std::vector<int>& data);

功能描述: 使用功能码03读取保持寄存器。

参数:

  • socket_fd:已连接的句柄
  • id:主站通道编号
  • address:起始寄存器地址
  • quantity:要读取的寄存器数量
  • data:输出参数,存储读取到的数据

返回值:

  • int
    • 0:成功
    • 负值:失败

使用示例:

C++
bool test_modbus_read_holding_registers(int id, int address, int quantity, std::vector<int>& out_data) {
    if (socket_fd_6001_ <= 0) return false;
    // 校验读取长度,确保请求的寄存器数量符合Modbus协议规范
    if (quantity <= 0) {
        std::cout << "[提示] 读取的寄存器数量必须大于0" << std::endl;
        return false;
    }
    // 提前为输出容器开辟足够的存储空间,便于底层接口直接写入数据
    out_data.resize(quantity);
    // 传入控制端口句柄、主站ID、起始寄存器地址、读取数量及输出容器,调用底层接口执行Modbus读取
    int ret = modbus_read_holding_registers(socket_fd_6001_, id, address, quantity, out_data);
    if (ret != SUCCESS) {
        out_data.clear();
        std::cout << "[失败] Modbus读取寄存器失败,错误码: " << ret << std::endl;
        return false;
    }
    std::cout << "[成功] Modbus ID=" << id << " 从地址 " << address
              << " 开始成功读取了 " << quantity << " 个寄存器值" << std::endl;
    return true;
}

完整Modbus Rtu使用示例见使用示例1所示。