:本篇是我翻译并加入自己理解的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. 先学习下一些基础的js和xpath语法

    这两个方法到底是在做什么呢?其实就是克隆了当前指令的节点,并生成子作用域.克隆的节点由transclude定义,如果你的属性是true,则克隆的是指令模板中的ng-transclude所在的DOM节点 ...

  2. hdu 1342(DFS)

    Lotto Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  3. Mac电脑配置IOS React Native开发环境配置笔记

    React Native(以下简称RN)的开发环境配置直接参考官方文档即可完成,不过对小白来说东西有点多,有些名词不是很好理解,这里就官方的安装文档稍微展开说一下. 中文版配置说明:不错的中文说明.官 ...

  4. Python回调函数用法实例详解

    本文实例讲述了Python回调函数用法.分享给大家供大家参考.具体分析如下: 一.百度百科上对回调函数的解释: 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函 ...

  5. 使用<c:if>标签处理页面数据

    使用${feeList.feeType}来取值的时候,因为定义的是数值,刚好看到<c:if>标签的使用,套用代码如下 <td> <c:if test="${fe ...

  6. Java数组与vector互转

    Java数组与vector互转 /* Object[] object1 = null ; //数组定义 Vector<Object> object2;//Vector定义 object2 ...

  7. Delphi 版 MIB_IF_ROW2

    unit netioapi; interface uses Windows; type {$Z4} NDIS_MEDIUM = ( NdisMedium802_3, NdisMedium802_5, ...

  8. HttpServletRequest的Attribute和Parameter区别

    HttpServletRequest类既有getAttribute()方法,也由getParameter()方法,这两个方法有以下的组件通过getParameter()方法来获得请求参数,例如假定we ...

  9. Lua与C++互相调用(上)

    int main1(int argc, const char * argv[]) { lua_State* L = luaL_newstate();//创建栈 luaopen_base(L); lua ...

  10. Linux网卡bounding详解

    多块网卡绑在一起,作为一个网卡用,实现负载均衡和提高带宽   linux双网卡绑定一个IP地址,实质工作就是使用两块网卡虚拟为一块,使用同一个IP地址,是我们能够得到更好的更快的服务.其实这项技术在 ...