QSerialPort的线程常用操作(包含心跳,读写延时方法等)

Posted jobgeo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QSerialPort的线程常用操作(包含心跳,读写延时方法等)相关的知识,希望对你有一定的参考价值。

 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的线程常用操作(包含心跳,读写延时方法等)的主要内容,如果未能解决你的问题,请参考以下文章

读写串口 类QSerialPort

从另一个线程向 QSerialPort 发送数据

多线程代码中 QSerialPort 的 Qt 错误:QCoreApplication::sendEvent:“无法将事件发送到不同线程拥有的对象

关闭正在运行的 QSerialPort 的电源是不是有问题?

QT5串口编程

Linux多线程之线程同步