瑞萨S5D9实现UART环形缓冲
队列的常见两种形式,普通队列和环形队列:
普通队列:

环形队列:

当有大量数据的时候,我们不能存储所有的数据,那么计算机处理数据的时候,只能先处理先来的,那么处理完后呢,就会把数据释放掉,再处理下一个。那么,已经处理的数据的内存就会被浪费掉。因为后来的数据只能往后排队,如过要将剩余的数据都往前移动一次,那么效率就会低下了,肯定不现实,所以,环形队列就出现了。
队列头 (Head) :允许进行删除的一端称为队首。
队列尾 (Tail) :允许进行插入的一端称为队尾。
环形队列的实现:在计算机中,也是没有环形的内存的,只不过是我们将顺序的内存处理过,让某一段内存形成环形,使他们首尾相连,简单来说,这其实就是一个数组,只不过有两个指针,一个指向列队头,一个指向列队尾。指向列队头的指针(Head)是缓冲区可读的数据,指向列队尾的指针(Tail)是缓冲区可写的数据,通过移动这两个指针(Head) &(Tail)即可对缓冲区的数据进行读写操作了,直到缓冲区已满(头尾相接),将数据处理完,可以释放掉数据,又可以进行存储新的数据了。
实现的原理:初始化的时候,列队头与列队尾都指向0,当有数据存储的时候,数据存储在‘0’的地址空间,列队尾指向下一个可以存储数据的地方‘1’,再有数据来的时候,存储数据到地址‘1’,然后队列尾指向下一个地址‘2’。当数据要进行处理的时候,肯定是先处理‘0’空间的数据,也就是列队头的数据,处理完了数据,‘0’地址空间的数据进行释放掉,列队头指向下一个可以处理数据的地址‘1’。从而实现整个环形缓冲区的数据读写。

看图,队列头就是指向已经存储的数据,并且这个数据是待处理的。下一个CPU处理的数据就是1;而队列尾则指向可以进行写数据的地址。当1处理了,就会把1释放掉。并且把队列头指向2。当写入了一个数据6,那么队列尾的指针就会指向下一个可以写的地址。

