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