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

2019-04-15 18:42发布

工业控制中单片机与pc机通讯,常常通过串口通讯来完成,本次基于RS232通讯来完成的,硬件是普中的STC51单片机开发板;板子如下图: 不需要液晶显示器,自带的例子这里就不贴了,主要实验是Qt进行串口链接,发送数据,单片机判断发送的内容并做出反馈; 单片机程序是c语言写的,用keil编译,再下载到开发板上的,单片的程序如下: #include //--声明全局函数--// 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 #include 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: "<lineEdit->text().toLatin1() ; //////////////////////////////////////////////////////// ui->lineEdit->clear(); } else { ui->pushButton_2->setEnabled(true); QMessageBox::about(NULL, "提示", "串口未打开"); } } 效果如下: 因为串口只能手动ASCII,中文无法识别;所以要发送中文就是乱码;