<strike id="kiyse"></strike>
  • <tr id="kiyse"></tr>
  • <strike id="kiyse"></strike><samp id="kiyse"><tbody id="kiyse"></tbody></samp>
    <strike id="kiyse"><s id="kiyse"></s></strike>
    <tr id="kiyse"></tr>
    <noframes id="kiyse"><code id="kiyse"></code></noframes>
    <th id="kiyse"></th>
    <samp id="kiyse"></samp>
  • <th id="kiyse"><s id="kiyse"></s></th>
  • ESM6802支持Qt MODBUS程序開發

     2017-5-27     作者:廖光澤         
    文章標簽:C/C++QtESM6802

      ESM6802使用iMX6DL作為CPU,支持硬件圖形加速,使得用戶可以開發具有較好圖形界面的工業控制程序。Qt是嵌入式開發中常用的圖形庫,MODBUS作為工控中常用的通信協議,已經作為Qt的模塊引入了Qt中。我們在ESM6802上移植了最新的Qt 5.8.0版本,包括MODBUS模塊,用戶在使用中可以方便的調用Qt提供的API進行MODBUS協議相關的程序編寫。Qt對于MODBUS協議的封裝使得用戶能夠更加便捷快速的進行MODBUS應用程序開發,我們將在下面根據Qt源碼中的modbusmaster例程簡單介紹Qt的MODBUS相關函數接口。文中使用的程序可以在http://doc.qt.io/qt-5/qtserialbus-modbus-master-example.html獲取或向我們的工程師索取。


      在使用Qt提供的MODBUS相關API時需要使用Qt提供的MODBUS數據類:QModbusDataUnit,類中有公共數據RegisterType表示此數據代表的MODBUS數據類型:

      enum    RegisterType { Invalid, DiscreteInputs, Coils, InputRegisters, HoldingRegisters }


      可以使用構造函數進行初始化:

      QModbusDataUnit(RegisterType type, int address, quint16 size)


      對于MODBUS client相關的函數,Qt將其封裝在類QModbusClient中,部分函數如下:

      int  numberOfRetries() const

      QModbusReply *      sendRawRequest(const QModbusRequest &request, int serverAddress)

      QModbusReply *      sendReadRequest(const QModbusDataUnit &read, int serverAddress)

      QModbusReply *      sendReadWriteRequest(const QModbusDataUnit &read, const QModbusDataUnit &write, int serverAddress)

      QModbusReply *      sendWriteRequest(const QModbusDataUnit &write, int serverAddress)

      void       setNumberOfRetries(int number)

      void       setTimeout(int newTimeout)

      int  timeout() const


      其中numberOfRetries以及setTimeout是用于設置重試次數和超時時間的。send*Request系列函數是用于發送MODBUS數據包的函數,其中數據相關的都用之前介紹的QModbusDataUnit類對象作為函數參數。


      截取部分Qt例程modbusmaster發送讀請求的代碼如下:


      首先設置連接類型(RTU/TCP)、重試次數、超時時間等,然后建立連接:

      if (static_cast<ModbusConnection> (ui->connectType->currentIndex()) == Serial) {

             modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,

          ui->portEdit->text());

             modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,

          m_settingsDialog->settings().parity);

             modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,

          m_settingsDialog->settings().baud);

             modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,

          m_settingsDialog->settings().dataBits);

             modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,

          m_settingsDialog->settings().stopBits);

      } else {

        const QUrl url = QUrl::fromUserInput(ui->portEdit->text());

        modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, url.port());

        modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, url.host());

      }

      modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);

      modbusDevice->setNumberOfRetries(m_settingsDialog->settings().numberOfRetries);

      if (!modbusDevice->connectDevice()) {

        statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000);

      }


      設置讀取數據類型、地址等參數:

      QModbusDataUnit MainWindow::readRequest() const

      {

        const auto table =

        static_cast<QModbusDataUnit::RegisterType> (ui->writeTable->currentData().toInt());

        int startAddress = ui->readAddress->value();

        Q_ASSERT(startAddress >= 0 && startAddress < 65535);

        // do not go beyond 10 entries

        int numberOfEntries = qMin(ui->readSize->currentText().toInt(), 65535 - startAddress);

        return QModbusDataUnit(table, startAddress, numberOfEntries);

      }


      發送讀數據請求:

      void MainWindow::on_readButton_clicked()

      {

      if (!modbusDevice)

        return;

      ui->readValue->clear();

      statusBar()->clearMessage();

      if (auto *reply = modbusDevice->sendReadRequest(readRequest(), ui->serverEdit->value())) {

        if (!reply->isFinished())

          connect(reply, &QModbusReply::finished, this, &MainWindow::readReady);

        else

          delete reply; // broadcast replies return immediately

      } else {

        statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000);

        }

      }


      可以看到使用Qt提供的API進行MODBUS通訊編程很便捷,只需要首先設置數據QModbusDataUnit,然后調用相應的Request函數發送請求即可。

      modbusmaster程序運行效果如下圖:

    ESM6802支持Qt-MODBUS程序開發.gif


      我們使用ESM6802連接ADAM模塊進行測試連接圖如下:

    ESM6802支持Qt-MODBUS程序開發.gif


      ADAM-4117進行電流采集時電流輸入量程為4~20mA,對應的采樣值為0x0000~0xffff。有關AMAM-4117的介紹可以參考我們官網上的文章:《4~20mA模擬電流采集應用方案》。當輸入12.0mA(半量程)時讀到采樣值為0x8007,可見modbusmaster與AMAM模塊正確進行了數據通信。

      更多Qt MODBUS相關內容請參考Qt官方資料:http://doc.qt.io/qt-5/qtmodbus-backends.html

    文章標簽:C/C++QtESM6802
    久久这里只有精品国产免费10| 日本精品高清一区二区2021 | 国产成人一区二区动漫精品| 亚洲国产精品特色大片观看完整版| 无码人妻精品一二三区免费| 久久久久成人精品免费播放动漫 | 亚洲国产高清在线精品一区| 一本色道久久综合亚洲精品高清| 成人国产精品一区二区网站公司| 久久精品国产99精品国产亚洲性色| 国产剧情精品在线| 亚洲精品国产福利片| 国产精品亚洲A∨天堂不卡| 国产乱码一二三区精品| 91无码人妻精品一区二区三区L | 思思99re66在线精品免费观看 | 精品国产一区二区三区在线观看 | 91精品一区二区| 亚洲精品无码高潮喷水在线| 九九这里只有精品视频| 精品国偷自产在线视频99| 亚洲国产精品网站久久| 亚洲视频精品在线| 国产精品无码专区| 精品精品国产高清a毛片| 国产午夜久久精品| 国产伦精品一区二区三区不卡| 91精品手机国产免费| 亚洲国产精品VA在线看黑人| 国产一区二区精品久久岳| 无码AⅤ精品一区二区三区| 精品72久久久久久久中文字幕 | 久久久精品国产免大香伊| 国产福利精品一区二区| 亚洲无线观看国产精品| 国产精品午夜久久| 国产91精品一区二区麻豆亚洲| 国产在线精品观看一区| 国产精品成人一区二区三区| 图片区精品综合自拍| 九九99久久精品国产|