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 的 Qt 错误:QCoreApplication::sendEvent:“无法将事件发送到不同线程拥有的对象