Qt Modbus 寄存器读写实例

一.线圈状态寄存器读写

  • 项目效果如下
    在这里插入图片描述

1. 写单个寄存器

  • MODBUS_API int modbus_write_bit(modbus_t *ctx, int coil_addr, int status);
int addr=ui->spinBoxwirte_addr->value();
    int data=ui->spinBoxwirte_data->value();
    int ret = modbus_write_bit(mb,addr,data);

    if(ret!=1)
    {
   
   
        QMessageBox::information(this,"失败",
                                 "写状态寄存器失败,地址:"+QString::number(data));
    }else
    {
   
   
        label_status->setText("写线圈状态寄存器成功!");
    }

2. 读单个寄存器

  • int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);
int addr=ui->spinBoxRead_addr->value();
    int data=ui->spinBoxRead_data->value();
    //int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);
    uint8_t dest[4];
    int ret = modbus_read_bits(mb,addr,1,dest);

    if(ret!=1)
    {
   
   
        QMessageBox::information(this,"失败",
                                 "读状态寄存器失败,地址:"+QString::number(data));
    }else
    {
   
   
        label_status->setText("读线圈状态寄存器成功!");
        qDebug()<<"读出的数据为:"<<dest[0];
        ui->spinBoxRead_data->setValue(dest[0]);
    }

3. 写多个寄存器

  • int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *data);
int addr=ui->spinBoxWriteMore_addr->value();

    //使用正则表达式,来处理字符串的分割
    QString  str = ui->textEdit_xianWrite->toPlainText();

    //用正则表达式进行分割
    QRegExp separator= QRegExp("\t|\n|\r\n|,| |;");

    //进行分割
    QStringList list =  str.split(
### 如何在 Qt 中实现 MODBUS TCP 读写指令 #### 构造 MODBUS TCP 写操作 通过 `QVector` 和 Modbus 协议标准,可以构建一个用于发送数据的函数。以下是基于引用中的描述以及 Modbus 官方 API 的方法来完成此功能。 ```cpp #include <QtNetwork> #include <QDebug> void writeModbusRegisters(QTcpSocket *socket, quint16 startAddress, const QVector<quint16> &values) { QByteArray data; QDataStream stream(&data, QIODevice::WriteOnly); stream.setByteOrder(QDataStream::LittleEndian); // 计算消息长度 (起始地址 + 数据数量) int messageLength = values.size() * 2 + 1; // 构建请求帧 stream << static_cast<char>(0); // Transaction ID 高字节 stream << static_cast<char>(0); // Transaction ID 低字节 stream << static_cast<char>(0); // Protocol ID 高字节 stream << static_cast<char>(0); // Protocol ID 低字节 stream << static_cast<char>(messageLength >> 8); // Length 高字节 stream << static_cast<char>(messageLength & 0xFF); // Length 低字节 stream << static_cast<char>(0); // Unit Identifier stream << static_cast<char>(0x10); // 功能码 0x10 表示写多个寄存器 stream << static_cast<char>(startAddress >> 8); // 起始地址高字节 stream << static_cast<char>(startAddress & 0xFF); // 起始地址低字节 stream << static_cast<char>(values.size() >> 8); // 寄存器数量高字节 stream << static_cast<char>(values.size() & 0xFF); // 寄存器数量低字节 stream << static_cast<char>(values.size() * 2); // 字节数量 for (const auto &value : values) { // 添加实际数据 stream << value; } socket->write(data); } ``` 以上代码展示了如何构造一个写入多个寄存器的功能码 `0x10` 请求包[^1]。它利用了 `QDataStream` 来处理二进制流并确保字节顺序正确。 --- #### 构造 MODBUS TCP 读操作 对于读取操作,通常使用功能码 `0x03` 或 `0x04`。下面是一个简单的例子: ```cpp void readModbusRegisters(QTcpSocket *socket, quint16 startAddress, quint16 quantity) { QByteArray data; QDataStream stream(&data, QIODevice::WriteOnly); stream.setByteOrder(QDataStream::LittleEndian); // 构建请求帧 stream << static_cast<char>(0); // Transaction ID 高字节 stream << static_cast<char>(0); // Transaction ID 低字节 stream << static_cast<char>(0); // Protocol ID 高字节 stream << static_cast<char>(0); // Protocol ID 低字节 stream << static_cast<char>(0x00); // Length 高字节 stream << static_cast<char>(0x06); // Length 低字节 stream << static_cast<char>(0); // Unit Identifier stream << static_cast<char>(0x03); // 功能码 0x03 表示读保持寄存器 stream << static_cast<char>(startAddress >> 8); // 起始地址高字节 stream << static_cast<char>(startAddress & 0xFF); // 起始地址低字节 stream << static_cast<char>(quantity >> 8); // 数量高字节 stream << static_cast<char>(quantity & 0xFF); // 数量低字节 socket->write(data); } ``` 该函数实现了向服务器发送读取命令的功能,其中指定了要读取的寄存器范围和数量[^2]。 --- #### 使用指南 为了使上述代码正常工作,需遵循以下步骤: 1. 创建一个 `QTcpSocket` 实例并与目标设备建立连接。 2. 调用 `readModbusRegisters()` 或 `writeModbusRegisters()` 函数以生成相应的请求帧。 3. 处理返回的数据(如果需要),解析响应帧的内容。 注意:在实际应用中可能还需要考虑超时设置、错误检测等功能。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值