原创 Qt编写串口通信程序全程图文讲解(四)终(原创)

2009-10-30 09:51 4676 5 5 分类: MCU/ 嵌入式

到我的空间查看完整文档:


http://hi.baidu.com/yafeilinux/blog/item/54f4f845f9ed7646510ffe8c.html


 


本文一开始先讲解对程序的改进,在文章最后将要讲解一些重要问题


第一,在窗口中加入一些组合框Combo Box,它们的名称及条目如下:


串口:portNameComboBox,条目为:COM1,COM2


波特率:baudRateComboBox,条目为:9600,115200


数据位:dataBitsComboBox,条目为:8,7


校验位:parityComboBox,条目为:无,奇,偶


停止位:stopBitsComboBox,条目为:1,2


(注:在窗口上的Combo Box上双击,在弹出的对话框上按“+”号,可添加条目。)


改好的窗口如下所示:



第二,更改“打开串口”按钮的单击事件槽函数。


void MainWindow::on_openMyComBtn_clicked()


{


QString portName = ui->portNameComboBox->currentText(); //获取串口名


myCom = new Win_QextSerialPort(portName,QextSerialBase::EventDriven);


//定义串口对象,并传递参数,在构造函数里对其进行初始化


myCom ->open(QIODevice::ReadWrite); //打开串口


j_0043.gif



if(ui->baudRateComboBox->currentText()==tr("9600")) //根据组合框内容对串口进行设置


myCom->setBaudRate(BAUD9600);


else if(ui->baudRateComboBox->currentText()==tr("115200"))


myCom->setBaudRate(BAUD115200);


j_0043.gif



if(ui->dataBitsComboBox->currentText()==tr("8"))


myCom->setDataBits(DATA_8);


else if(ui->dataBitsComboBox->currentText()==tr("7"))


myCom->setDataBits(DATA_7);


j_0043.gif



if(ui->parityComboBox->currentText()==tr("无"))


myCom->setParity(PAR_NONE);


else if(ui->parityComboBox->currentText()==tr("奇"))


myCom->setParity(PAR_ODD);


else if(ui->parityComboBox->currentText()==tr("偶"))


myCom->setParity(PAR_EVEN);


j_0043.gif



if(ui->stopBitsComboBox->currentText()==tr("1"))


myCom->setStopBits(STOP_1);


else if(ui->stopBitsComboBox->currentText()==tr("2"))


myCom->setStopBits(STOP_2);


j_0043.gif



myCom->setFlowControl(FLOW_OFF);


myCom->setTimeout(500);


j_0043.gif



connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));


//信号和槽函数关联,当串口缓冲区有数据时,进行读串口操作


j_0043.gif



ui->openMyComBtn->setEnabled(false); //打开串口后“打开串口”按钮不可用


ui->closeMyComBtn->setEnabled(true); //打开串口后“关闭串口”按钮可用


ui->sendMsgBtn->setEnabled(true); //打开串口后“发送数据”按钮可用


j_0043.gif


ui->baudRateComboBox->setEnabled(false); //设置各个组合框不可用


ui->dataBitsComboBox->setEnabled(false);


ui->parityComboBox->setEnabled(false);


ui->stopBitsComboBox->setEnabled(false);


ui->portNameComboBox->setEnabled(false);


}



这里我们先获取串口的名称,然后调用另一个构造函数对myCom进行定义,这个构造函数里没有串口的设置参数。然后打开串口。然后获取串口的设置数据,用setBaudRate();等一系列函数进行串口的设置,这些函数都在win_qextserialport.cpp文件中定义,如下图。


对于这几个函数应该很好理解,这里不再解释。在最后我们对添加的那几个组合框进行了不可用设置,使其在串口打开的情况下不能选择。


程序如下:




第三,更改“关闭串口”按钮单击事件的槽函数。


void MainWindow::on_closeMyComBtn_clicked()


{


myCom->close();


ui->openMyComBtn->setEnabled(true); //关闭串口后“打开串口”按钮可用


ui->closeMyComBtn->setEnabled(false); //关闭串口后“关闭串口”按钮不可用


ui->sendMsgBtn->setEnabled(false); //关闭串口后“发送数据”按钮不可用



ui->baudRateComboBox->setEnabled(true); //设置各个组合框可用


ui->dataBitsComboBox->setEnabled(true);


ui->parityComboBox->setEnabled(true);


ui->stopBitsComboBox->setEnabled(true);


ui->portNameComboBox->setEnabled(true);


}


