串口协议包的接收及解析处理

对于串口接收问题前面之前有文章介绍过串口缓存机制的应用。当然这里不应用缓存机制也是完全可行的。这里我们讲解基于不带串口缓存机制的处理。对于串口接收我们最常用的方式就是在串口中断中接收数据。

利用串口接收数据包信息大致分为下面三种情况:

  1. 接收一帧数据,对帧数据进行处理(可以利用串口接收非空中断和串口空闲中断实现)
  2. 中断中边接收边处理存储,并将有效数据存储起来,再对有效数据进行解析。
  3. 将接收到的数据全部存入缓存,从缓存中提取数据并做处理。

第11课.串口(UART)的使用

1.UART连线图

S3C2440有3个独立通道的UART

2.数据传输流程

1.平时数据线处于“空闲”状态(1状态)
2.当要发送数据时,UART改变TxD数据线的状态(变为0状态),并维持1位的时间,这样接收方检测到开始位后,在等待1.5位的时间就开始一位一位的检测数据线的状态得到所传输的数据
3.UART一帧中可以有5,6,7或8位的数据,发送方一位一位的改变数据线的状态将它们发送出去。首先发送最低位
4.如果使用校验功能,UART在发送完数据位后,还要发送1个校验位。有两种校验方法:奇校验,偶校验——数据位连同校验位,“1”的数目等于奇数或偶数
5.最后,发送停止位。数据线恢复到“空闲”状态(1状态)。停止位的长度有3种:1位,1.5位,2位

 正是由于这种机制,没有干扰的情况下,发送每个字节都能读到。

Linux读取串口数据

问题背景

大致为:有一个发送端周期性的往本机串口上发送数据,本机需要定时读取串口数据,解析,获取自己想要的信息。实际描述为:由于是做智能驾驶的,需要读取车辆速度,通过OBD设备读取并解析车辆速度,然后通过蓝牙发送给PC串口(也是通过一个蓝牙模块接收),PC端串口定时接收串口数据并解析。

在上述过程中,有一个问题需要注意:发送方是周期性的不停的发送数据,也就是说PC机串口一直有数据进来,最常见的是发送端频率比接收端频率高,即准备读取串口数据时总可以读取的数据,但也也导致了另一个问题,那就是怎么处理接收端串口缓冲,因为你每次的读取操作都必须要把当前串口缓冲区中数据全部读取出来,不能只读一部分,不然发送端一直有数据进来,而你每次都不读玩,就会造成缓冲区溢出。

串口的实质是什么

但凡接触过Linux系统知识或者了解计算机系统原理,那你一定通过一句话“在任何操作系统下,一切都是文件”,Linux系统就是这句话的最完美的实现,即在Linux系统下,你完全可以把所有东西当成是一个文件、即所有东西都可以按照“打开——设置——读写——关闭”的模式进行,同样,在Linux下串口也可以看成是一种文件(其实任何操作系统下都可以这样认为),你要读写串口数据,就必须先打开、设置串口,然后读写,读写完毕,就必须要关闭串口。

从串口缓冲区里读数据,其实和打开txt文件读数据一样,可以一次读几个字节,也可以全读出来。

(1)打开串口:

在ReadCarSpeed.cpp文件中,OpenCom()函数负责打开和设置串口,这里有一点需要啰嗦一下:myCom->setTimeout(50);延时设置函数,我这里设置的是50ms,对于这个延时,我的理解是本机串口的接收频率,注意这个接收频率是不同于你读取的频率的,这里的接收频率是本机串口缓冲区接收数据的延时,即没50ms就有一个数据进去接收缓冲区队列(要理解数据缓冲区实际就是一个队列,先进先出),而你读取的频率是你调用readAll()函数的频率,如我的读取频率就是主控程序的频率(大约为500ms),所以每次大约读取10个速度信息。

缓冲区(buffer)与缓存(cache)

一、什么是缓冲区

缓冲区(buffer),它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区,显然缓冲区是具有一定大小的。

缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。

二、为什么要引入缓冲区

我们为什么要引入缓冲区呢?

高速设备与低速设备的不匹配,势必会让高速设备花时间等待低速设备,我们可以在这两者之间设立一个缓冲区。

缓冲区的作用:

1.可以解除两者的制约关系,数据可以直接送往缓冲区,高速设备不用再等待低速设备,提高了计算机的效率。例如:我们使用打印机打印文档,由于打印机的打印速度相对较慢,我们先把文档输出到打印机相应的缓冲区,打印机再自行逐步打印,这时我们的CPU可以处理别的事情。

