fifo在嵌入式应用的非常广泛,可以说有数据收发的地方,基本就有fifo的存在,今天给大家分享一款基于c语言实现的fifo模块:xqueue.
1. 为什么需要fifo
fifo 是first-in first-out的缩写,它是一个具有先入先出特点的缓冲区。
可以理解成一个大的水池,水对应数据,注水速度对应数据输入的频率,放水速度对应数据处理的速度,当注水速度和放水速度相同时,我们不需要使用水池来缓冲,但是当注水速度大于放水速度,或者注水速度突然变大时(突发),为了保证水池不溢出(数据不丢失),就需要水池(缓冲区)来处理这种突发情况,并设置合理大小的水池空间(fifo的深度)。
或者为了降低cpu负担,提高数据处理效率,可以在积累到一定的数据量之后,再一次性处理。
在fpga中,fifo一般是使用ram存储器作为缓冲区,可以分为同步fifo或异步fio,一般用于数据缓冲,或者不同时钟域之间的数据传递。
在单片机中,一般是基于一维数组和结构体实现的循环队列(queue),或者叫环形队列。
fifo的使用,既可以保证数据的完整性,还可以让数据被及时的处理。
本文介绍,基于c语言的循环队列缓冲区原理、设计与实现。
2. fifo的存取顺序
定义一个一维数组当作存储区,数组长度为6,再定义两个读写指针变量。
初始化时,fifo为空,读写指针相等,并都置为0。
写入一个数据1之后,写指针递增,读指针不变:
再写两个数据2和3,写指针递增,读指针不变:
写了三个数据之后,我们读出一个数据1,写指针不变,读指针递增:
读出一个数据2,再写两个数据4和5,读写指针变化:
再写一个数据6,此时超过数组长度,但是数组头部还有空间,所以写指针回到数组起始地址0:
再写一个数据7,此时判断fifo满:
可能会有朋友疑惑,不是还有一个空位置可以存放数据吗?
如果再存入一个数据之后,读写指针相等,此时可以判断是满状态吗?
显然是不能,因为当fifo为空时,也是读写指针相等,所以这种情况就无法判断满和空。
这里就涉及到fifo设计中,最重要的满和空的判断条件,需要遵循fifo读写的两个规则:
fifo为空时,不能执行读操作
fifo为满时,不能执行写操作
为了避免这种情况发生,我们空出一个元素位置,写指针指向的位置永远为空,这样就会有两种满的情况:
rd wr
对于第一种情况,当(wr + 1) % fifo_size == rd时,可以认为fifo满,fifo_size是指数组长度;
对于第二种情况,当wr + 1 == rd时,可以认为fifo满。
以上两种情况可以合并为一种,即(wr + 1) % fifo_size == rd时,判断fifo满。
所以这种判断方式,会牺牲一个存储位置,实际可以存储的元素个数为fifo_size-1。
同理,获取当前fifo内元素的个数,也可以分为两种情况:
当wr > rd时, count = wr - rd
当wr < rd时,count = wr + fifo_size - rd
3. fifo的代码实现
根据以上fifo存取逻辑,我们可以使用一维数组来构造一个环形缓冲区,读写地址循环递增,分别实现fifo初始化、读写操作、判断空满、获取元素个数等函数,并封装成模块。
xqueue.h
xqueue.c文件
实际应用:
运行结果:
循环队列元素的数据类型,可以根据需要指定,也可以是结构体类型。
关于大米重金属检测仪的详细参数介绍
事故频发,特斯拉和蔚来后,比亚迪也自燃了......
北京大学深圳研究生院&知存科技联合实验室揭牌,共谋存算一体化研究
应用元件技术升级 提升物联网应用等级
2.4G无线数传模块电路
分享一款基于C语言实现的FIFO模块:xqueue.
专为工业或车载应用的边缘计算而构建的可移动平台
旁路二极管在光伏组件中的作用
关于百度3麦克风阵列智能音箱功能介绍
华为荣耀Note8 VS 努比亚Max,结果意想不到!
cd4518应用电路汇总(引脚图及功能和工作原理)
荣耀和红米带来3款入门设备 荣耀Play5活力版 红米Note11系列来关注下
兽药残留检测仪的工作原理是什么
如何制作渐变RGBLed
如何解决汽车和工业应用中输入供电中断时需要完成数据备份的问题
OLED和量子点终究还是败给了LCD
增强现实的发展卡在哪里了
新基建给智能化行业带来了哪些机遇
汽车排放污染检验中新车排放标准的发展及赶超历程
华为三大基石加速商用之路