这里只是加入了一些使组合框在“关闭串口”按钮按下后变为可用的语句。


程序如下:


第四,更改main.cpp文件。


#include <QtGui/QApplication>


#include <QTextCodec> //加入头文件


#include "mainwindow.h"



int main(int argc, char *argv[])


{


QApplication a(argc, argv);


QTextCodec::setCodecForTr(QTextCodec::codecForLocale());


//使程序可处理中文


MainWindow w;


w.show();


return a.exec();


}


因为上面的语句中用到了中文,为了能使程序识别中文,我们需要在主函数中加入这些语句。


程序如下:


第五,运行程序。


打开后程序界面如下。


正常发送1后如下。


设置为“奇校验”后,发送完1的效果如下图。


到这里,整个程序就完全写完了。





重要问题说明:


(下面所说的第一个程序是指第一篇文章中写的那个程序,第二个程序是指第三篇文章中那个程序,第三个程序是指本篇文章中所写的程序。)


问题一:第一个程序中


struct PortSettings myComSetting = {BAUD9600,DATA_8,PAR_NONE,STOP_1,FLOW_OFF,500};


myCom = new Win_QextSerialPort("com1",myComSetting,QextSerialBase::EventDriven);


这两句代码如果换为下面一行:


myCom = new Win_QextSerialPort("com1",QextSerialBase::EventDriven);


你再运行一下程序,是不是还能用?那我们的串口设置的结构体myComSetting没有用吗?你可以把上面的结构体里的波特率由9600改为115200,如果这个结构体有用,那么程序不可能再接收到数据,不过,你再运行一下程序,是这样吗?


      如此看来,我们对串口进行的设置果真没用,那默认的串口设置是什么呢?我们先看下一个问题。


问题二:我们同时打开第三个程序和第二个程序。(注意:两个程序的串口不能同时打开,所以打开一


个程序的串口时要将另一个程序的串口关闭。)


我们先在第三个程序上按默认设置打开串口,发送数据1。然后关闭串口,在第二个程序上打开串口,发送数据1。可以看到两个程序上接受到的信息都正确。如下图。



我们关闭第二个程序上的串口,再将第三个程序上设置为奇校验,然后打开串口,发送数据1,可以看到其收到的数据显示乱码。这时我们关闭第三个程序上的串口,打开第二个程序上的串口,发送数据1,你会惊奇地发现,它收到的信息也是乱码。如下图。



这到底是怎么回事呢?我们也可以去网上下载其他的串口助手进行实验,也可以改变波特率进行实验。由所有的结果得出的结论只能是:我们用那个结构体作为参数传过去后,并没有对串口进行设置,而程序运行使用的串口设置是系统以前保留的设置。那么,为什么会这样呢?我们看下面的一个问题。


问题三:我们将第三个程序中的那行代码


myCom ->open(QIODevice::ReadWrite);


放到设置串口的语句之后,


connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));


这句之前,然后再运行程序。你会发现程序的串口设置功能已经不起作用了。


       其实,上面的三个问题是一个问题,它的结论就是,写串口程序时,要先打开串口再对它进行设置,不然设置就不会起作用。所以,这里应该说明,第一个和第二个程序都是不太正确的,正确的方法应该是像第三个程序一样,先定义Win_QextSerialPort类对象,然后打开串口,再用那几个函数对串口进行设置。



到这里整篇文章就结束了。对于其中的一些问题也只是我个人的观点,由于水平有限,所以理解上可能会有偏差,或者错误,请广大网友批评指正。我写这篇文章的目的只是想让Qt初学者能更轻松的用Qt写出串口通信程序,及掌握Qt写程序时的一些技巧。如果你从我的文章中学到了一点知识,那么我的这篇文章就算是没有白写。


      最后,如果你喜欢我的写作风格,并且初学Qt,可以在我的空间查看Qt Creator系列教程,希望能对你的入门有所帮助。

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
5
关闭 站长推荐上一条 /3 下一条