1. 程式人生 > >QT筆記(8)——Qt與51微控制器串列埠通訊

QT筆記(8)——Qt與51微控制器串列埠通訊

工業控制中微控制器與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,中文無法識別;所以要傳送中文就是亂碼;