QT - 基于Modbus协议的光谱采集软件

建立基于Modbus协议的光谱采集软件,其中设计到的部分问题在此处进行说明,方便后续使用。

Step 1. 波特率配置

由于在使用中涉及576000,921600高波特率,在QT源码中不涉及,故需改源码。

修改文件:

C:\Qt\Qt5.14.2\5.14.2\msvc2017_64\include\QtSerialPort\qserialport.h (不同版本,编译环境会存在差异,请自行配置)

修改内容:

enum BaudRate {

        Baud1200 = 1200,

        Baud2400 = 2400,

        Baud4800 = 4800,

        Baud9600 = 9600,

        Baud19200 = 19200,

        Baud38400 = 38400,

        Baud57600 = 57600,

        Baud115200 = 115200,

        Baud576000 = 576000,

        Baud921600 = 921600,

        UnknownBaud = -1

};

Q_ENUM(BaudRate)

Step 2. 查找可用端口

foreach(const QSerialPortInfo & info, QSerialPortInfo::availablePorts())

{

    QSerialPort port;

    port.setPort(info);

    if (port.open(QIODevice::ReadWrite))

    {

        ui.comboBox_serialName->addItem(port.portName());//用于记录端口信息

        port.close();
    }

}

Step 3. 创建连接

QModbusClient* modbusDevice =  new QModbusRtuSerialMaster;

dataBit = QSerialPort::Data8;

stopBit = QSerialPort::OneStop;

parity = QSerialPort::NoParity;

modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, ui.comboBox_serialName->currentText());     modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, parity);

modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, baud);     modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, dataBit);

modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, stopBit);

modbusDevice->setTimeout(500);

modbusDevice->setNumberOfRetries(3);

modbusDevice->connectDevice();

Step 4. 读写操作

功能码

含义

01

读线圈

05

写单个线圈

0F

写多个线圈

02

读离散量输入

04

读输入寄存器

03

读保持寄存器

06

写单个保持寄存器

10

写多个保持寄存器

m_Device->sendReadRequest(QModbusDataUnit(QModbusDataUnit::HoldingRegisters, startAddress, readNum), slaveId);

其中,相关函数如下:

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


class QModbusDataUnit
{
public:
    enum RegisterType {
        Invalid,
        DiscreteInputs,
        Coils,
        InputRegisters,
        HoldingRegisters
    };

    QModbusDataUnit() = default;

    explicit QModbusDataUnit(RegisterType type)
        : QModbusDataUnit(type, 0, 0)
    {}

    QModbusDataUnit(RegisterType type, int newStartAddress, quint16 newValueCount)
        : QModbusDataUnit(type, newStartAddress, QVector(newValueCount))
    {}

    QModbusDataUnit(RegisterType type, int newStartAddress, const QVector &newValues)
        : m_type(type)
        , m_startAddress(newStartAddress)
        , m_values(newValues)
        , m_valueCount(newValues.size())
    {}

    RegisterType registerType() const { return m_type; }
    void setRegisterType(RegisterType type) { m_type = type; }

    inline int startAddress() const { return m_startAddress; }
    inline void setStartAddress(int newAddress) { m_startAddress = newAddress; }

    inline QVector values() const { return m_values; }
    inline void setValues(const QVector &newValues)
    {
        m_values = newValues;
        m_valueCount = newValues.size();
    }

    inline uint valueCount() const { return m_valueCount; }
    inline void setValueCount(uint newCount) { m_valueCount = newCount; }

    inline void setValue(int index, quint16 newValue)
    {
        if (m_values.isEmpty() || index >= m_values.size())
            return;
        m_values[index] = newValue;
    }
    inline quint16 value(int index) const { return m_values.value(index); }

    bool isValid() const { return m_type != Invalid && m_startAddress != -1; }

private:
    RegisterType m_type = Invalid;
    int m_startAddress = -1;
    QVector m_values;
    uint m_valueCount = 0;
};

参考案例:

https://download.csdn.net/download/zydkl_906/87362503

你可能感兴趣的:(编程整理,qt,开发语言)