Qt QSerialPort 類實(shí)現(xiàn)串口通信
2021/3/16??????點(diǎn)擊:
使用的時(shí)候在 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:"<
獲取到串口名字列表以后,我們需要選擇個(gè)需要連接的 (自行根據(jù)選擇)
2.根據(jù)串口名字 打開串口
#includeQSerialPort *m_serialPort = new QSerialPort();//實(shí)例化串口類個(gè)對(duì)象
if(m_serialPort->isOpen())//如果串口已經(jīng)打開了 先給他關(guān)閉了
{
m_serialPort->clear();
m_serialPort->close();
}
//設(shè)置串口名字 假設(shè)我們上面已經(jīng)成功獲取到了 并且使用個(gè)
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); //無校驗(yàn)位
m_serialPort->setStopBits(QSerialPort::OneStop); //位停止位
//連接信號(hào)槽 當(dāng)下位機(jī)發(fā)送數(shù)據(jù)QSerialPortInfo 會(huì)發(fā)送個(gè) readyRead 信號(hào),我們定義個(gè)槽void receiveInfo()解析數(shù)據(jù)
connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo()));
3.收發(fā)發(fā)送交互數(shù)據(jù)
//接收單片機(jī)的數(shù)據(jù)
void receiveInfo()
{
QByteArray info = m_serialPort->readAll();
QByteArray hexData = info.toHex();
//這里面的協(xié)議 你們自己定義就行 單片機(jī)發(fā)什么 代表什么 我們這里簡單模擬下
if(hexData == "0x10000")
{
//do something
}
else if(hexData == "0x100001")
{
//do something
}
}
//向單片機(jī)發(fā)送數(shù)據(jù)
//基本和單片機(jī)交互 數(shù)據(jù) 都是16進(jìn)制的 我們這里自己寫個(gè) Qstring 轉(zhuǎn)為 16進(jìn)制的函數(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; i= 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);
}
//另個(gè) 函數(shù) char 轉(zhuǎn)為 16進(jìn)制
char SerialPort::convertCharToHex(char ch)
{
/*
0x30等于十進(jìn)制的48,48也是0的ASCII值,,
1-9的ASCII值是49-57,,所以某個(gè)值-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);
}
//寫兩個(gè)函數(shù) 向單片機(jī)發(fā)送數(shù)據(jù)
void sendInfo(char* info,int len){
for(int i=0; iwrite(info,len);//這句是真正的給單片機(jī)發(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);這句是真正的給單片機(jī)發(fā)數(shù)據(jù) 用到的是QIODevice::write 具體可以看文檔
}
4.析構(gòu)的時(shí)候 關(guān)閉串口
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());//當(dāng)前選擇的串口名字
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); //無校驗(yàn)位
m_serialPort->setStopBits(QSerialPort::OneStop); //位停止位
connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo()));
}
//接收到單片機(jī)發(fā)送的數(shù)據(jù)進(jìn)行解析
void Widget::receiveInfo()
{
QByteArray info = m_serialPort->readAll();
qDebug()<<"receive info:"<
- 上一篇:LINUX串口通信 2021/3/16
- 下一篇:C#延時(shí)導(dǎo)致UI界面不能刷新的問題 2021/3/6