2.可以减少数据的读写次数,如果每次数据只传输一点数据,就需要传送很多次,这样会浪费很多时间,因为开始读写与终止读写所需要的时间很长,如果将数据送往缓冲区,待缓冲区满后再进行传送会大大减少读写次数,这样就可以节省很多时间。例如:我们想将数据写入到磁盘中,不是立马将数据写到磁盘中,而是先输入缓冲区中,当缓冲区满了以后,再将数据写入到磁盘中,这样就可以减少磁盘的读写次数,不然磁盘很容易坏掉。

简单来说,缓冲区就是一块内存区,它用在输入输出设备和CPU之间,用来存储数据。它使得低速的输入输出设备和高速的CPU能够协调工作,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作。

小草手把手教你 LabVIEW 串口仪器控制——VISA 串口配置

串口有个缓冲区,存在计算机内存里,VISA 读取,就是从缓冲区读取数据,读完之后,读取的就不存在缓冲区里了。如果你没读取,那就一直在缓冲区里,直到缓冲区溢出。其实就好比一个水桶,写 VISA 是往水桶进水,读 VISA 是出水。你也可以想想队列的原理,差不多的。

手把手教你学51单片机-C语言版.pdf

UART (Universal Asynchronous Receiver/Transmitter,即通用异步收发器)串行通信是单片机最常用的一种通信技术,通常用于单片机和电脑之间以及单片机和单片机之间的通信。

11.1 串行通信的初步认识

当单片机 1 想给单片机 2 发送数据时,比如发送一个 0xE4 这个数据,用二进制形式表 示就是 0b11100100,在 UART 通信过程中,是低位先发,高位后发的原则,那么就让 TXD 首先拉低电平,持续一段时间,发送一位 0,然后继续拉低,再持续一段时间,又发送了一 位 0,然后拉高电平,持续一段时间,发了一位 1……一直到把 8 位二进制数字 0b11100100 全部发送完毕。这里就涉及到了一个问题,就是持续的这“一段时间”到底是多久?由此便引入了通信中的一个重要概念——波特率,也叫做比特率。

波特率就是发送二进制数据位的速率,习惯上用 baud 表示,即我们发送一位二进制数据 的持续时间=1/baud。在通信之前,单片机 1 和单片机 2 首先都要明确的约定好它们之间的通 信波特率,必须保持一致,收发双方才能正常实现通信,这一点大家一定要记清楚。

约定好速度后,我们还要考虑第二个问题,数据什么时候是起始,什么时候是结束呢? 不管是提前接收还是延迟接收,数据都会接收错误。在 UART 通信的时候,一个字节是 8 位, 规定当没有通信信号发生时,通信线路保持高电平,当要发送数据之前,先发一位 0 表示起 始位,然后发送 8 位数据位,数据位是先低后高的顺序,数据位发完后再发一位 1 表示停止 位。这样本来要发送一个字节的 8 位数据,而实际上我们一共发送了 10 位,多出来的两位 其中一位起始位,一位停止位。而接收方呢,原本一直保持的高电平,一旦检测到了一位低 电平,那就知道了要开始准备接收数据了,接收到 8 位数据位后,然后检测到停止位,再准 备下一个数据的接收。我们图示看一下,如图 11-2 所示。

图 11-2 串口数据发送示意图,实际上是一个时域示意图,就是信号随着时间变化的对应 关系。比如在单片机的发送引脚上,左边的是先发生的,右边的是后发生的,数据位的切换 时间就是波特率分之一秒,如果能够理解时域的概念,后边很多通信的时序图就很容易理解 了。

11.4 IO 口模拟 UART 串口通信

这一节对理解串口的高低电平发送与接收特别有帮助,具体看  第11章 UART 串口通信(手把手教你学51单片机pdf部分)

11.5.2 UART 模块介绍

IO 口模拟串口通信,让大家了解了串口通信的本质,但是我们的单片机程序却需要不停 的检测扫描单片机 IO 口收到的数据,大量占用了单片机的运行时间。这时候就会有聪明人 想了,其实我们并不是很关心通信的过程,我们只需要一个通信的结果,最终得到接收到的 数据就行了。这样我们可以在单片机内部做一个硬件模块,让它自动接收数据,接收完了, 通知我们一下就可以了,我们的 51 单片机内部就存在这样一个 UART 模块,要正确使用它, 当然还得先把对应的特殊功能寄存器配置好。

