:本篇是我翻译并加入自己理解的nRF51 SDK中按钮相关操作的库和先进先出队列库。虽然是nRF51的SDK,但是通过此文你将更多地了解到在BSP(板级支持)上层嵌入式程序或OS的构建方法。

1、按钮相关操作库

  按键管理程序是通过GPIO事务和事件管理程序来检测一个按钮是否被按下的。当然,其中也做了消抖的工作——在GPIOTE事件中启动一个定时器用来延时一段时间,当该定时器失效后如果按钮仍然处于按下状态,则会产生一个按钮事件。如果在延时的过程中又有一个新的GPIOTE,那么这个定时器会重新被启动。此外,在APP_BUTTON_INIT()参数中,使用USE_SCHEDULER参数来决定是否使用scheduler。(关于GPIOTE和SCHEDULER会在下面详细讲)

  app_button模块会用到app_timer模块。用户必须确保app_timer的队列足够大来容纳app_timer_stop()和app_timer_start()操作(注意:这两个操作会在每个GPIOTE事件中执行,所以频度很高!)

ps:即使scheduler没被用,app_button.h也要包含app_scheduler.h!

2、先进先出队列

该队列采用环形缓冲,其大小和缓冲区在初始化的地方配置,如下:

 // Create a FIFO
structureapp_fifo_t my_fifo; // Create a buffer for the FIFO
uint16_t buffer_size = ;
uint8_t buffer[buffer_size]; // Initialize FIFO structure
uint32_t err_code = app_fifo_init(&test_fifo, buffer, (uint16_t)sizeof(buffer));

ps:1.通过app_fifo_init函数,test_fifo会被初始化(其结构体如下)。2.buffer的大小应该是2的倍数。3.一定要确保当FIFO在用的时候,app_fifo_t的缓冲内存不被回收了

 typedef struct{
uint8_t * p_buf; /**< Pointer to FIFO buffer memory. */
uint16_t buf_size_mask; /**< Read/write index mask. Also used for size checking. */
volatile uint32_t read_pos; /**< Next read position in the FIFO buffer. */
volatile uint32_t write_pos; /**< Next write position in the FIFO buffer. */
} app_fifo_t;

这是个环形FIFO队列,p_buf是调用初始化函数中传入的数据池地址,read_pos和write_pos是读地址和写地址~此外,既然是环形FIFO就要用到mod,即:假设环形fifo数据池大小为n,当前写入数据为第x个,则应该写在xmodn位置。这里官方用了个小技巧(如下英语),首先要保证buffer-size是2的倍数,这样xMODn就等于xAND(n-1)。

>>To simplify the index handling, the FIFO is restricted to require the buffer size <n>, to be a power of two, as this reduces the modulus operation to become a simple  AND operation with <n> - 1.

n     = 8 = 0b00001000
n - 1 = 7 = 0b00000111

ANDing any number with <n>-1 , is identical to the modulus operation of <n>, when <n> is a power of two, see below:
3 = 11 mod 8 = 11 AND 7 = 0b00001011 & 0b00000111 = 0b00000011 = 3 .

♠ 若n=8,则初始状态下FIFO为:

♠ 插入一个8位uint8数据则:

 uint8_t data = ;
// Add an element to the FIFO
err_code = app_fifo_put(&my_fifo, data);

上图为插入4个uint8的效果~

♠ 取出一个8位uint8数据的代码为:

 // Consume one element from FIFO
uint8_t return_val;
err_code = app_fifo_get(&my_fifo, &return_val);

下图为取出两个的效果~

♠ Empty Buffer

当read_pos=write_pos时表示buffer是空的。

初始化的时候读写位置都置为0、buffer内的内容被取完或者调用app_fifo_flush。

此时再调用读函数则返回没数据。

♠ Full Buffer

write_pos == read_pos + <n>时表示buffer是满的。

此时再调用写函数则返回没内存。

@beautifulzzzz 2016-01-01 continue~ 

