QT筆記(8)——Qt與51微控制器串列埠通訊
阿新 • • 發佈:2019-01-02
工業控制中微控制器與pc機通訊,常常通過串列埠通訊來完成,本次基於RS232通訊來完成的,硬體是普中的STC51微控制器開發板;板子如下圖:
不需要液晶顯示器,自帶的例子這裡就不貼了,主要實驗是Qt進行串列埠連結,傳送資料,微控制器判斷髮送的內容並做出反饋;
微控制器程式是c語言寫的,用keil編譯,再下載到開發板上的,單片的程式如下:
#include<reg51.h> //--宣告全域性函式--// void UsartConfiguration(); unsigned char To[]=" THE END "; unsigned char ToNo[]=" Timeout "; unsigned char GET[5]; unsigned int i,j,n,flag; unsigned char receiveData; unsigned char AA[]="?!"; void Delay10ms(unsigned int c); //延時10ms void main() { UsartConfiguration(); flag=0;//標記為0;為1時候傳送" THE END ",當然不用flag直接在中斷函式裡寫也可以 while(1) { /////////////用flag時取消註釋////////////////////// // if(flag==1) // { // for(i=0;i<9;i++) // { // ES=0; // SBUF=To[i]; // while(!TI); //等待發送資料完成 // TI=0; // } // ES=1; // flag=0; // } } } /******************************************************************************* * 函 數 名 :UsartConfiguration() * 函式功能 :設定串列埠 * 輸 入 : 無 * 輸 出 : 無 *******************************************************************************/ void UsartConfiguration() { SCON=0X50; //設定為工作方式1 TMOD=0X20; //設定計數器工作方式2 PCON=0X80; //波特率加倍 TH1=0XF3; //計數器初始值設定,注意波特率是4800的 TL1=0XF3; ES=1; //開啟接收中斷 EA=1; //開啟總中斷 TR1=1; //開啟計數器 } /******************************************************************************* * 函 數 名 : Usart() interrupt 4 * 函式功能 : 串列埠函式 * 輸 入 : 無 * 輸 出 : 無 *******************************************************************************/ void Usart() interrupt 4 { unsigned char ff[]="/"; RI=0; receiveData=SBUF; //出去接收到的資料 SBUF=receiveData; //將接收到的資料放入到傳送暫存器 while(!TI); //等待發送資料完成 TI=0; //清除傳送完成標誌位 if(receiveData==ff[0]) //如果收到"/",flag設定為1,則傳送" THE END " ,並且解析指令並執行某種操作 { SBUF=AA[1]; flag=1; while(!TI); //等待發送資料完成 TI=0; //清除傳送完成標誌位 ////////////////用flag時候註釋下面/////////////////////// for(i=0;i<9;i++) { ES=0; //關閉接收中斷 SBUF=To[i]; //迴圈傳送字元 while(!TI); //等待發送資料完成 TI=0; } ES=1; //開啟接收中斷 /////////////////////////////////////// } }
基本功能如上面的註解,收到“/”時候,說明pc端傳送完成,則微控制器反饋給pc資訊;
qt的程式如下,不過先建一個視窗,然後在窗口裡新增控制元件,然後再把功能寫進控制元件,視窗程式如下:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QMessageBox> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //設定下拉選單,波特率 ui->comboBox_2->addItem("1200"); ui->comboBox_2->addItem("2400"); ui->comboBox_2->addItem("4800"); ui->comboBox_2->addItem("9600"); ui->comboBox_2->addItem("19200"); ui->comboBox_3->addItem("8"); ui->comboBox_4->addItem("0"); ui->comboBox_5->addItem("1"); ui->comboBox_5->addItem("2"); //設定波特率下拉選單預設顯示第0項 ui->comboBox_2->setCurrentIndex(2); //查詢可用的串列埠 foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) { QSerialPort serial; serial.setPort(info); if(serial.open(QIODevice::ReadWrite)) { ui->comboBox->addItem(serial.portName()); serial.close(); } } } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { if(ui->pushButton->text()==tr("開啟串列埠")) { serial=new QSerialPort; serial->setPortName(ui->comboBox->currentText());//設定串列埠名稱 serial->open(QIODevice::ReadWrite);//開啟串列埠 //設定波特率 // serial->setBaudRate(QSerialPort::Baud4800); switch (ui->comboBox_2->currentIndex()) { case 0: serial->setBaudRate(QSerialPort::Baud1200); break; case 1: serial->setBaudRate(QSerialPort::Baud2400); break; case 2: serial->setBaudRate(QSerialPort::Baud4800); break; case 3: serial->setBaudRate(QSerialPort::Baud9600); break; case 4: serial->setBaudRate(QSerialPort::Baud19200); break; default: break; } //設定校驗位 switch (ui->comboBox_4->currentIndex()) { case 0: serial->setParity(QSerialPort::NoParity); break; default: break; } //設定停止位 switch (ui->comboBox_5->currentIndex()) { case 1: serial->setStopBits(QSerialPort::OneStop);//停止位設定為1 break; case 2: serial->setStopBits(QSerialPort::TwoStop);// break; default: break; } //設定流控制 serial->setFlowControl(QSerialPort::NoFlowControl);//設定為無流控制 ui->comboBox->setEnabled(false); ui->comboBox_2->setEnabled(false); ui->comboBox_3->setEnabled(false); ui->comboBox_4->setEnabled(false); ui->comboBox_5->setEnabled(false); ui->pushButton->setText(tr("關閉串列埠")); } else { //關閉串列埠 serial->clear(); serial->close(); serial->deleteLater(); ui->comboBox->setEnabled(true); ui->comboBox_2->setEnabled(true); ui->comboBox_3->setEnabled(true); ui->comboBox_4->setEnabled(true); ui->comboBox_5->setEnabled(true); ui->pushButton->setText(tr("開啟串列埠")); } //連線訊號槽 QObject::connect(serial,&QSerialPort::readyRead,this,&MainWindow::ReadData); } //讀取接收到的資訊 void MainWindow::ReadData() { QByteArray buf; //二進位制 buf=serial->readAll(); if(!buf.isEmpty()) { QString str=buf; if(str.endsWith(" THE END ")) { ui->textEdit->append("I get"); } ui->textEdit->append(str); } buf.clear(); } //傳送按鈕槽函式 void MainWindow::on_pushButton_2_clicked() { if(ui->pushButton->text()=="關閉串列埠") { serial->write(ui->lineEdit->text().toLatin1().append("/"));//Latin1是ISO-8859-1的別名,微控制器僅能識別ASCII碼 // serial->write(ui->lineEdit->text().toLatin1());//Latin1是ISO-8859-1的別名,微控制器僅能識別ASCII碼 ////////////////////////test//////////////////////////////// // QString tmp=ui->lineEdit->text().toUtf8(); // qDebug() <<"utf8: "<<tmp ; // qDebug() <<"toLatin1(): "<<tmp.toLatin1() ; // qDebug() <<"toLocal8Bit(): "<<tmp.toLocal8Bit() ; // qDebug() << ui->lineEdit->text().toLatin1() ; //////////////////////////////////////////////////////// ui->lineEdit->clear(); } else { ui->pushButton_2->setEnabled(true); QMessageBox::about(NULL, "提示", "串列埠未開啟"); } }
效果如下:
因為串列埠只能手動ASCII,中文無法識別;所以要傳送中文就是亂碼;