基于FIFO的按键检测(1)—FIFO实现

目录

什么是FIFO

FIFO实现方法

数组及管理数组的结构体(找个钱袋子,贴上标签)

关联结构体和数组(贴标签,并写好)

存储数据(存钱)

读取数组(花钱)

总结


什么是FIFO

        FIFO也就是First in, First out。用中文来描述就是先进先出,后进后出,不进不出。FIFO相当于是一个缓冲环节,可以防止数据丢失。

        一般用到不同时域之间的数据传输。比如说单片机按键的速度和CPU去处理按键对应的任务的速度显然是不同的,如果任务非常庞大,可能还没有处理完一个任务,我们已经按了好几次。如果没有FIFO机制,那么后面几次的按键可能都会被忽略,但又不能让CPU去等待按键。所以说可以使用FIFO机制去存储按键事件,等待CPU挨个处理。在单片机的串口也会使用这种方法,挨个发送数据,因为CPU处理的速度显然比串口发送数据的速度高。

FIFO实现方法

        落实到C语言上,FIFO机制归根结底是对数组的管理和读写,主要分为三个部分,数组及管理数组的结构体、读数组、写数组。

数组及管理数组的结构体(找个钱袋子,贴上标签)

        数组的定义比较简单,可以根据自己的需求选择数据类型,应用到按键的话,uint8_t足矣。这一步就好比是确定钱袋子存多大的钱,是1块还是5毛。

/*! fifo缓冲区类型 */
#define FIFO_TYPE uint8_t

        下面就是数组的管理机构,结构体。要想管理一个数组,就需要在结构体里面包括数组的一些信息,就好像标签。如下所示

/**
 *  FIFO结构体
 */
typedef struct
{
	FIFO_TYPE *buff; /* FIFO 缓冲区 */

	uint16_t fifoLen;	/* FIFO 缓冲区有效数据长度 */
	uint16_t fifoSize;	/* 缓冲区大小   */
	uint16_t fifoWrite; /* 缓冲区写指针 */
	uint16_t fifoRead;	/* 缓冲区读指针 */
} fifo_t;

        这里面包括了数组的大部分信息,包括数组的地址、有效数据长度、数组的大小、读写的位置。这一步就好比是确定钱袋子上面的标签该写些什么,有多少钱,最大能存多少,存到哪了,花到哪了。

但上面这些都只是概念,还没有实例化,虚无缥缈。实例化如下

#define Key_Buff_Size 10  //数组大小
fifo_t Key_Fifo;
FIFO_TYPE Key_Buff[Key_Buff_Size];

关联结构体和数组(贴标签,并写好)

        这个时候我们只是定义好了数组和结构体,还没有确定关系,还没把标签贴到钱袋子上面。先把标签写好,刚开始是的时候钱袋子里面可什么都没有,所以初始化的时候所有的数据清零。格式如下

void fifo_init(fifo_t *fifo, FIFO_TYPE *buff, uint16_t size)
{
	fifo->fifoLen = 0;
	fifo->fifoRead = 0;
	fifo->fifoWrite = 0;
	fifo->buff = buff;
	fifo->fifoSize = size;
}

把标签贴上去吧,如下所示

fifo_init(&Key_Fifo, Key_Buff, Key_Buff_Size);

存储数据(存钱)

        想要在数组里面存储数据,首先需要知道存储的数组的地址,存什么。好比是想存多少钱、应该自己存哪个钱袋子,钱袋子已经存了多少,有没有存满,钱肯定得接着之前存的继续往下存,不能重新开一个账户吧。

        所以我们在编写函数的时候,形参就基本确定了,数组的地址,存的数据(存哪个,存多少)。确定好数组之后,第一步就是要检查检查数组有没有满,钱袋子还能不能放。和钱袋子不同的是,这个数组存满了就要从头再存。判断结束后就开始存储到数组里面,然后存储的指针,大于数组大小后归零,相当于是更新标签。具体如下

void fifo_push(fifo_t *fifo, FIFO_TYPE data)
{
	fifo->fifoLen++;

	/* 判断缓冲区是否已满 */
	if (fifo->fifoLen > fifo->fifoSize)
	{
		fifo->fifoLen = fifo->fifoSize;
	}

	fifo->buff[fifo->fifoWrite] = data;

	if (++fifo->fifoWrite >= fifo->fifoSize)
	{
		fifo->fifoWrite = 0;
	}

}

读取数组(花钱)

        不能只存不花吧,存钱就是为了花钱。花钱的步骤和存钱差不多,也要找好花哪个钱袋子,花到哪。

        第一步先判断数组是否为空,要是钱袋子里面本来都没钱怎么花。判断结束后,就要开始更新标签了。有效数据自减,转移数据,有效数据限幅。理解怎么存取数据了之后,就会读取数据了。会花钱就会赚钱,花钱是赚钱的动力。如下所示

void fifo_pop(fifo_t *fifo, FIFO_TYPE *data)
{
	/* 缓冲区为空 */
	if (fifo->fifoLen == 0)
	{
     *data = KEY_NONE;
	}else
	{

			fifo->fifoLen--;

			*data = fifo->buff[fifo->fifoRead];

			if (++fifo->fifoRead >= fifo->fifoSize)
			{
				fifo->fifoRead = 0;
			}
  }
}

总结

        源代码来自网上,作者加以简化,以便于理解。没有添加复杂的功能,可以根据自己需求添砖加瓦。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苦瓜人生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值