从队列到串口缓冲区的实现
串口环形缓冲区收发:在很多入门级教程中,我们知道的串口收发都是:接收一个数据,触发中断,然后把数据发回来。这种处理方式是没有缓冲的,当数量太大的时候,亦或者当数据接收太快的时候,我们来不及处理已经收到的数据,那么,当再次收到数据的时候,就会将之前还未处理的数据覆盖掉。那么就会出现丢包的现象了,对我们的程序是一个致命的创伤。
将接受的数据缓存一下,让处理的速度有些许缓冲,使得处理的速度赶得上接收的速度,上面又已经分析了普通队列与环形队列的优劣了,那么我们肯定是用环形队列来进行实现了。下面就是代码的实现:
①定义一个结构体:
typedef struct
{
u16 Head;
u16 Tail;
u16 Lenght;
u8 Ring_Buff[RINGBUFF_LEN];
}RingBuff_t;
RingBuff_t ringBuff;//创建一个ringBuff的缓冲区
void RingBuff_Init(void)
{
//初始化相关信息
ringBuff.Head = 0;
ringBuff.Tail = 0;
ringBuff.Lenght = 0;
}
接收到的数据写入ringBuff
u8 Write_RingBuff(u8 data)
{
if(ringBuff.Lenght >= RINGBUFF_LEN) //判断缓冲区是否已满
{
return FLASE;
}
ringBuff.Ring_Buff[ringBuff.Tail]=data;
//ringBuff.Tail++;
ringBuff.Tail = (ringBuff.Tail+)%RINGBUFF_LEN;//防止越界非法访问
ringBuff.Lenght++;
return TRUE;
}
从ringBuff读数据
u8 Read_RingBuff(u8 *rData)
{
if(ringBuff.Lenght == )//判断非空
{
return FLASE;
}
*rData = ringBuff.Ring_Buff[ringBuff.Head];//先进先出FIFO,从缓冲区头出
//ringBuff.Head++;
ringBuff.Head = (ringBuff.Head+)%RINGBUFF_LEN;//防止越界非法访问
ringBuff.Lenght--;
return TRUE;
}
对于读写操作需要注意的地方有两个:
1:判断队列是否为空或者满,如果空的话,是不允许读取数据的,返回FLASE。如果是满的话,也是不允许写入数据的,避免将已有数据覆盖掉。那么如果处理的速度赶不上接收的速度,可以适当增大缓冲区的大小,用空间换取时间。
2:防止指针越界非法访问,程序有说明,需要使用者对整个缓冲区的大小进行把握。
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
{
USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清楚标志位
Write_RingBuff(USART_ReceiveData(USART1)); //读取接收到的数据
}
}
头文件
#define USER_RINGBUFF 1 //使用环形缓冲区形式接收数据
#if USER_RINGBUFF
/**如果使用环形缓冲形式接收串口数据***/
#define RINGBUFF_LEN 200 //定义最大接收字节数 200
#define FLASE 1
#define TRUE 0
void RingBuff_Init(void);
u8 Write_RingBuff(u8 data);
u8 Read_RingBuff(u8 *rData);
#endif
瑞萨S5D9实现UART环形缓冲的更多相关文章
- 六轴加速度传感器MPU6050官方DMP库到瑞萨RL78/G13的移植
2015年的电赛已经结束了.赛前接到器件清单的时候,看到带防护圈的多旋翼飞行器赫然在列,又给了一个瑞萨RL78/G13的MCU,于是自然联想到13年的电赛,觉得多半是拿RL78/G13做四旋翼的主控, ...
- LPC同STM32的比较
Cortex-M3是新兴起来的一种ARM7的核,而ARM7TDMI是一种传统的经典的ARM内核.我们就抛开这一切,来比较一下两则的异同. 我们就在以下平台上比较吧: STMicoelectronics ...
- 大众车机天宝187A Hack笔记
0×00前言 自从去年买了车,对汽车电子系统的兴趣就上来了.这不,前一阵子逛汽车论坛,发现了有网友将老版本的天宝车机被刷上了2017新帕萨特车机的系统,支持超级蓝牙和苹果CarPlay,百度CarLi ...
- git版本控制管理实践-2
给网站设置一个 "根目录下的logo.ico", 还是很有必要的,比如赶集网,这时在 "历史"搜索时, 就可以根据 网站的 logo.ico 很轻松的就能够找到 ...
- linux arch目录下处理器体系架构介绍
alpha 处理器Alpha 处理器最早由美国DEC 公司设计制造,在Compaq (康柏)公司收购DEC 之后,Alpha 处理器继续得到发展,并且应用于许多高档的Compaq 服务器上,HP (惠 ...
- ARM公布“物联网”嵌入式mbed OS系统软件平台
继ARM公司发布了为嵌入式微控制器设计的Cortex-M7架构处理器,ARM又公布了专为廉价低功耗“物联网”设计的新版软件及系统平台,以加速物联网设备的发展及部署.该软件为基于ARM现有Cortex- ...
- NFC简介
NFC简介 NFC是Near Field Communication缩写,即近距离无线通讯技术.由飞利浦和索尼公司共同开发的NFC是一种非接触式识别和互联技术,可以在移动设备.消费类电子产品.PC 和 ...
- CANoe 入门 Step by step系列(二)CAPL编程【转】
CAPL就是Communication Application Programming Laguage的缩写,CAPL类似于C语言的语法,因此所有的语法请参考C语言教程,这里不在这里进行详述,关于C语 ...
- 这十大MCU厂商瓜分着中国市场
MCU(Micro Control Unit)中文名称为微控制单元,又称单片微型计算机(Single Chip Microcomputer)或者单片机,是指随着大规模集成电路的出现及其发展,将计算机的 ...
随机推荐
- shell 批量计算MD5值
#!/bin/sh #需要计算MD5文件列表 # list=`ls` list="file list" for file in $list do file1=`` echo &qu ...
- ss-libev控制脚本
适用于:shadowsocks-libev-3.0.3 操作系统:CentOS6.8 #!/bin/sh SHADOWSOCKS_SERVER="/usr/local/shadowsocks ...
- scrapy框架简介和基础应用
scrapy框架介绍 环境安装 基础使用 一.什么是Scrapy? Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍.所谓的框架就是一个已经被集成了各种功能(高性 ...
- 【Leetcode】292. Nim Game
problem 292. Nim Game solution class Solution { public: bool canWinNim(int n) { ; } }; 来generalize一下 ...
- sql ''增删改'' 笔记
结构语言分类 DDL(数据定义语言) create drop alter 创建删除以及修改数据库,表,存储过程,触发器,索引.... DML(数据操作语言) insert delete ...
- djang 过滤器和装饰器
Django自定义过滤器 Django 自定义过滤器, 在项目目录中建立templatetags目录. 建立my_filter.py 文件, 导入模板模块 :from django import te ...
- js的数据类型。
字符串 String 数字 Number 布尔 Boolean Null 空 Undefined Object 对象 Array 数组 json function ...
- go build Multiple main.go file
golang 如何编译同目录下多个main文件? 多个go 文件在相同目录编译时候会报错, 可将文件放在不同的package下,结构如下: buidtest/├── a│ └── a.go└── ...
- dive 方便的观察容器各层信息的工具
dive 是一个方便的观察容器各层信息的工具,同时也集成了容器构建命令,方便我们在构建容器 镜像的同时查询镜像各层的变动信息 安装 mac 系统,可以按照自己的系统选择安装方式 wget http ...
- linux之 awk
简介awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进 ...