串口接收完整一帧数据处理方式

原文地址:让串口可以自动分辨一帧数据作者:李冬冬

有时我们希望串口接收到数据后,在该帧数据的末尾加上一些标志,比如这是第几帧或接收的时间等等。那么我们就需要知道什么时候

接收到了完整的一帧数据。有两种方法可以实现:

1,自己人为地在一帧数据的最后加上一个标志符号,如#,@等,上位机接收到这些标志后可认为一帧数据到来完成。这样做很方便,但缺点是

只能分辨自己做好的数据,对于别人做的设备的信号监控做不到分割

2:利用定时器判断一帧数据是否完成。这种做法可以通用与任何信息。

下面主要分析第二种方法,对第一种方法感兴趣的朋友可以自己实验。以波特率9600BPS为例。

9600BPS,则传送每一位的时间为1000MS/9600=0.104MS,即位与位之间间隔为0.104MS,

现在假如我们在操作PC机最底层IO,收到5个数据。当5个数据的第一个数据到来时,我们启动一个

定时器,时间为1MS,然后每收到一个数据时就重新设置定时器,因为0.104MS要远远小于1MS,所以

如果一直有数据来,定时器就会被重设,没有溢出的机会。当没有数据来了(也就是第5个数据接收到了)

定时器不会被重设直到溢出产生事件号,然后我们就到这个事件号的处理函数里面处理刚接收的完整的一帧数据了

,当然该处理函数里面要停止定时器,直到再有数据来才开启。本人不善言辞,不直到讲的大家听懂没有。

下面弄点实际的东东给大家看,我是把yafeilinux 老兄的串口稍加修改做成,如果刚看到我的例子的朋友

可以先看看他写的串口(Qt编写串口通信程序全程图文讲解),写的很好很容易懂。

头文件中增加如下:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMessageBox>
#include <QTimer>//添加定时器类
#include <QtCore>//添加日期类
#include <QString>
#include “win_qextserialport.h”

namespace Ui
{
    class MainWindow;
}

class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

protected:
    void changeEvent(QEvent *e);

private:
    Ui::MainWindow *ui;
    Win_QextSerialPort *myCom;

//增加一个数据用于放数据
    char data[1024];

//增加一个标志用于计算接收了个多少数据        
    unsigned int bytesRead ;       
    QTimer *timer;

private slots:
    void on_sendComMsgbtn_released();
    void on_closeMyCombtn_released();
    void on_openMyCompbn_released();

// 增加一个函数用于定时器溢出后的处理程序
    void timerUpDate();
    void readMyCom();
};

#endif // MAINWINDOW_H

然后是.cpp文件

#include “mainwindow.h”
#include “ui_mainwindow.h”

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->openMyCompbn->setEnabled(true);
    ui->closeMyCombtn->setEnabled(false);
    ui->sendComMsgbtn->setEnabled(false);
    bytesRead = 0;
    timer = new QTimer(this);

connect(timer,SIGNAL(timeout()),this,SLOT(timerUpDate()));
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void MainWindow::readMyCom()
{
    unsigned int byte = 0;
    byte = myCom->read(&data[bytesRead], 1024);
    bytesRead +=byte;

//上面讲的就在此体现了,为什么是50呢,因为此是并不是操作最底层IO,PC机会将数据接收几个后在给上层。所以这个时间稍微长一点点
    timer->start(50);

}
void MainWindow::on_openMyCompbn_released()
{
   
    struct PortSettings myComSetting = {BAUD9600,DATA_8,PAR_NONE,STOP_1,FLOW_OFF,
                                    500};
    myCom = new Win_QextSerialPort(“com1″,myComSetting,QextSerialBase::EventDriven);
   if( myCom->open(QIODevice::ReadWrite))
    {
    connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));
    ui->openMyCompbn->setEnabled(false);
    ui->closeMyCombtn->setEnabled(true);
    ui->sendComMsgbtn->setEnabled(true);
    }
   else
   {
       QMessageBox::information(this,tr(“错误”),tr(“串口被打开或没有该串口”));
   }
}

void MainWindow::on_closeMyCombtn_released()
{
    myCom->close();
    ui->openMyCompbn->setEnabled(true);
    ui->closeMyCombtn->setEnabled(false);
    ui->sendComMsgbtn->setEnabled(false);
}

void MainWindow::on_sendComMsgbtn_released()
{
    myCom->write(ui->sendMsglineEdit->text().toAscii());
}

//定时器到的处理函数,我在数据的最好添加了一帧日期。刚看这里的朋友也可以看看yafeilinux讲的关于定时器和日期(十、Qt Creator中实现定时器和产生随机数)的文章
void MainWindow::timerUpDate()
{
    timer->stop();
    QDateTime time = QDateTime::currentDateTime();
    QString str = time.toString(“yyyy-MM-dd hh:mm:ss dddd”);
    ui->textBrowser->insertPlainText(str.append(‘n’));
    data[bytesRead] = ‘n’;
    data[bytesRead+1] = ”;
    ui->textBrowser->insertPlainText(data);
    bytesRead = 0;
}

好了,讲到这了,本人才疏学浅,学QT也没几日,上面难免会出现不地道的语句,希望大家别见笑。另外,这个发帖子的东东我也是第一次用,发的帖子不是很好,以后慢慢学习。另外希望大家一起进步。

