QT C++ modbus 两个字 合成 32位整数

在项目开发中,从传感器读到2个字,高字在前,低字在后,本文用两种方法,将两个字顺序交换,转换为32位整数。

方法一:用联合体

方法二:位移动


#include <QApplication>

#include <QDebug>
 

union int32Split
{
    int int32Value; // 32位整数
    struct
    {
        unsigned short  word0;
        unsigned short  word1;
    } sInt32Values;      
    unsigned short Uint16Array[2];
};

int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   
    int32Split c,c2;
    c.Uint16Array[1]=65535;//
    c.Uint16Array[0]=65533;
    qDebug()<<c.int32Value;
    //-------------------
    c2.int32Value=-3;
     qDebug()<<c2.Uint16Array[1];
     qDebug()<<c2.Uint16Array[0];
     //------------------- 
    int c3,c4;
    c3=65535<<16;//左移16位
    c4=c3 | 65533;//位或运算
    qDebug()<<c4;
     //------------------
    unsigned short d1=c4>>16;//右移16位
    unsigned short d2=c4 & 0xffff;//位与运算
    qDebug()<<d1;
    qDebug()<<d2;
    return a.exec();
}

### 使用 Qt Modbus RTU 协议读取 32 数据 在使用 Qt 的 `QModBus` 类库实现 Modbus RTU 协议时,可以通过组合两个连续的寄存器来获取完整的 32 数据。以下是具体方法: #### 方法概述 Modbus RTU 中通常以 16 寄存器的形式存储数据。如果需要读取 32 数据,则需从设备中读取两个连续的 16 寄存器,并将其拼接成一个 32 整数或浮点数值。 --- #### 实现步骤说明 1. **设置连接方式** 需要先创建并配置 `QModBusRtuSerialMaster` 或者通过 TCP/IP 创建 `QModBusTcpClient` 来模拟 Modbus RTU 数据传输[^1]。对于 RTU over TCP 场景,推荐使用自定义 socket 方式处理底层通信逻辑。 2. **发送请求命令** 调用 `sendRawRequest()` 函数构建 Modbus 请求帧,指定目标地址、功能码以及起始寄存器置和数量。例如,为了读取单个 32 值(由两组 16 组成),应请求至少两个寄存器的内容。 3. **接收响应解析** 当收到服务器返回的数据包后,提取其中的有效负载部分。假设高于第一个寄存器而低则处于第二个寄存器之中,那么可以根据大小端模式决定如何排列这两个半部形成最终结果。 4. **转换为适当类型** 如果期望得到的是 IEEE754 标准下的 float 型变量而非单纯的 unsigned integer ,就需要借助 union 结构体或者 reinterpret_cast 技巧完成相应转变过程。 下面给出一段示范代码展示上述流程的具体实践情况: ```cpp #include <QtWidgets/QApplication> #include <QModbusDataUnit> #include <QModbusReply> // 定义辅助宏简化联合体声明 #define UNION_FLOAT_UINT32 \ union { uint32_t u; float f;} bool readFloatFromRegisters(QModbusClient *client, quint16 startAddress){ bool success = false; // 构建查询单元实例化对象 QModbusDataUnit request(QModbusDataUnit::HoldingRegisters, startAddress, 2); auto reply = client->sendReadRequest(request, 1); // 设备ID设为1 if (!reply) { qDebug() << "Read error:" << client->errorString(); return false; } QObject::connect(reply,&QModbusReply::finished,[=]()mutable{ if (reply->error() == QModbusDevice::NoError) { const QList<quint16> resultValues = reply->result().values(); UNION_FLOAT_UINT32 converter; // 将高低两分别赋给uint型成员再解释成float形式输出 converter.u |= static_cast<uint32_t>(resultValues.at(0))<<16 | resultValues.at(1); qDebug()<<"The Float Value is:"<<converter.f; success=true; } else{ qDebug()<< "Transaction failed:" << reply->errorString(); } reply->deleteLater(); }); return success ; } ``` 此段 C++ 程序片段展示了利用 Qt 提供的功能模块轻松达成跨平台应用开发目的的同时也兼顾到了效率考量因素。 --- ### 注意事项 - 不同厂商可能遵循不同的节顺序规则,请务必查阅所对接硬件手册确认实际部署环境中的具体情况。 - 上述例子仅演示了最基础的操作手法,在真实工程项目里还需要考虑超时重传机制以及其他异常状况处理策略等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值