QT笔记(8)——Qt与51单片机串口通讯

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/abcvincent/article/details/83420154

工业控制中单片机与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,中文无法识别;所以要发送中文就是乱码;

猜你喜欢

转载自blog.csdn.net/abcvincent/article/details/83420154