Qt 串口類QSerialPort 使用筆記
雖然現在大多數的家用PC機上已經不提供RS232接口了。但是由於RS232串口操作簡單、通訊可靠,在工業領域中仍然有大量的應用。Qt以前的版本中,沒有提供官方的對RS232串口的支持,編寫串口程序很不方便。現在好了,在 Qt5.1 中提供了QtSerialPort模塊,方便編程人員快速的開發應用串口的應用程序。 本文就簡單的講講QtSerialPort模塊的使用。
當前的QtSerialPort模塊中提供了兩個C++類,分別是QSerialPort 和QSerialPortInfo。
QSerialPort 類提供了操作串口的各種接口。
QSerialPortInfo 是一個輔助類,可以提供計算機中可用串口的各種信息。
使用方法
先介紹 QSerialPortInfo 的使用。下面是一個簡單的例子,用來列舉出電腦上全部的串口設備。
首先,需要在pro文件中增加如下內容:
QT += serialport
Cpp 文件如下:
- #include <QCoreApplication>
- #include <QDebug>
- #include <QSerialPort>
- #include <QSerialPortInfo>
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
- foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
- {
- qDebug() << "Name : " << info.portName();
- qDebug() << "Description : " << info.description();
- qDebug() << "Manufacturer: " << info.manufacturer();
- qDebug() << "Serial Number: " << info.serialNumber();
- qDebug() << "System Location: " << info.systemLocation();
- }
- return a.exec();
- }
在我的電腦上顯示的結果如下:
- Name : "COM1"
- Description : "通信端口"
- Manufacturer: "(標准端口類型)"
- Serial Number: ""
- System Location: "\\.\COM1"
- Name : "COM5"
- Description : "USB Serial Port"
- Manufacturer: "FTDI"
- Serial Number: "A400G3UXA"
- System Location: "\\.\COM5"
通常,我們需要指定程序使用某一個確定的串口,這時不能只使用串口名稱,因為USB串口每次插在不同的USB口上時獲得的串口名稱都可能有變化。這時可以利用串口的序列號,這個號碼一般來說是唯一的,比如下面的代碼,首先遍歷所有的串口,找到我們需要的串口后就返回。
- #include <QCoreApplication>
- #include <QDebug>
- #include <QSerialPort>
- #include <QSerialPortInfo>
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
- QSerialPortInfo com_info;
- foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
- {
- if( info.serialNumber() == "A400G3UXA" )
- {
- com_info = info;
- break;
- }
- }
- qDebug() << "Name : " << com_info.portName();
- qDebug() << "Description : " << com_info.description();
- qDebug() << "serialNumber: " << com_info.serialNumber();
- return a.exec();
- }
QSerialPort 負責具體的串口操作。選定串口后,要先打開串口,才能設置波特率等參數。這些參數都設置好了就可以使用了。最基本的操作無非是read() 和 write()。需要注意的是這兩個操作都是非阻塞的。
另外有一個重要的signal 也需要用到,那就是 void QIODevice::readyRead()
每次串口收到數據后都會發出這個signal。我們的程序中需要定義一個slot,並將其與這個signal 相連接。這樣,每次新數據到來后,我們就可以在slot中讀取數據了。這時一定要將串口緩沖區中的數據全部讀出來,可以利用readAll() 來實現。
下面的代碼片段給出了設置串口的例子。
- m_reader.setPort(info);
- if(m_reader.open(QIODevice::ReadWrite))
- {
- qDebug() << "m_reader.open(QIODevice::ReadWrite)";
- m_reader.setBaudRate(QSerialPort::Baud9600);
- m_reader.setParity(QSerialPort::NoParity);
- m_reader.setDataBits(QSerialPort::Data8);
- m_reader.setStopBits(QSerialPort::OneStop);
- m_reader.setFlowControl(QSerialPort::NoFlowControl);
- m_reader.clearError();
- m_reader.clear();
- connect(&m_reader, SIGNAL(readyRead()), this, SLOT(readyReadSlot()));
- }
- void Dialog::readyReadSlot()
- {
- qDebug() << "x";
- QByteArray arr = m_reader.readAll();
- do_something(arr);
- }