赞
踩
很多小伙伴们对串口编程刚上手时,不知道如何下手,本例子带大家看看一个简单的串口通讯的例子,例子是网上的demo,这里简单的介绍下:
这是我们常见的界面窗口,下面我们来解析下代码部分:
串口步骤:
* 1.设置串口参数
* 2.打开串口
* 3.读/写串口
* 4.关闭串口
- #ifndef SERIALPORT_H
- #define SERIALPORT_H
-
- #include <QMainWindow>
- #include <QtSerialPort/QSerialPort>
- #include <QtSerialPort/QSerialPortInfo>
-
- #include <QLabel>
- #include <QPushButton>
- #include <QCloseEvent>
-
- namespace Ui {
- class SerialPort;
- }
-
- class SerialPort : public QMainWindow
- {
- Q_OBJECT
-
- public:
- explicit SerialPort(QWidget *parent = 0);
- ~SerialPort();
-
- /* 初始状态栏 */
- void InitStatusBar(); // 初始化状态栏
- void SetSerState(); // 设置状态栏串口状态
- void SetRecvNum(); // 设置接收字节数
- void SetSendNum(); // 设置发送字节数
-
- /* 初始化CombBox控件 */
- void InitCommCmb(); // 初始化CombBox控件
- void SetPortNumCmb(); // 设置串口号
- QStringList GetEnableCommPortQt(); // 获取计算机可用串口 Qt方式
- QStringList GetEnableCommPortWin(); // 获取计算机可用串口 Windows API方式
- QString GetComm(int nIndex, bool bValue = true);
- void SetBaudCmb(); // 设置波特率
- void SetDPaityCmb(); // 设置校验位
- void SetDataBCmb(); // 设置数据位
- void SetStopBCmb(); // 设置停止位
- void SetStreamCmb(); // 设置流控制
-
- bool SetSerialPortParam(QSerialPort *serial); // 设置串口参数,失败返回false,成功返回true
-
- /* 父类函数重写 */
- void closeEvent(QCloseEvent *event);
-
- private slots:
- void on_baudRCmb_currentIndexChanged(int index); // 自定义波特率
- void on_OnOffBtn_clicked(); // 打开/断开串口
- void on_ReflushSerPortBtn_clicked(); // 刷新串口,重新扫描计算机可用串口
- void slot_RecvPortData(); // 接收串口数据
- void on_SendBtn_clicked(); // 发送数据
- void on_ClearRecvBtn_clicked(); // 清空接收区
- void slot_ResetNumBtn_clicked(); // 复位计数
-
- private:
- Ui::SerialPort *ui;
-
- /* 状态栏控件 */
- QLabel *m_SerStateLbl; // 串口状态
- QLabel *m_RecvNumLbl; // 接收字节数
- QLabel *m_SendNumLbl; // 发送字节数
- QPushButton *m_ResetNumBtn; // 复位计数按钮
-
- /* 发送、接收字节数 */
- uint m_nRecvNum; // 接收字节数
- uint m_nSendNum; // 发送字节数
- bool m_bOpen; // 标识串口状态
-
- QSerialPort *m_serial; // 串口通信类对象
- qint64 m_nReadBuffSize; // 串口缓冲区大小
- };
-
- #endif // SERIALPORT_H
对应 cpp:
- SerialPort::SerialPort(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::SerialPort)
- {
- ui->setupUi(this);
-
- this->setWindowTitle(tr("串口调试助手 Qt版 V1.0"));
- this->setFixedSize(this->width(), this->height());
-
- m_nRecvNum = 0;
- m_nSendNum = 0;
- m_bOpen = false;
-
- InitStatusBar();
- InitCommCmb();
-
- ui->OnOffBtn->setIcon(QIcon(":/pic/res/OFF.png"));
- ui->RecvDataEdt->setReadOnly(true);
-
- m_serial = new QSerialPort;
- connect(m_serial, SIGNAL(readyRead()), this, SLOT(slot_RecvPortData()));
- m_nReadBuffSize = 64;
-
- }
- void SerialPort::InitStatusBar()
- {
- m_SerStateLbl = new QLabel();
- m_RecvNumLbl = new QLabel();
- m_SendNumLbl = new QLabel();
- m_ResetNumBtn = new QPushButton();
- connect(m_ResetNumBtn, SIGNAL(clicked()), this, SLOT(slot_ResetNumBtn_clicked()));
-
- m_SerStateLbl->setMinimumSize(180, 20);
- m_RecvNumLbl->setMinimumSize(180, 20); // 标签最小尺寸
- m_SendNumLbl->setMinimumSize(180, 20);
-
- ui->statusBar->addWidget(m_SerStateLbl);
- ui->statusBar->addWidget(m_RecvNumLbl);
- ui->statusBar->addWidget(m_SendNumLbl);
- ui->statusBar->addWidget(m_ResetNumBtn);
-
- SetSerState();
- SetRecvNum();
- SetSendNum();
- m_ResetNumBtn->setText(tr("复位计数"));
- }
其中对应的set个个的函数:
- void SerialPort::SetSerState()
- {
- QString strState;
- if ( m_bOpen )
- strState = tr("打开");
- else
- strState = tr("关闭");
-
- m_SerStateLbl->setText(tr("串口状态:%1").arg(strState));
- }
-
- void SerialPort::SetRecvNum()
- {
- QString strRecvNum = QString::number(m_nRecvNum);
- m_RecvNumLbl->setText(tr("接收字节数:%1").arg(strRecvNum));
- }
-
- void SerialPort::SetSendNum()
- {
- QString strSendNum = QString::number(m_nSendNum);
- m_SendNumLbl->setText(tr("发送字节数:%1").arg(strSendNum));
- }
其目的在状态栏上显示对应的接收数据,并显示在状态栏上面。
- void SerialPort::InitCommCmb()
- {
- SetPortNumCmb(); // 串口号
- SetBaudCmb(); // 波特率
- SetDPaityCmb(); // 校验位
- SetDataBCmb(); // 数据位
- SetStopBCmb(); // 停止位
- SetStreamCmb(); // 流控制
- }
这些函数是初始化最基本的东西:串口号,波特率,校验位,数据位,停止位,流控制(这个用的较少)
- // 设置串口号
- void SerialPort::SetPortNumCmb()
- {
- QStringList commPortList = GetEnableCommPortQt();
- if ( !commPortList.isEmpty() )
- ui->PortNumCmb->addItems(commPortList);
- }
- // 获取计算机可用串口 QSerialPort QSerialPortInfo类
- QStringList SerialPort::GetEnableCommPortQt()
- {
- QStringList CommPortList;
-
- foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
- {
- QSerialPort serial;
- serial.setPort(info);
- if (serial.open(QIODevice::ReadWrite))
- {
- CommPortList.append(serial.portName());
- serial.close();
- }
- }
-
- return CommPortList;
- }
这个可以寻找当前串口号,然后添加到对应的选项框。
波特率:
- // 设置波特率
- void SerialPort::SetBaudCmb()
- {
- QStringList baudRList;
- baudRList.append(tr("110"));
- baudRList.append(tr("300"));
- baudRList.append(tr("600"));
- baudRList.append(tr("1200"));
- baudRList.append(tr("2400"));
- baudRList.append(tr("4800"));
- baudRList.append(tr("9600"));
- baudRList.append(tr("14400"));
- baudRList.append(tr("19200"));
- baudRList.append(tr("38400"));
- baudRList.append(tr("56000"));
- baudRList.append(tr("57600"));
- baudRList.append(tr("115200"));
- baudRList.append(tr("128000"));
- baudRList.append(tr("256000"));
- baudRList.append(tr("自定义"));
-
- ui->baudRCmb->addItems(baudRList);
- ui->baudRCmb->setCurrentIndex(6);
- }
校验位
- void SerialPort::SetDPaityCmb()
- {
- QStringList DPaityList;
- DPaityList.append(tr("NONE"));
- DPaityList.append(tr("ODD"));
- DPaityList.append(tr("EVEN"));
- DPaityList.append(tr("MARK"));
- DPaityList.append(tr("SPACE"));
-
- ui->DPaityCmb->addItems(DPaityList);
- }
数据位:
- // 设置数据位
- void SerialPort::SetDataBCmb()
- {
- for (int i = 5; i <= 8; i++)
- {
- QString strDataB = QString::number(i);
- ui->DataBCmb->addItem(strDataB);
- }
- ui->DataBCmb->setCurrentIndex(3);
- }
停止位
- // 设置停止位
- void SerialPort::SetStopBCmb()
- {
- ui->StopBCmb->addItem(tr("1"));
- ui->StopBCmb->addItem(tr("1.5"));
- ui->StopBCmb->addItem(tr("2"));
- }
流控制:
- // 流控制
- void SerialPort::SetStreamCmb()
- {
- ui->FlowCtrlCmb->addItem(tr("NO"));
- ui->FlowCtrlCmb->addItem(tr("RTS/CTS"));
- ui->FlowCtrlCmb->addItem(tr("XON/XOFF"));
- }
初始化结束后,我们开始第二歩:
- // 打开/关闭串口
- void SerialPort::on_OnOffBtn_clicked()
- {
- if (m_serial->isOpen()) // 已经处于打开状态,则关闭串口
- {
- m_serial->close();
- ui->OnOffBtn->setText(tr("打开"));
- ui->OnOffBtn->setIcon(QIcon(":/pic/res/OFF.png"));
- m_bOpen = false;
- SetSerState();
- }
- else // 串口处于关闭状态,打开串口
- {
- if ( !SetSerialPortParam(m_serial) )
- {
- QMessageBox::critical(this, tr("Error"), tr("串口错误!"), QMessageBox::Ok);
- return;
- }
-
- // 打开串口
- if ( !m_serial->open(QIODevice::ReadWrite) ) // 打开失败
- {
- QMessageBox::critical(this, tr("Error"), tr("串口不存在或者被其它程序占用!"), QMessageBox::Ok);
- // QString strRecv = ui->RecvDataEdt->toPlainText();
- // strRecv += tr("\n【Error】Can't Open COM Port!");
- ui->RecvDataEdt->append(tr("\n【Error】Can't Open COM Port!"));
- return;
- }
-
- // 设置串口缓冲区大小
- m_serial->setReadBufferSize(m_nReadBuffSize);
-
- ui->OnOffBtn->setText(tr("断开"));
- ui->OnOffBtn->setIcon(QIcon(":/pic/res/ON.png"));
- m_bOpen = true;
- SetSerState();
- }
- }
- // 设置串口参数,失败返回false,成功返回true
- bool SerialPort::SetSerialPortParam(QSerialPort *serial)
- {
- // 设置串口号
- QString strPortNum = ui->PortNumCmb->currentText();
- if (strPortNum == tr(""))
- return false;
- serial->setPortName(strPortNum);
-
- // 设置波特率
- qint32 nBaudRate = ui->baudRCmb->currentText().toInt();
- serial->setBaudRate(nBaudRate);
-
- // 设置奇偶校验
- int nParityType = ui->DPaityCmb->currentIndex();
- switch (nParityType)
- {
- case 0:
- serial->setParity(QSerialPort::NoParity);
- break;
- case 1:
- serial->setParity(QSerialPort::OddParity);
- break;
- case 2:
- serial->setParity(QSerialPort::EvenParity);
- break;
- case 3:
- serial->setParity(QSerialPort::MarkParity);
- break;
- case 4:
- serial->setParity(QSerialPort::SpaceParity);
- break;
- default:
- serial->setParity(QSerialPort::UnknownParity);
- break;
- }
-
- // 设置数据位
- int nDataBits = ui->DataBCmb->currentIndex();
- switch (nDataBits)
- {
- case 0:
- serial->setDataBits(QSerialPort::Data5);
- break;
- case 1:
- serial->setDataBits(QSerialPort::Data6);
- break;
- case 2:
- serial->setDataBits(QSerialPort::Data7);
- break;
- case 3:
- serial->setDataBits(QSerialPort::Data8);
- break;
- default:
- serial->setDataBits(QSerialPort::UnknownDataBits);
- break;
- }
-
- // 设置停止位
- int nStopBits = ui->StopBCmb->currentIndex();
- switch (nStopBits)
- {
- case 0:
- serial->setStopBits(QSerialPort::OneStop);
- break;
- case 1:
- serial->setStopBits(QSerialPort::OneAndHalfStop);
- break;
- case 2:
- serial->setStopBits(QSerialPort::TwoStop);
- break;
- default:
- serial->setStopBits(QSerialPort::UnknownStopBits);
- break;
- }
-
- // 流控制
- int nFlowCtrl = ui->FlowCtrlCmb->currentIndex();
- switch (nFlowCtrl)
- {
- case 0:
- serial->setFlowControl(QSerialPort::NoFlowControl);
- break;
- case 1:
- serial->setFlowControl(QSerialPort::HardwareControl);
- break;
- case 2:
- serial->setFlowControl(QSerialPort::SoftwareControl);
- break;
- default:
- serial->setFlowControl(QSerialPort::UnknownFlowControl);
- break;
- }
-
- return true;
- }
- // 槽函数,接收串口数据
- void SerialPort::slot_RecvPortData()
- {
- QByteArray bytes = m_serial->readAll();
-
- if ( !bytes.isEmpty() )
- {
- QString strRecv = QString::fromLocal8Bit(bytes);
- ui->RecvDataEdt->append(strRecv);
-
- m_nRecvNum += bytes.count();
- SetRecvNum();
- }
- else
- ui->RecvDataEdt->setText(tr("接收数据出错!"));
- }
-
- // 发送数据,写串口
- void SerialPort::on_SendBtn_clicked()
- {
- // 串口未打开
- if ( !m_bOpen )
- {
- QMessageBox::warning(this, tr("Error"), tr("串口未打开,发送失败!"), QMessageBox::Ok);
- return;
- }
-
- QByteArray SendBytes = ui->SendDataEdt->toPlainText().toLocal8Bit();
- if ( !SendBytes.isEmpty() )
- {
- m_serial->write(SendBytes);
- m_nSendNum += SendBytes.count();
- SetSendNum();
- }
- }
这里如果想显示16进制,可以把代码给为下面:
- QByteArray buffer = tcpClient->readAll();
- int length = buffer.count();
- if(!buffer.isEmpty())
- {
- for(int i = 0; i<length; i++)
- {
- ui->textEdit_2->append(QString::asprintf("%0.2X ",buffer.at(i)));
- }
- // ui->textEdit_2->append(buffer.toHex()); //16进制显示出来数据
- }
这样输出的就是大写的16进制的数据啦。
- // 串口关闭事件,如果窗口关闭前串口未关闭,则关闭串口
- void SerialPort::closeEvent(QCloseEvent *event)
- {
- if (m_serial->isOpen())
- m_serial->close();
-
- event->accept();
- }
-
- // 波特率自定义
- void SerialPort::on_baudRCmb_currentIndexChanged(int index)
- {
- uint nCount = ui->baudRCmb->count();
- if ((unsigned)index == nCount - 1)
- {
- ui->baudRCmb->setEditable(TRUE);
- ui->baudRCmb->setItemText(index, tr(""));
- }
- else
- {
- ui->baudRCmb->setEditable(FALSE);
- ui->baudRCmb->setItemText(nCount-1, tr("自定义"));
- }
- }
-
- // 刷新串口
- void SerialPort::on_ReflushSerPortBtn_clicked()
- {
- ui->PortNumCmb->clear();
- SetPortNumCmb();
- }
-
- // 复位计数
- void SerialPort::slot_ResetNumBtn_clicked()
- {
- m_nSendNum = 0;
- m_nRecvNum = 0;
- SetSendNum();
- SetRecvNum();
- }
-
- // 清空接受区
- void SerialPort::on_ClearRecvBtn_clicked()
- {
- ui->RecvDataEdt->setText(tr(""));
- }
需要例子的可以私信我,关注我。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。