Qt QSerialPort 類實現(xiàn)串口通信
2021/3/16??????點擊:
使用的時候在 pro 添加這句導(dǎo)入模塊 QT += serialport
1.連接串口 . 要先獲取到 可連接的所有的串口的名字
QSerialPortInfo::availablePorts() [static] QListQSerialPortInfo::availablePorts() Returns a list of available serial ports on the system. 返回系統(tǒng)上可用串行端口的列表 QStringList m_serialPortName; foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) { m_serialPortName << info.portName(); qDebug()<<"serialPortName:"<獲取到串口名字列表以后,我們需要選擇個需要連接的 (自行根據(jù)選擇)
2.根據(jù)串口名字 打開串口
#includeQSerialPort *m_serialPort = new QSerialPort();//實例化串口類個對象 if(m_serialPort->isOpen())//如果串口已經(jīng)打開了 先給他關(guān)閉了 { m_serialPort->clear(); m_serialPort->close(); } //設(shè)置串口名字 假設(shè)我們上面已經(jīng)成功獲取到了 并且使用個 m_serialPort->setPortName(m_serialPortName[0]); if(!m_serialPort->open(QIODevice::ReadWrite))//用ReadWrite 的模式嘗試打開串口 { qDebug()<setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);//設(shè)置波率和讀寫方向 m_serialPort->setDataBits(QSerialPort::Data8); //數(shù)據(jù)位為8位 m_serialPort->setFlowControl(QSerialPort::NoFlowControl);//無流控制 m_serialPort->setParity(QSerialPort::NoParity); //無校驗位 m_serialPort->setStopBits(QSerialPort::OneStop); //位停止位 //連接信號槽 當下位機發(fā)送數(shù)據(jù)QSerialPortInfo 會發(fā)送個 readyRead 信號,我們定義個槽void receiveInfo()解析數(shù)據(jù) connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo())); 3.收發(fā)發(fā)送交互數(shù)據(jù)
//接收單片機的數(shù)據(jù) void receiveInfo() { QByteArray info = m_serialPort->readAll(); QByteArray hexData = info.toHex(); //這里面的協(xié)議 你們自己定義就行 單片機發(fā)什么 代表什么 我們這里簡單模擬下 if(hexData == "0x10000") { //do something } else if(hexData == "0x100001") { //do something } } //向單片機發(fā)送數(shù)據(jù) //基本和單片機交互 數(shù)據(jù) 都是16進制的 我們這里自己寫個 Qstring 轉(zhuǎn)為 16進制的函數(shù) void convertStringToHex(const QString &str, QByteArray &byteData) { int hexdata,lowhexdata; int hexdatalen = 0; int len = str.length(); byteData.resize(len/2); char lstr,hstr; for(int i=0; i4.析構(gòu)的時候 關(guān)閉串口= len) break; lstr = str[i].toLatin1(); hexdata = convertCharToHex(hstr); lowhexdata = convertCharToHex(lstr); if((hexdata == 16) || (lowhexdata == 16)) break; else hexdata = hexdata*16+lowhexdata; i++; byteData[hexdatalen] = (char)hexdata; hexdatalen++; } byteData.resize(hexdatalen); } //另個 函數(shù) char 轉(zhuǎn)為 16進制 char SerialPort::convertCharToHex(char ch) { /* 0x30等于十進制的48,48也是0的ASCII值,, 1-9的ASCII值是49-57,,所以某個值-0x30,, 就是將字符0-9轉(zhuǎn)換為0-9 */ if((ch >= '0') && (ch <= '9')) return ch-0x30; else if((ch >= 'A') && (ch <= 'F')) return ch-'A'+10; else if((ch >= 'a') && (ch <= 'f')) return ch-'a'+10; else return (-1); } //寫兩個函數(shù) 向單片機發(fā)送數(shù)據(jù) void sendInfo(char* info,int len){ for(int i=0; i write(info,len);//這句是真正的給單片機發(fā)數(shù)據(jù) 用到的是QIODevice::write 具體可以看文檔 } void sendInfo(const QString &info){ QByteArray sendBuf; if (info.contains(" ")) { info.replace(QString(" "),QString(""));//我這里是把空格去掉,根據(jù)你們定的協(xié)議來 } qDebug()<<"Write to serial: "< write(sendBuf);這句是真正的給單片機發(fā)數(shù)據(jù) 用到的是QIODevice::write 具體可以看文檔 } if (m_serialPort->isOpen()) { m_serialPort->close(); } delete m_serialPort;#ifndef WIDGET_H #define WIDGET_H #include#include#include#include#includenamespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); void initUI(); QStringList getPortNameList();//獲取所有可用的串口列表 void openPort();//打開串口 public slots: void receiveInfo(); private: Ui::Widget *ui; QSerialPort* m_serialPort; //串口類 QStringList m_portNameList; QComboBox* m_PortNameComboBox; QPushButton* m_OpenPortButton; }; #endif // WIDGET_H#include "widget.h" #include "ui_widget.h" #include#includeWidget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); m_serialPort = new QSerialPort(); initUI(); m_portNameList = getPortNameList(); m_PortNameComboBox->addItems(m_portNameList); connect(m_OpenPortButton,&QPushButton::clicked,this,&Widget::openPort); } Widget::~Widget() { if (m_serialPort->isOpen()) { m_serialPort->close(); } delete m_serialPort; delete ui; } void Widget::initUI() { this->setWindowTitle("碼農(nóng)小明 test QSerialPort"); m_OpenPortButton = new QPushButton(); m_OpenPortButton->setText("打開串口"); m_PortNameComboBox = new QComboBox(); QHBoxLayout *m_layout = new QHBoxLayout(); m_layout->addWidget(m_PortNameComboBox); m_layout->addWidget(m_OpenPortButton); this->setLayout(m_layout); } QStringList Widget::getPortNameList() { QStringList m_serialPortName; foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) { m_serialPortName << info.portName(); qDebug()<<"serialPortName:"<isOpen())//如果串口已經(jīng)打開了 先給他關(guān)閉了 { m_serialPort->clear(); m_serialPort->close(); } m_serialPort->setPortName(m_PortNameComboBox->currentText());//當前選擇的串口名字 if(!m_serialPort->open(QIODevice::ReadWrite))//用ReadWrite 的模式嘗試打開串口 { qDebug()<<"打開失敗!"; return; } qDebug()<<"串口打開成功!"; m_serialPort->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);//設(shè)置波率和讀寫方向 m_serialPort->setDataBits(QSerialPort::Data8); //數(shù)據(jù)位為8位 m_serialPort->setFlowControl(QSerialPort::NoFlowControl);//無流控制 m_serialPort->setParity(QSerialPort::NoParity); //無校驗位 m_serialPort->setStopBits(QSerialPort::OneStop); //位停止位 connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo())); } //接收到單片機發(fā)送的數(shù)據(jù)進行解析 void Widget::receiveInfo() { QByteArray info = m_serialPort->readAll(); qDebug()<<"receive info:"<
- 上一篇:LINUX串口通信 2021/3/16
- 下一篇:C#延時導(dǎo)致UI界面不能刷新的問題 2021/3/6