1. 程式人生 > >QSerialPort的線程常用操作(包含心跳,讀寫延時方法等)

QSerialPort的線程常用操作(包含心跳,讀寫延時方法等)

exp tab else rect 信號 ttl tag fine blog

 1 #ifndef DATACOMMSERIAL_H
 2 #define DATACOMMSERIAL_H
 3 
 4 #include <QThread>
 5 #include <QSerialPort>
 6 
 7 struct tagSerialPortInfo
 8 {
 9     QString                     portName;
10     qint32                      baudRate;
11     QSerialPort::Directions     directions;
12     QSerialPort::DataBits       dataBits;
13 QSerialPort::FlowControl flowControl; 14 QSerialPort::Parity parity; 15 QSerialPort::StopBits stopBits; 16 17 tagSerialPortInfo() 18 { 19 directions = QSerialPort::AllDirections; 20 dataBits = QSerialPort::Data8; 21 flowControl = QSerialPort::NoFlowControl;
22 parity = QSerialPort::NoParity; 23 stopBits = QSerialPort::OneStop; 24 } 25 26 tagSerialPortInfo(QString name, qint32 rate): 27 tagSerialPortInfo() 28 { 29 portName = name; 30 baudRate = rate; 31 } 32 }; 33 34 enum SerialWorkMode 35 { 36 serial_send_time_to_live,
37 serial_send_request_only, 38 serial_send_request_recv_response, 39 serial_send_request_check_response, 40 serial_recv_response_only, 41 }; 42 43 class IResponseValidate 44 { 45 public: 46 virtual bool validate(const QByteArray& response) = 0; 47 }; 48 49 class DataCommSerial : public QThread 50 { 51 Q_OBJECT 52 public: 53 explicit DataCommSerial(QObject *parent = 0); 54 55 // 初始化串口信息 56 void init(const tagSerialPortInfo& info); 57 58 // 發送ttl信號 59 void send_time_to_live(int interval_time_ms, int timeout_ms); 60 61 // 僅發送數據 62 void sendRequest_only(const QList<QByteArray>& datas, int timeout_ms); 63 64 // 發送且接收應答 65 void sendRequest_and_recvResponse(const QList<QByteArray>& datas, int timeout_ms); 66 67 // 發送且檢查應答 68 void sendRequest_and_checkResponse(const QList<QByteArray>& datas, int timeout_ms, IResponseValidate* pValidate); 69 70 // 僅接受數據 71 void recvResponse_only(); 72 73 void run(); 74 75 signals: 76 // 應答數據信號 77 void sigRecvResponse(const QByteArray& data); 78 79 // 校驗應答數據信號 80 void sigCheckResponse(bool valid, const QByteArray& data); 81 82 // 異常提示信號 83 void sigCatchException(const QString& info); 84 85 public slots: 86 87 private: 88 QList<QByteArray> m_request_datas; 89 int m_ttl_interval_ms; 90 int m_wait_timeout; 91 tagSerialPortInfo m_serialport_info; 92 SerialWorkMode m_serial_work_mode; 93 IResponseValidate* m_pResponseValidate; 94 }; 95 96 #endif // DATACOMMSERIAL_H

  1 #include "datacommserial.h"
  2 #include <QDebug>
  3 #include <QDateTime>
  4 
  5 DataCommSerial::DataCommSerial(QObject *parent) : QThread(parent)
  6 {
  7     m_pResponseValidate = 0;
  8     m_ttl_interval_ms = 1000;
  9     m_wait_timeout = 5000;
 10 }
 11 
 12 void DataCommSerial::init(const tagSerialPortInfo& info)
 13 {
 14     m_serialport_info = info;
 15 }
 16 
 17 void DataCommSerial::send_time_to_live(int interval_time_ms, int timeout_ms)
 18 {
 19     m_serial_work_mode = serial_send_time_to_live;
 20     m_ttl_interval_ms = interval_time_ms;
 21     m_wait_timeout = timeout_ms;
 22 }
 23 
 24 void DataCommSerial::sendRequest_only(const QList<QByteArray>& datas, int timeout_ms)
 25 {
 26     m_serial_work_mode = serial_send_request_only;
 27     m_request_datas = datas;
 28     m_wait_timeout = timeout_ms;
 29 }
 30 
 31 void DataCommSerial::sendRequest_and_recvResponse(const QList<QByteArray>& datas, int timeout_ms)
 32 {
 33     m_serial_work_mode = serial_send_request_recv_response;
 34     m_request_datas = datas;
 35     m_wait_timeout = timeout_ms;
 36 }
 37 
 38 void DataCommSerial::sendRequest_and_checkResponse(const QList<QByteArray>& datas, int timeout_ms, IResponseValidate* pValidate)
 39 {
 40     m_serial_work_mode = serial_send_request_check_response;
 41     m_request_datas = datas;
 42     m_wait_timeout = timeout_ms;
 43     m_pResponseValidate = pValidate;
 44 }
 45 
 46 void DataCommSerial::recvResponse_only()
 47 {
 48     m_serial_work_mode = serial_recv_response_only;
 49 }
 50 
 51 void DataCommSerial::run()
 52 {
 53     QSerialPort serialport;
 54     tagSerialPortInfo& cfg = m_serialport_info;
 55     serialport.setPortName(cfg.portName);
 56     if(!serialport.setBaudRate(cfg.baudRate, cfg.directions)) return;
 57     if(!serialport.setDataBits(cfg.dataBits)) return;
 58     if(!serialport.setFlowControl(cfg.flowControl)) return;
 59     if(!serialport.setParity(cfg.parity)) return;
 60     if(!serialport.setStopBits(cfg.stopBits)) return;
 61     if(!serialport.open(QIODevice::ReadWrite))
 62     {
 63         emit sigCatchException("serialport open failture" + serialport.errorString());
 64         qDebug() << "serialport open failture" << serialport.errorString();
 65         return;
 66     }
 67 
 68     if(serial_send_time_to_live==m_serial_work_mode)
 69     {
 70         while (true)
 71         {
 72             QString ttl = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz");
 73             serialport.write(ttl.toLocal8Bit());
 74             if(!serialport.waitForBytesWritten(m_wait_timeout))
 75             {
 76                 emit sigCatchException("waitForBytesWritten timeout");
 77                 qDebug() << "waitForBytesWritten timeout" << ttl;
 78             }
 79 
 80             msleep(m_ttl_interval_ms);
 81         }
 82     }
 83     else if(serial_send_request_only==m_serial_work_mode)
 84     {
 85         foreach(QByteArray request_data, m_request_datas)
 86         {
 87             serialport.write(request_data);
 88             if(!serialport.waitForBytesWritten(m_wait_timeout))
 89             {
 90                 emit sigCatchException("waitForBytesWritten timeout");
 91                 qDebug() << "waitForBytesWritten timeout";
 92                 return;
 93             }
 94         }
 95     }
 96     else if(serial_send_request_recv_response==m_serial_work_mode)
 97     {
 98         foreach(QByteArray request_data, m_request_datas)
 99         {
100             serialport.write(request_data);
101             if(serialport.waitForBytesWritten(m_wait_timeout))
102             {
103                 if(serialport.waitForReadyRead(m_wait_timeout))
104                 {
105                     QByteArray response_data = serialport.readAll();
106                     while(serialport.waitForReadyRead(50))
107                     {
108                         response_data += serialport.readAll();
109                     }
110                     qDebug() << response_data;
111                     emit sigRecvResponse(response_data);
112                 }
113                 else
114                 {
115                     emit sigCatchException("waitForReadyRead timeout");
116                     qDebug() << "waitForReadyRead timeout";
117                     return;
118                 }
119             }
120             else
121             {
122                 emit sigCatchException("waitForBytesWritten timeout");
123                 qDebug() << "waitForBytesWritten timeout";
124                 return;
125             }
126         }
127     }
128     else if(serial_send_request_check_response==m_serial_work_mode)
129     {
130         foreach(QByteArray request_data, m_request_datas)
131         {
132             serialport.write(request_data);
133             if(serialport.waitForBytesWritten(m_wait_timeout))
134             {
135                 if(serialport.waitForReadyRead(m_wait_timeout))
136                 {
137                     QByteArray response_data = serialport.readAll();
138                     while(serialport.waitForReadyRead(50))
139                     {
140                         response_data += serialport.readAll();
141                     }
142 
143                     if(m_pResponseValidate)
144                     {
145                         bool bValid = m_pResponseValidate->validate(response_data);
146                         qDebug() << bValid << response_data.toHex();
147                         emit sigCheckResponse(bValid, response_data);
148                     }
149                     else
150                     {
151                         emit sigCatchException("m_pResponseValidate invalid");
152                         qDebug() << "m_pResponseValidate invalid" << m_pResponseValidate;
153                         return;
154                     }
155                 }
156                 else
157                 {
158                     emit sigCatchException("waitForReadyRead timeout");
159                     qDebug() << "waitForReadyRead timeout";
160                     return;
161                 }
162             }
163             else
164             {
165                 emit sigCatchException("waitForBytesWritten timeout");
166                 qDebug() << "waitForBytesWritten timeout";
167                 return;
168             }
169         }
170     }
171     else if(serial_recv_response_only==m_serial_work_mode)
172     {
173         while (true)
174         {
175             QByteArray response_data = serialport.readAll();
176 
177             while (serialport.waitForReadyRead(500))
178             {
179                 response_data += serialport.readAll();
180             }
181 
182             if(!response_data.isEmpty())
183             {
184                 emit sigRecvResponse(response_data);
185                 qDebug() << response_data;
186             }
187         }
188     }
189 }

測試方法

#ifndef DATACOMMMANAGER_H
#define DATACOMMMANAGER_H

#include <QObject>

#include "datacommserial.h"

class IResponseValidate_F1 : public IResponseValidate
{
public:
    virtual bool validate(const QByteArray& response)
    {
        bool bValid = false;
        return bValid;
    }
};

class DataCommTest : public QObject
{
    Q_OBJECT
public:
    explicit DataCommTest(QObject *parent = 0);

    void test();

    void test_serial0();

    void test_serial1();

    void test_serial2();

    void test_serial3();

    void test_serial4();

signals:

public slots:
};

#endif // DATACOMMMANAGER_H

#include "datacommmanager.h"
#include <QDateTime>

DataCommTest::DataCommTest(QObject *parent) : QObject(parent)
{

}

void DataCommTest::test_serial0()
{
    DataCommSerial* pComm = new DataCommSerial();
    if(pComm)
    {
        pComm->init(tagSerialPortInfo("com1", 9600));

        pComm->send_time_to_live(500, 3000);

        pComm->start();
    }
}

void DataCommTest::test_serial1()
{
    DataCommSerial* pComm = new DataCommSerial();
    if(pComm)
    {
        pComm->init(tagSerialPortInfo("com1", 9600));
        QList<QByteArray> datas;
        for(int i=0;i<10;i++)
        {
            datas << QDateTime::currentDateTime().toString("yyyyMMddHHmmss--").toLocal8Bit();
        }
        pComm->sendRequest_only(datas, 3000);
        pComm->start();
    }
}

void DataCommTest::test_serial2()
{
    DataCommSerial* pComm = new DataCommSerial();
    if(pComm)
    {
        pComm->init(tagSerialPortInfo("com1", 9600));
        QList<QByteArray> datas;
        for(int i=0;i<10;i++)
        {
            datas << QDateTime::currentDateTime().toString("yyyyMMddHHmmss--").toLocal8Bit();
        }
        pComm->sendRequest_and_recvResponse(datas, 3000);
        pComm->start();
    }
}

void DataCommTest::test_serial3()
{
    DataCommSerial* pComm = new DataCommSerial();
    if(pComm)
    {
        pComm->init(tagSerialPortInfo("com1", 9600));
        QList<QByteArray> datas;
        for(int i=0;i<10;i++)
        {
            datas << QDateTime::currentDateTime().toString("yyyyMMddHHmmss--").toLocal8Bit();
        }

        IResponseValidate* pF1 = new IResponseValidate_F1();
        pComm->sendRequest_and_checkResponse(datas, 3000, pF1);
        pComm->start();
    }
}

void DataCommTest::test_serial4()
{
    DataCommSerial* pComm = new DataCommSerial();
    if(pComm)
    {
        pComm->init(tagSerialPortInfo("com1", 9600));

        pComm->recvResponse_only();
        pComm->start();
    }
}

void DataCommTest::test()
{
    test_serial0();
//    test_serial1();
//    test_serial2();
//    test_serial3();
//    test_serial4();
}

QSerialPort的線程常用操作(包含心跳,讀寫延時方法等)