2串口收发数据

来源:互联网 发布:网络h小说合集 编辑:程序博客网 时间:2024/05/24 07:28

一,精简版串口代码

1,界面设计

2,串口头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "win_qextserialport.h"
#include "qextserialbase.h"
#include "qextserialport.h"
//我的修改123456789
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    Ui::MainWindow *ui;
//串口编程函数
private:
    Win_QextSerialPort *myCom;
private slots:
    //读取数据槽函数
    void readMyCom();
    void on_openMyComBtn_clicked();
    void on_closeMyConBtn_clicked();
    void on_sendMsgBtn_clicked();
};
#endif // MAINWINDOW_H

3,串口.cpp文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QByteArray>
#include <QString>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->closeMyConBtn->setEnabled(false); //开始“关闭串口”按钮不可用
    ui->sendMsgBtn->setEnabled(false); //开始“发送数据”按钮不可用
    /*
    struct PortSettings myComSetting = {BAUD4800,DATA_8,PAR_NONE,STOP_1,FLOW_OFF,
    500};
    //定义一个结构体,用来存放串口各个参数
    myCom = new Win_QextSerialPort("com5",myComSetting,QextSerialBase::EventDriven);
    //定义串口对象,并传递参数,在构造函数里对其进行初始化
    myCom ->open(QIODevice::ReadWrite);
    //以可读写方式打开串口
    connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));
    //信号和槽函数关联,当串口缓冲区有数据时,进行读串口操作
    */
}
MainWindow::~MainWindow()
{
    delete ui;
}
//在下面添加 readMyCom()函数的定义,添加如下代码。
void MainWindow::readMyCom() //读串口函数
{
QByteArray temp = myCom->readAll();
//读取串口缓冲区的所有数据给临时变量 temp
ui->textBrowser->insertPlainText(temp);
//将串口的数据显示在窗口的文本浏览器中
}
//打开串口函数
void MainWindow::on_openMyComBtn_clicked()
{
    //打开串口之前的参数设置
    QString portName = ui->portName->currentText(); //获取串口名
    myCom = new Win_QextSerialPort(portName,QextSerialBase::EventDriven);
    //定义串口对象,并传递参数,在构造函数里对其进行初始化
    myCom ->open(QIODevice::ReadWrite); //打开串口
    if(ui->baudRate->currentText()==tr("4800")) //根据组合框内容对串口进行设置
    myCom->setBaudRate(BAUD4800);
    else if(ui->baudRate->currentText()==tr("9600"))
    myCom->setBaudRate(BAUD9600);
    else if(ui->baudRate->currentText()==tr("115200"))
    myCom->setBaudRate(BAUD115200);
    //设置波特率
    if(ui->dataBits->currentText()==tr("8"))
    myCom->setDataBits(DATA_8);
    else if(ui->dataBits->currentText()==tr("7"))
    myCom->setDataBits(DATA_7);
    //设置数据位
    if(ui->parityCombox->currentText()==tr("无"))
    myCom->setParity(PAR_NONE);
    else if(ui->parityCombox->currentText()==tr("奇"))
    myCom->setParity(PAR_ODD);
    else if(ui->parityCombox->currentText()==tr("偶"))
    myCom->setParity(PAR_EVEN);
    //设置奇偶校验
    if(ui->stopBits->currentText()==tr("1"))
    myCom->setStopBits(STOP_1);
    else if(ui->stopBits->currentText()==tr("2"))
    myCom->setStopBits(STOP_2);
    //设置停止位
    myCom->setFlowControl(FLOW_OFF); //设置数据流控制,我们使用无数据流控制的默认设置
    myCom->setTimeout(500); //设置延时
    connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));
    //信号和槽函数关联,当串口缓冲区有数据时,进行读串口操作
    ui->openMyComBtn->setEnabled(false); //打开串口后“打开串口”按钮不可
    ui->closeMyConBtn->setEnabled(true); //打开串口后“关闭串口”按钮可用
    ui->sendMsgBtn->setEnabled(true); //打开串口后“发送数据”按钮可用
    ui->baudRate->setEnabled(false); //设置各个组合框不可用
    ui->dataBits->setEnabled(false);
    ui->parityCombox->setEnabled(false);
    ui->stopBits->setEnabled(false);
    ui->portName->setEnabled(false);
    /*
    //定义一个结构体,用来存放串口各个参数
    struct PortSettings myComSetting = {BAUD4800,DATA_8,PAR_NONE,STOP_1,FLOW_OFF,
    500};
    //定义串口对象,并传递参数,在构造函数里对其进行初始化
    myCom = new Win_QextSerialPort("com5",myComSetting,QextSerialBase::EventDriven);
    //以可读写方式打开串口
    myCom ->open(QIODevice::ReadWrite);
    //信号和槽函数关联,当串口缓冲区有数据时,进行读串口操作
    connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));
    ui->openMyComBtn->setEnabled(false); //打开串口后“打开串口”按钮不可用
    ui->closeMyConBtn->setEnabled(true); //打开串口后“关闭串口”按钮可用
    ui->sendMsgBtn->setEnabled(true); //打开串口后“发送数据”按钮可用
    */
}
//关闭串口的函数
void MainWindow::on_closeMyConBtn_clicked()
{
   myCom->close();  //关闭串口函数
   ui->closeMyConBtn->setEnabled(false);  //关闭串口按钮失能
   ui->sendMsgBtn->setEnabled(false);  //发送按钮失能
   ui->openMyComBtn->setEnabled(true);  //打开按钮串口使能
}
//发送数据的槽函数
void MainWindow::on_sendMsgBtn_clicked()
{
    myCom->write(ui->sendMesLineEdit->text().toLocal8Bit());
}
4,文件工程目录

运行环境;window7,Qt Creator5.4

//上述代码为整个串口收发的核心代码,是最初的雏形,是所有后续的关键;

既然是雏形,必然存在一定的缺陷:串口的收是全双工的,每发送一个数据,就会就收一个数据,从而会导致数据的断层,数据的显示不完整。

针对上述问题做出如下改进

二:串口收发数据的改进版

改进方案:

1、打开一个定时器,当串口接收到数据后,启动定时器,开始计时,计时时间到后,再对数据的进行处理;

2、在定时器计时的这段时间内,对串口接收的数据进行追加到字符串的末尾;

3、计时的时间到后,对数据进行按字节处理,这样就可以得到我们想要的数据啦。

详情请阅如下代码:

1,串口接收数据,将数据进行追加

//在下面添加 readMyCom()函数的定义,添加如下代码。
void mySerial::readMyCom() //读串口函数
{
    timer.start(100);  //定时100ms处理数据
    myRecvData.append(myCom->readAll()); //将串口的数据保存起来
}
2,超时数据处理,
//定时器超时处理函数
void mySerial::timeoutSlot()
{
    timer.stop(); //停止定时器
    int i=0;
    //**********重点在此*******//
    myRecvData.toHex();; //将读到的数据转化成16进制数据
    QDataStream out(&myRecvData,QIODevice::ReadWrite);//有字节数据发送过来
    while(!out.atEnd())
    {
        qint8 outChar = 0;//设置发送长度初始值为0
        out>>outChar;//每字节填充一次,直到结束
        recvData[i++]=outChar;
        if(i>99)
            break;
        qDebug()<<"timeoutSlot():"<<outChar;
    }
    emit getSerialReadData(recvData,i);
}

上述工程在Qt5.4中编译运行通过,完整工程如下:
Qt串口通信两个完整工程
博文索引  持续更新中。。。