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();
}