让串口可以自动分辨一帧数据相关推荐

  1. java 串口判断报文完整_如何判断串口接收完成一帧数据

    1 使用定时器判断 这种方式建立在两帧数据不可能连续发送的基础上,也是modbus判断帧结束的方式,在接收到第一个字节的时候打开定时器,如果继续接收到数据则更新定时器,在被设定时间内没有接收到数据则定 ...

  2. 教你使用stm32接收串口的一帧数据!

    stm32支持接受单个数据或者一帧数据,若配置单个数据接收中断的话,会出现接收包丢包,数据不完整的情况!因此在stm32的串口中断中,还有一个IDLE中断,用来产生串口接受一帧数据而产生的中断,比如说 ...

  3. js 串口通信mscomm接收undefined_串口通信帧的同步方法(识别一帧数据的起始结束)42...

    串口通信是单片机和DSP等嵌入式系统之间,以及嵌入式系统与PC机或无线模块之间的一种非常重要且普遍使用的通信方式.在嵌入式系统的硬件结构中,通常只有一个8位或16位的CPU,不仅要完成主流程的工作,同 ...

  4. 工程思想——关于串口通讯协议帧数据的一些想法

    前言:之前在学校上计算机网络这门课程时候,被里面的各种协议绕的头晕眼花,总以为这些协议都已经被前辈固定,后生们只要按照之前的协议老老实实收发数据就能解决一切,直到自己也有做东西时要自己编写通讯协议时, ...

  5. 关于STM32串口3的使用,接收并解析一帧数据

    关于STM32串口3的使用,接收并解析一帧数据 当stm32的串口1被使用时,我们可以使用其他串口来使用. 步骤: 串口3定义.初始化: 串口3中断服务函数(接收的一帧数据并判断是否正确): 主函数使 ...

  6. STM32串口读取一帧数据USART_IT_IDLE

    stm32 串口读取数据中断 USART_IT_RXNE:读取到一个数据产生中断 USART_IT_IDLE:读取到一帧数据产生中断 以前串口读取一帧数据的方法:收到数据后重置定时器的值,等到定时器超 ...

  7. STM32串口中断接收帧数据并返回给上位机总结(配合MAX3483)

    一.前言 这是我的第一篇CSDN,记录一些代码总结,一方面与大家分享交流,另一方面方便以后再次使用能够快速回忆,再就是提高自身写作水平.如有错误之处,欢迎各位大佬批评指正. 二.所涉及的芯片 1.ST ...

  8. stm32串口空闲中断接收不定长数据

    串口空闲中断接收不定长数据 空闲中断是接受数据后出现一个byte的高电平(空闲)状态,就会触发空闲中断.并不是空闲就会一直中断,准确的说应该是上升沿(停止位)后一个byte,如果一直是低电平是不会触发 ...

  9. STM32单片机串口空闲中断接收不定长数据

    在使用单片机的串口通信功能时,常用的接收数据方法是通过固定的字节数来判断一帧数是否发送完成,或者是通过固定的结束标志位来表示一帧数据发送完成.但是有时候会遇到发送的数据长度不固定,也没有固定的结束标志 ...

最新文章

  1. IT服务管理(ITSM):IT行业变革的思考(4)
  2. 一个BADI中实施多个Implementation
  3. Docker如何正确开启 Hyper-V?
  4. 移动app部分机型无法唤起h5支付宝支付_用这段代码对App说:喂,醒醒!App,到你出场了!...
  5. 谷歌回归中国,最紧张的为什么会是小米、华为们?
  6. JFrog Container Registry 搭建Docker镜像仓库 (tar.gz 版本)
  7. 加载项找不到java,未显示自定义Outlook加载项
  8. 【十五分钟Talkshow】如何善用你的.NET开发环境
  9. php如何生成伪静态url,thinkphp控制器(三) 伪静态及URL生成
  10. 基于ObjectCache的应用
  11. 享元模式在 Java String 中的应用
  12. 2. jQuery 语法
  13. 修改屏幕分辨率比例,4*3拼接屏 21:9 比例,大屏项目拼接适配屏解决方案
  14. 5G风起,CDN边缘计算将乘风破浪
  15. [BZOJ 3654] 图样图森破
  16. Protobuf 介绍与实战21:如何生成一维数组、二维数组(repeated数组类型介绍)
  17. 1276 不浪费原料的汉堡制作方案
  18. app启动速度优化实践
  19. 组合数学(三)鸽巢原理
  20. 双目摄像头——活体检测

热门文章

  1. jQuery实现点击开关图片切换
  2. 第1章 ZLG7290B 简介
  3. Hibernate Annotation _List/Map
  4. CI配置文件 --------- autoload.php
  5. fir.im Weekly - APP 性能监测优化 二三事
  6. CSS FILTERS:CSS过滤器能够做什么?
  7. 1. 列维过程的混沌及可料表示(1)
  8. img 隐藏_CSS3界面样式和溢出文字隐藏overflow
  9. springcloud 整合 gateway_GitHub上最火的SpringCloud微服务商城系统项目,附全套教程
  10. PCB 零件尺寸图:Arduino Mega 2560 尺寸