[nRF51822] 3、 新年也来个总结——图解nRF51 SDK中的Button handling library和FIFO library的更多相关文章

  1. [nRF51822] 4、 图解nRF51 SDK中的Schedule handling library 和Timer library

    :nRF51822虽然是一个小型的单片机,但是能真正达到任意调用其官方驱动以及BLE协议栈的人还是奇缺的.据我所见,大都拿官方给的一个冗长的蓝牙低功耗心率计工程改的.之前我对于这个工程进行log跟踪, ...

  2. [nRF51822] 5、 霸屏了——详解nRF51 SDK中的GPIOTE(从GPIO电平变化到产生中断事件的流程详解)

    :由于在大多数情况下GPIO的状态变化都会触发应用程序执行一些动作.为了方便nRF51官方把该流程封装成了GPIOTE,全称:The GPIO Tasks and Events (GPIOTE) . ...

  3. 【读书笔记】关于《精通C#(第6版)》与《C#5.0图解教程》中的一点矛盾的地方

    志铭-2020年2月8日 03:32:03 先说明,这是一个旧问题,很久很久以前大家就讨论了, 哈哈哈,而且先声明这是一个很无聊的问题,

  4. 新年上新!极光认证 Web SDK 首版上线

    新年伊始,极光开发者服务也抢先为各位开发者朋友带来了"新年大礼包",几款明星产品都悉数有不少更新: 极光认证 Web SDK 版本上线 相信不少小伙伴早已熟知极光认证这款产品,3秒 ...

  5. 图解在Eclipse中如何上传项目到svn

    方法/步骤 1.在Eclipse中新建project,如下图所示: 2.右键project --> team --> share project,如下图所示: 3.选择repository ...

  6. Spring Security 实战干货:图解Spring Security中的Servlet过滤器体系

    1. 前言 我在Spring Security 实战干货:内置 Filter 全解析对Spring Security的内置过滤器进行了罗列,但是Spring Security真正的过滤器体系才是我们了 ...

  7. 图解算法——链表中倒数第k个节点

    题目来源: 剑指 Offer 22. 链表中倒数第k个节点 leetCode 题目描述: 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个 ...

  8. [nRF51822] 14、浅谈蓝牙低功耗(BLE)的几种常见的应用场景及架构(科普类干货)

    蓝牙在短距离无线通信领域占据举足轻重的地位—— 从手机.平板.PC到车载设备, 到耳机.游戏手柄.音响.电视, 再到手环.电子秤.智能医疗器械(血糖仪.数字血压计.血气计.数字脉搏/心率监视器.数字体 ...

  9. [编译] 4、在Linux下搭建nRF51822的开发烧写环境(makefile版)

    星期日, 09. 九月 2018 07:51下午 - beautifulzzzz 1.安装步骤 1) 从GNU Arm Embedded Toolchain官网下载最新的gcc-arm工具链,写文章时 ...

随机推荐

  1. IosPush推送通知的实现

    1. Apple推送通知的机制 上图可以分为三个阶段: 第一阶段:应用程序把要发送的消息.目的iPhone的标识打包,发给APNS. 第二阶段:APNS在自身的已注册Push服务的iPhone列表中, ...

  2. char、wchar_t、strlen、wcslen

    第一部分: strlen函数的宽字符版是wcslen(wide-character string length:宽字符串长度),并且在STRING.H(其中也说明了strlen)和WCHAR.H中均有 ...

  3. amr转MP3

    using System; using System.Threading; using System.IO; using System.Diagnostics; using System.Securi ...

  4. 再牛逼的梦想,也抵不住SB似的坚持

    说起梦想,哪都是好几年前的事了.自从毕业之后,梦想不知道去哪了.可能一次次的失败,找不到了梦想的方向了吧! 自从毕业去了深圳,为了能够在这个城市安稳下来,白天正常上班晚上在街上摆地摊给人下载音乐和电影 ...

  5. [转]了解SQL Server锁争用:NOLOCK 和 ROWLOCK 的秘密_Mr_Indigo的空间

    了解SQL Server锁争用:NOLOCK 和 ROWLOCK 的秘密 关系型数据库,如SQL Server,使用锁来避免多用户修改数据时的并发冲突.当一组数据被某个用户锁定时,除非第一个用户结束修 ...

  6. yii 图片展示

    <?= DetailView::widget([ 'model' => $model, 'attributes' => [ 'id', 'name', 'time', 'pic', ...

  7. Linux三剑客之sed

    sed sed对文本的处理很强大,并且sed非常小,参数少,容易掌握,他的操作方式根awk有点像.sed按顺序逐行读取文件.然后,它执行为该行指定的所有操作,并在完成请求的修改之后的内容显示出来,也可 ...

  8. select值的获取及修改

    例子: <select id="a" name="a"> <options value="1">a</opti ...

  9. 【转载】【树形DP】【数学期望】Codeforces Round #362 (Div. 2) D.Puzzles

    期望计算的套路: 1.定义:算出所有测试值的和,除以测试次数. 2.定义:算出所有值出现的概率与其乘积之和. 3.用前一步的期望,加上两者的期望距离,递推出来. 题意: 一个树,dfs遍历子树的顺序是 ...

  10. java时区问题的一个坑

    事情是这样的,前台传过去一个日期字符串,就像2016/12/15 00:00,2016/12/15 23:59类似的格式,但每次从日志平台查日志查询的时间范围都不对,而是提前了一天. 原因是在java ...