串口调试工具开发
剛學習Qt,搜查資料,根據學到的知識,完成一個簡單的串口調試工具~剛入行,諒解
最終效果圖,圖上功能都可實現
UI界面繪制:
代碼如下:
串口調試工具開發1.創建工程QWidget,根據串口調試工具繪制Ui界面 給每個控件設置特定名,方便調用2.在.pro文件添加代碼 QT += core gui serialport3.在.h文件頭添加代碼 #include <QSerialPort> #include <QSerialPortInfo>private:Ui::Widget *ui;QSerialPort * serialport;//串口端口QTimer *timSend;//創建定時器對象QString mTime;//拼接日志樣式對象QDateTime mDateTime;//獲取當前時間QByteArray Sendtext;//發送緩存區QByteArray Receivetext;//接收緩存區long int SendByte=0;//發送字符數long int ReceByte=0;//接收字符數4.給串口號設置自動獲取電腦中的串口//遍歷可用串口設備//創建一個QStringList 對象來存儲端口名QStringList serialPort_Name;//foreach遍歷方法foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()){//端口名呈現格式serialPort_Name << info.portName();}//添加到控件串口顯示ui->PostName->addItems(serialPort_Name);*如果需要過濾無用串口,代碼如下//獲取串口列表int snum=0;//用下面的方法會過濾掉一些無用的串口QSerialPort temp_serial;foreach (const QSerialPortInfo &Info, QSerialPortInfo::availablePorts()) {temp_serial.setPort(Info);if(temp_serial.open(QIODevice::ReadWrite)){//如果串口是可以讀寫方式打開的ui->PostName->addItem(Info.portName());temp_serial.close();++snum;}}//默認選中第0項if(snum>2){ui->PostName->setCurrentIndex(1);}ui->PostName->currentText();*如果需要對下拉框進行自適應設置,代碼如下//下拉列表自適應/* 獲取最長字符串 */int maxlen = 0;for (int index = 0; index < ui->PostName->count(); index++){if (ui->PostName->itemText(index).length() > maxlen){maxlen = ui->PostName->itemText(index).length();}}/*獲取字體磅值轉換為像素值*/int fontsize = ui->PostName->font().pointSize();//獲取字體的磅值ui->PostName->setFixedWidth(fontsize * maxlen * 0.75);//設置像素值 ```接下來需聲明一個串口全局對象,在.h文件中 QSerialPort * serialport;//串口端口聲明后在.cpp文件中創建出來 serialport = new QSerialPort(this);//聲明后把對象創建出來給打開按鈕設置轉到槽.h文件自動生成 private slots:void on_Btn_Open_clicked();//打開鍵按下/*打開按鈕配置*/ /*串口參數配置*/ void Widget::on_Btn_Open_clicked() {if (ui->Btn_Open->text()=="打開") {//設置串口名serialport->setPortName(ui->PostName->currentText());//設置波特率switch (ui->BaudRate->currentIndex()){case 0:serialport->setBaudRate(QSerialPort::Baud19200,QSerialPort::AllDirections);break;case 1:serialport->setBaudRate(QSerialPort::Baud38400,QSerialPort::AllDirections);break;case 2:serialport->setBaudRate(QSerialPort::Baud57600,QSerialPort::AllDirections);break;default:serialport->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);break;} /* 檢驗位、數據位、停止位、流控制 與 波特率(switch)寫法一致 *///打開串口if(!serialport->open(QIODevice::ReadWrite)){QMessageBox::about(NULL,"提示","無法打開串口");return;}/*點擊后效果*///設置控件不可編輯ui->PostName->setEnabled(false);ui->BaudRate->setEnabled(false);ui->Parity->setEnabled(false);ui->DataBits->setEnabled(false);ui->StopBits->setEnabled(false);ui->FlowControl->setEnabled(false);//點擊打開按鈕后發送和循環發送可編輯ui->Btn_Send->setEnabled(true);ui->Cyclet_time->setEnabled(true);//點擊打開后顯示關閉ui->Btn_Open->setText("關閉");ui->Btn_Open->setStyleSheet("QPushButton{color:red;background:yellow}");/*點擊前效果*/與上方代碼相反,寫在else{}中 ```獲取時間戳/*獲取時間戳*/ 先在.h頭文件創建對象,如經常使用的對象,都在頭文件創建,減少損耗資源 QString mTime; QDateTime mDateTime; .cpp文件寫對應事件 if(ui->Re_Log->isChecked()){mDateTime = QDateTime::currentDateTime();//拼接日志樣式mTime = "[";mTime += mDateTime.toString("[yyyy-MM-dd hh:mm:ss.zzz]") ;mTime += "]:RECV ->" ;mTime += Receivetext;ui->Re_Edit->append(mTime);}添加數據換行問題,insertPlainText函數在原數據末尾直接添加,可以使用append函數替代換行添加if(ui->Re_Line->checkState()==Qt::Checked){ui->Re_Edit->append(Receivetext);}else{ui->Re_Edit->insertPlainText(Receivetext);} ```**串口接收代碼**/*串口接收*/ void Widget::on_SerialPort_readyRead(){int i,length;Receivetext = serialport->readAll();//接收字節并顯示ReceByte+=Receivetext.length();ui->Re_Byte->setText(QString::number(ReceByte));//十六進制if(ui->Re_Hex->checkState()==Qt::Checked){//字符串轉十六進制Receivetext = Receivetext.toHex().toUpper();length=Receivetext.length();for(i=0;i<=length/2;i++){//插入空格字符串Receivetext.insert((2+3*i),' ');}}//自動換行if(ui->Re_Line->checkState()==Qt::Checked){ui->Re_Edit->append(Receivetext);}//日志顯示樣式else if(ui->Re_Log->isChecked()){//獲取當前時間mDateTime = QDateTime::currentDateTime();//時間展示拼接樣式mTime = "[";mTime += mDateTime.toString("[yyyy-MM-dd hh:mm:ss.zzz]") ;mTime += "]:RECV ->" ;mTime += Receivetext;//append自動換行ui->Re_Edit->append(mTime);}else{//原數據末尾添加(文本接收)ui->Re_Edit->insertPlainText(Receivetext);} }**串口發送代碼**void Widget::on_Btn_Send_clicked() {int i,length;Sendtext = ui->Se_Edit->toPlainText().toUtf8();//發送設置HEXif(ui->Se_Hex->checkState()==Qt::Checked){//轉換成十六進制Sendtext = Sendtext.toHex().toUpper();length=Sendtext.length();for(i=0;i<=length/2;i++){//插入空格字符串Sendtext.insert((2+3*i),' ');}serialport->write(Sendtext);}else{serialport->write(Sendtext);}//發送字節顯示SendByte+=Sendtext.length();ui->Se_Byte->setText(QString::number(SendByte)); // ui->Se_Edit->moveCursor(QTextCursor::End);}定時器使用方法在.h頭文件中 //定義并初始化mTimerID int mTimerID= 0;/*定時器定時發送*///設置默認值1000ms mTimerID = startTimer(500);在.cpp文件中 void Widget::timerEvent(QTimerEvent *event) {qDebug()<<"我是定時器!"; } void Widget::closeEvent(QCloseEvent *event) {if(mTimerID){killTimer(mTimerID);mTimerID = 0;} }**串口循環發送代碼**在.h頭文件 QTimer *timSend;//創建定時器對象在.cpp文件 //定時發送=定時器timSend=new QTimer;timSend->setInterval(1000);//設置默認值1000ms//定時器信號連接發送信號connect(timSend,&QTimer::timeout,this,[=](){on_Btn_Send_clicked();});ui界面給循環發送checkbox轉到槽void on_Cyclet_time_stateChanged(int arg1);//循環發送void Widget::on_Cyclet_time_stateChanged(int arg1) {//獲取復選框狀態,沒有選就為0,選擇了就為2if(arg1==0){timSend->stop();}else {//對輸入的值大小的限制,小于10會彈出對話框提示if(ui->Se_Line_2->text().toInt()>=10){timSend->start(ui->Se_Line_2->text().toInt());//設置時長,重新計數}else {ui->Cyclet_time->setCheckState(Qt::Unchecked);QMessageBox::information(this,"錯誤提示","定時發送最小間隔為10ms!");}} }```清空按鈕在.h頭文件 void on_Btn_Reclean_clicked();//清空接收區域 void on_Btn_Seclean_clicked();//清空發送區域在.cpp文件 /*清空接收區域*/ void Widget::on_Btn_Reclean_clicked() {ui->Re_Edit->clear(); } /*清空發送區域*/ void Widget::on_Btn_Seclean_clicked() {ui->Se_Edit->clear(); }ASCII、HEX發送與接收在.h頭文件中 void on_Re_Hex_clicked();//點擊十六進制接收 void on_Se_Ascll_clicked();//點擊ASCII發送在.cpp文件中 /*十六進制接收*/ void Widget::on_Re_Hex_clicked() {ui->Re_Ascll->setCheckState(Qt::Unchecked);ui->Re_Hex->setCheckState(Qt::Checked); }/*ASCII發送*/ void Widget::on_Se_Ascll_clicked() {ui->Se_Ascll->setCheckState(Qt::Checked);ui->Se_Hex->setCheckState(Qt::Unchecked); }復位計數在.h頭文件中 void on_Btn_Reset_clicked();//復位計數在.cpp文件中 /*清除計數*/ void Widget::on_Btn_Reset_clicked() {SendByte = 0;ReceByte = 0;ui->Re_Byte->setText(QString::number(ReceByte));ui->Se_Byte->setText(QString::number(SendByte)); } ```總結
- 上一篇: 【致敬嵌入式攻城狮第2期活动预热征文】蜂
- 下一篇: 有些人每天都元气满满,就因为做到了这5点