Linux串口读取与解析相关推荐

  1. linux串口返回条件,c – Linux – 串口读取返回EAGAIN

    我在从以下方式打开的串口读取一些数据时遇到了一些麻烦.我已经多次使用这个代码实例并且一切正常,但现在,由于某些原因我无法弄清楚,我完全无法从串口读取任何内容. 我能够在另一端写入并正确接收所有内容,但 ...

  2. linux串口读取 GPS模块程序

    最近找到一个GPS模块,在接上了CH340串口工具后,我想试试自己编写一个程序在Linux环境下读取GPS数值. 串口编程的流程 串口也是一种字符设备,串口编程的流程包括: 打开串口:open函数 初 ...

  3. linux 串口读取陀螺仪,stm32读取陀螺仪MPU6050发送数据到串口

    [实例简介] IAR环境下,stm32读取MPU6050数据,发送到串口. [实例截图] [核心代码] 6b42b05e-a094-444f-b033-eda513b6cc49 └── tly01 ├ ...

  4. linux串口读取mpu9250数据,模拟 I2C 读取 MPU9250 数据的测试笔记

    硬件:STM32F103ZET6 + GY9250 软件:Keil MDK(v5.27)+ STM32CUBEMX(v5.2.1) 这里我在使用STM32CUBEMX最新版本(v5.5.0)生成Kei ...

  5. linux通过串口读取文件,Linux 串口读写(二)

    例子 下面是一个简单的读取串口数据的例子,使用了上面定义的一些函数和头文件 /************************************************************* ...

  6. Linux下读取RFID卡号(C串口编程)

    由于项目需要用到RFID.GPRS.摄像头等模块所以便看了一下,整理了一下学习思路,本篇先是整理一下串口读取RFID卡号的程序思路,后面还会更其他的 RFID模块: 本次采用的是125K的RFID读卡 ...

  7. linux系统读sim卡信息,在Linux下使用串口读取SIM卡上的SMS消息使用C

    试图通过linux中的串口读取sms消息,从一张安装在华为3g USB调制解调器内的SIM卡读取.我必须在屏幕上显示一些短信之前执行脚本.有时它显示不寻常的字符.我想要做的就是使用AT命令,c和串行端 ...

  8. GPS NMEA 0183 4.10协议/GPS Linux串口驱动

      NMEA 0183是美国国家海洋电子协会(National Marine Electronics Association)为海用电子设备制定的标准格式.现在已经成为GPS导航设备统一的RTCM(R ...

  9. Linux串口应用编程

    目录 Demo 串口应用编程介绍 终端Terminal 串口应用编程(配置.读取.写入) struct termios 结构体配置 输入模式: c_iflag 输出模式: c_oflag 控制模式: ...

最新文章

  1. Exchange 2010和Exchange 2016共存部署-3:Exchange2016部署系统要求
  2. AI也能写高考作文?我们用清华刚刚开源的「九歌」试了试
  3. IronRuby 0.0.1.0
  4. 解决笔记本重装问题(VISTA系统改为XP系统)
  5. sublime 关闭自动更新
  6. 敢闯会创,第七届中国国际“互联网+”双创大赛腾讯广告产业命题等你来战!
  7. string s=new string() 创建了几个对象_Java的String类5个常见面试题的解答过程和原理...
  8. 英文论文中“such as, for example, e.g., i.e., etc., et al. ”的用法分析 (转)
  9. 浅谈Web网站的架构演变过程
  10. Linux下的内核测试工具——perf使用简介
  11. 龙芯的JDK非常慢,准备分析一下
  12. 一种定位激光在摄像头画面中位置的方法(附安卓源码)
  13. DCMTK3.6.5+cmake3.7.1+VS2017配置过程
  14. QLineEdit屏蔽扫描枪输入自带回车的方法
  15. Spring Boot项目WebService接口发布、调用、以及常见错误详解
  16. linux docer 安装redis
  17. ubuntu登录桌面后只显示壁纸,排查方案
  18. PPPOE和pppd的流程详解
  19. 硬盘活动分区(将磁盘分区标为活动或取消活动的方法)(转)
  20. 计算机二级有没有年龄,九龄童通过全国计算机二级 创年龄最小纪录(图)_新闻中心_新浪福建_新浪网...

热门文章

  1. 从零开始撸音乐播放器(源码可下载)
  2. 浪潮小机装oracle数据库,浪潮ERP系统oracle双机热备安装文档 | 浪潮888博客
  3. Mysql 755和750权限,chmod 755 究竟是什么鬼?
  4. 关于不能成为专业软件测试人员的10大理由的一些阐述
  5. CF735E Ostap and Tree
  6. nginx大量TIME_WAIT的解决办法(转载)
  7. ASP.Net4.0中新增23项功能
  8. DevExpress最强干货|实用示例、更新等你来体验!
  9. Map集合中value()方法与keySet()、entrySet()区别 ——转载
  10. 基于TransactionScope类的分布式隐式事务