QT串口通信实例

来源:互联网 发布:网络课幸福心理学答案 编辑:程序博客网 时间:2024/05/21 17:13

工作中需要用到QT串口通信,所使用的环境是QT4.7,由于QT中并没有特定的串口控制类,所以我使用的是使用的是第三方写的 qextserialport 类。我们可以去http://sourceforge.net/projects/qextserialport/files/进行下载

我们在 windows 下只需要使用其中的 6 个文件:
qextserialbase.cpp 和 qextserialbase.h, qextserialport.cpp 和 qextserialport.h, win_qextserialport.cpp 和 win_qextserialport.h
如果在 Linux 下只需将 win_qextserialport.cpp 和 win_qextserialport.h 换为 posix_qextserialport.cpp 和 posix_qextserialport.h 即可。

先附代码:

    Win_QextSerialPort *myCom;    myCom = new Win_QextSerialPort(portName, QextSerialBase::EventDriven);    //定义串口对象, 并传递参数, 在构造函数里对其进行初始化    myCom->open(QIODevice::ReadWrite);    //以读写方式打开串口    if(ui->baudRateComboBox->currentText()==tr("9600")) //根据组合框的内容对串口进行设置    myCom->setBaudRate(BAUD9600);    else if(ui->baudRateComboBox->currentText()==tr("115200"))    myCom->setBaudRate(BAUD115200);    //设置波特率    if(ui->dataBitsComboBox->currentText()==tr("8"))    myCom->setDataBits(DATA_8);    else if(ui->dataBitsComboBox->currentText()==tr("7"))    myCom->setDataBits(DATA_7);    //设置数据位    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);    //设置奇偶校验    if(ui->stopBitsComboBox->currentText()==tr("1"))    myCom->setStopBits(STOP_1);    else if(ui->stopBitsComboBox->currentText()==tr("2"))    myCom->setStopBits(STOP_2);    //设置停止位    myCom->setFlowControl(FLOW_OFF); //设置数据流控制,我们使用无数据流控制的默认设置    myCom->setTimeout(500); //设置延时    connect(myCom, SIGNAL(readyRead()), this, SLOT(readMycom()));    //信号和槽函数相连, 当串口缓冲区有数据时, 进行读串口操作
阅读上面几个文件在 win_qextserialport.cpp 文件中,我们看它的最后一个构造函数,会发现,串口可以在这里进行初始化。

Win_QextSerialPort::Win_QextSerialPort(const QString & name, const PortSettings& settings, QextSerialBase::QueryMode mode) {
Win_Handle=INVALID_HANDLE_VALUE;
setPortName(name);
setBaudRate(settings.BaudRate);
setDataBits(settings.DataBits);
setStopBits(settings.StopBits);
setParity(settings.Parity);
setFlowControl(settings.FlowControl);
setTimeout(settings.Timeout_Millisec);
setQueryMode(mode);
init();
}
它共有三个参数,其中第一个参数 const QString & name,应该是串口的名字,是 QString 类型,我们可以用串口 1 即“com1”,不用过多说明。

对于第二个参数我们可以在 qextserialbase.h 文件中找到有一个 struct PortSettings结构体

struct PortSettings
{
BaudRateType BaudRate;
DataBitsType DataBits;
ParityType Parity;
StopBitsType StopBits;
FlowType FlowControl;
long Timeout_Millisec;
};
可以看到在这个结构体里定义了串口初始化的各个参数,而对于 BaudRateType 等类型的定义,我们在这个结构体的上面可以看到,它们是多个枚举变量。所以这个结构体是实现串口参数设置的。下面我们就可以定义串口参数。

BaudRateType BaudRate;
波特率设置,我们设置为 9600,即程序中用 BAUD9600;
DataBitsType DataBits;
数据位设置,我们设置为 8 位数据位,即 DATA_8;
ParityType Parity;
奇偶校验设置,我们设置为无校验,即 PAR_NONE;
StopBitsType StopBits;
停止位设置,我们设置为 1 位停止位,即 STOP_1;
FlowType FlowControl;
数据流控制设置,我们设置为无数据流控制,即 FLOW_OFF;
long Timeout_Millisec;
延时设置,我们设置为延时 500ms,即 500;
//定义一个结构体
struct PortSettings myComSetting = {BAUD9600,DATA_8,PAR_NONE,STOP_1,FLOW_OFF,500};
我们定义了一个结构体变量 myComSetting,并对其进行了初始化。

对于第三个参数在 qextserialbase.h 中,可以看到查询模式也是枚举变量,有两个选项,我们选择第二个 EventDriven,事件驱动。
所以我们可以这样实现串口初始化:
myCom = new Win_QextSerialPort("com1",myComSetting,QextSerialBase::EventDriven);

其实这样写是不大正确的,写串口程序时,要先打开串口再对它进行设置,不然设置就不会起作用。正确的方法应该是先定义 Win_QextSerialPort 类对象,然后打开串口,再用那几个设置函数对串口进行设置,如下:

调用另一个构造函数:

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

然后获取串口的设置数据,用 setBaudRate();等一系列函数进行串口的设置,这些函数都在 win_qextserialport.cpp 文件中定义

打开串口函数和读取串口函数:

查看 win_qextserialport.h 文件,我们会发现 Win_QextSerialPort 类继承自 QextSerialBase 类。查看 qextserialbase.h 文件,我们会发现 QextSerialBase 类继承自 QIODevice 类。查看 QIODevice 类,信号函数中有 void readyRead ();它可以查看串口是否有新的数据传来。

所以,我们可以用这个类里的这些函数操作串口。
如程序中的语句:
myCom ->open(QIODevice::ReadWrite);
//我们调用了其中的 open 函数,用 ReadWrite 可读写的方式进行打开串口,这个 open 函数
//在 win_qextserialport.cpp 中被重定义了
connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));
//我们关联信号 readyRead(),和自己写的槽函数 readMyCom(),当串口有数据传来时进行读串口操作