[nRF51822] 3、 新年也来个总结——图解nRF51 SDK中的Button handling library和FIFO library
:本篇是我翻译并加入自己理解的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的更多相关文章
- [nRF51822] 4、 图解nRF51 SDK中的Schedule handling library 和Timer library
:nRF51822虽然是一个小型的单片机,但是能真正达到任意调用其官方驱动以及BLE协议栈的人还是奇缺的.据我所见,大都拿官方给的一个冗长的蓝牙低功耗心率计工程改的.之前我对于这个工程进行log跟踪, ...
- [nRF51822] 5、 霸屏了——详解nRF51 SDK中的GPIOTE(从GPIO电平变化到产生中断事件的流程详解)
:由于在大多数情况下GPIO的状态变化都会触发应用程序执行一些动作.为了方便nRF51官方把该流程封装成了GPIOTE,全称:The GPIO Tasks and Events (GPIOTE) . ...
- 【读书笔记】关于《精通C#(第6版)》与《C#5.0图解教程》中的一点矛盾的地方
志铭-2020年2月8日 03:32:03 先说明,这是一个旧问题,很久很久以前大家就讨论了, 哈哈哈,而且先声明这是一个很无聊的问题,
- 新年上新!极光认证 Web SDK 首版上线
新年伊始,极光开发者服务也抢先为各位开发者朋友带来了"新年大礼包",几款明星产品都悉数有不少更新: 极光认证 Web SDK 版本上线 相信不少小伙伴早已熟知极光认证这款产品,3秒 ...
- 图解在Eclipse中如何上传项目到svn
方法/步骤 1.在Eclipse中新建project,如下图所示: 2.右键project --> team --> share project,如下图所示: 3.选择repository ...
- Spring Security 实战干货:图解Spring Security中的Servlet过滤器体系
1. 前言 我在Spring Security 实战干货:内置 Filter 全解析对Spring Security的内置过滤器进行了罗列,但是Spring Security真正的过滤器体系才是我们了 ...
- 图解算法——链表中倒数第k个节点
题目来源: 剑指 Offer 22. 链表中倒数第k个节点 leetCode 题目描述: 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个 ...
- [nRF51822] 14、浅谈蓝牙低功耗(BLE)的几种常见的应用场景及架构(科普类干货)
蓝牙在短距离无线通信领域占据举足轻重的地位—— 从手机.平板.PC到车载设备, 到耳机.游戏手柄.音响.电视, 再到手环.电子秤.智能医疗器械(血糖仪.数字血压计.血气计.数字脉搏/心率监视器.数字体 ...
- [编译] 4、在Linux下搭建nRF51822的开发烧写环境(makefile版)
星期日, 09. 九月 2018 07:51下午 - beautifulzzzz 1.安装步骤 1) 从GNU Arm Embedded Toolchain官网下载最新的gcc-arm工具链,写文章时 ...
随机推荐
- [PHP]OOP两类写法的性能对比
在PHP的OOP中我们有常见两种方法调用,对象调用和静态调用. 下面是一个简单的测试来比较它们的细微差异. /** * 对象初始化 -> 调用:objectCall.php * * 测试调用50 ...
- c# dotfuscator 混淆后无法使用
在实体类中忘记给字段加上 get ;set ;导致编译后程序无法使用. 下面这个(A代码)是可以正常混淆的. public class PhoneUsedStatus { ...
- Java和Ibatis调用存储过程并取得返回值详解
Java和Ibatis调用存储过程并取得返回值详解 2011-07-19 17:33 jiandanfeng2 CSDN博客 字号:T | T 本文主要介绍了Java和Ibatis调用存储过程的方法, ...
- sql sever获取数据库还原时间语句
--只获取数据库名称和最后的还原时间 SELECT sdb.Name AS DatabaseName , ), ), '-') AS LastBackUpTime FROM sys.sysdataba ...
- spring事务源码研读1
转载摘录自:Spring事务源码分析(一)Spring事务入门 有时为了保证一些操作要么都成功,要么都失败,这就需要事务来保证. 传统的jdbc事务如下: @Test public void test ...
- jboss developers studio 快速创建 spring mvc 项目
1. 2. 部署运行 还有一个 rest very good !! ps:其实就是 一个 jboss 的 spring mvc maven 原型
- Hyper-v虚拟机文件VHDX与VHD的格式转换
今天遇到一个坑,我在本机(windows 10)上创建的CentOS虚拟机作为docker的宿主机,部署了gitlab等容器,准备迁移到服务器上的时候,发现始终无法导入,提示必须通过Hyper-v导出 ...
- 【转】Backbone使用总结
转自 http://www.pchou.info/javascript/2014/06/26/backbone-summary-01.html 开始在项目中大规模使用backbone,一路磕磕碰碰, ...
- ASP.Net MVC跳转,分为form的submit提交跳转和ajax跳转
1,用jquery ajax跳转的话,需要在前台用window.location("跳转网址")来跳转,在success后使用 2,用原声的form的submit来跳转,如下图 3 ...
- java中类型转换
1.基本数据类型转换 char, byte,short,int,long,float,double,boolean (1)小类型数据可以直接赋给大类型数据 例:char a=' ...