1.首先需要启动低速时钟

NRF_CLOCK->LFCLKSRC            = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
    NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_LFCLKSTART    = 1;

while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
    {
        // Do nothing.
    }

2.初时化函数bsp_init中

m_registered_callback = callback; 这行是注册回调函数,通过参数传入

err_code = bsp_event_to_button_action_assign(num, BSP_BUTTON_ACTION_PUSH, BSP_EVENT_DEFAULT);  这行是分

配默认的事件

err_code = app_button_init((app_button_cfg_t *)app_buttons,   //事件数组
                                       BUTTONS_NUMBER,         //按键个数
                                       APP_TIMER_TICKS(50));    //50ms的TICK时间数

事件数组定义

static const app_button_cfg_t app_buttons[BUTTONS_NUMBER] =
{
    #ifdef BSP_BUTTON_0
    {BSP_BUTTON_0, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_0

#ifdef BSP_BUTTON_1
    {BSP_BUTTON_1, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_1

#ifdef BSP_BUTTON_2
    {BSP_BUTTON_2, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_2

#ifdef BSP_BUTTON_3
    {BSP_BUTTON_3, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_3

#ifdef BSP_BUTTON_4
    {BSP_BUTTON_4, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_4

#ifdef BSP_BUTTON_5
    {BSP_BUTTON_5, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_5

#ifdef BSP_BUTTON_6
    {BSP_BUTTON_6, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_6

#ifdef BSP_BUTTON_7
    {BSP_BUTTON_7, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_7

};

使能APP Button

err_code = app_button_enable();

创建定APP定时器

err_code = app_timer_create(&m_bsp_button_tmr,
                                        APP_TIMER_MODE_SINGLE_SHOT,
                                        button_timer_handler);

3.指定按键与事件关联起来

uint32_t bsp_event_to_button_action_assign(uint32_t button, bsp_button_action_t action, bsp_event_t event)
{
    uint32_t err_code = NRF_SUCCESS;

#if BUTTONS_NUMBER > 0
    if (button < BUTTONS_NUMBER)
    {
        if (event == BSP_EVENT_DEFAULT)
        {
            // Setting default action: BSP_EVENT_KEY_x for PUSH actions, BSP_EVENT_NOTHING for RELEASE and LONG_PUSH actions.
            event = (action == BSP_BUTTON_ACTION_PUSH) ? (bsp_event_t)(BSP_EVENT_KEY_0 + button) : BSP_EVENT_NOTHING;
        }
        switch (action)
        {
            case BSP_BUTTON_ACTION_PUSH:     //按键压下事件指定
                m_events_list[button].push_event = event;
                break;
            case BSP_BUTTON_ACTION_LONG_PUSH:   //按键长按事件指定
                m_events_list[button].long_push_event = event;
                break;
            case BSP_BUTTON_ACTION_RELEASE:     按键释放事件指定
                m_events_list[button].release_event = event;
                break;
            default:
                err_code = NRF_ERROR_INVALID_PARAM;
                break;
        }
    }
    else
    {
        err_code = NRF_ERROR_INVALID_PARAM;
    }
#else
    err_code = NRF_ERROR_INVALID_PARAM;
#endif // BUTTONS_NUMBER > 0

return err_code;
}

4.app_button_init函数

err_code = nrf_drv_gpiote_init(); //初时化GPIOTE

err_code = nrf_drv_gpiote_in_init(p_btn->pin_no, &config, gpiote_event_handler); //GPIOTE IN事件设置

app_timer_create(&m_detection_delay_timer_id,
                            APP_TIMER_MODE_SINGLE_SHOT,
                            detection_delay_timeout_handler); //创建按键检测定时器

5.static void gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)由GPIOTE事件回调,回调中会启动

定时器一次err_code = app_timer_start(m_detection_delay_timer_id, m_detection_delay, NULL);

6.定时时间到会回调static void detection_delay_timeout_handler(void * p_context)函数一次,回调中由以下发出通知,即调用到

app_buttons数组中定义的函数bsp_button_event_handler

p_btn->button_handler(p_btn->pin_no, transition);

7.static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action)回调函数

static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action)
{
    bsp_event_t        event  = BSP_EVENT_NOTHING;
    uint32_t           button = 0;
    uint32_t           err_code;
    static uint8_t     current_long_push_pin_no;              /**< Pin number of a currently pushed button, that could become a long push if held long enough. */
    static bsp_event_t release_event_at_push[BUTTONS_NUMBER]; /**< Array of what the release event of each button was last time it was pushed, so that no release event is sent if the event was bound after the push of the button. */

button = bsp_board_pin_to_button_idx(pin_no);  //得到按键在数组中的序号

if (button < BUTTONS_NUMBER)
    {
        switch (button_action)
        {
            case APP_BUTTON_PUSH:    //按键按下事件
                event = m_events_list[button].push_event;
                if (m_events_list[button].long_push_event != BSP_EVENT_NOTHING) //如果定义了长按键
                {
                    err_code = app_timer_start(m_bsp_button_tmr, APP_TIMER_TICKS(BSP_LONG_PUSH_TIMEOUT_MS), (void*)&current_long_push_pin_no);  //启动长按键定时器
                    if (err_code == NRF_SUCCESS)
                    {
                        current_long_push_pin_no = pin_no;
                    }
                }
                release_event_at_push[button] = m_events_list[button].release_event;
                break;
            case APP_BUTTON_RELEASE:  //按键释放
                (void)app_timer_stop(m_bsp_button_tmr);
                if (release_event_at_push[button] == m_events_list[button].release_event)
                {
                    event = m_events_list[button].release_event;
                }
                break;
            case BSP_BUTTON_ACTION_LONG_PUSH:   //长按键事件,由长按键定时器调用进入
                event = m_events_list[button].long_push_event;
        }
    }

if ((event != BSP_EVENT_NOTHING) && (m_registered_callback != NULL))
    {
        m_registered_callback(event);   //回调到注册的按键事件函数
    }
}

8.长按定时器回调函数,此函数在bsp_init中设置过

static void button_timer_handler(void * p_context)
{
    bsp_button_event_handler(*(uint8_t *)p_context, BSP_BUTTON_ACTION_LONG_PUSH);  //调用按键事件函数
}

9.回调到使用者注册的按键事件函数,注册由bsp_init实现

m_registered_callback(event);

10. 使用者自定义bsp_evt_handler按键事件注册

err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_evt_handler);

11.void bsp_evt_handler(bsp_event_t evt)函数

void bsp_evt_handler(bsp_event_t evt)
{
    uint32_t err_code;
    switch (evt)
    {
        case BSP_EVENT_KEY_0:        //此事件值可由bsp_event_to_button_action_assign函数指定
            break;

case BSP_EVENT_KEY_1:   //此事件值可由bsp_event_to_button_action_assign函数指定
            break;

default:
            return; // no implementation needed
    }
    
}

总结按键事件传递流程:

按键产生GPIOTE事件->回调gpiote_event_handler函数,启动一次性定时器(50ms,可设置)->定时器事件回调函数,调用

p_btn->button_handler(p_btn->pin_no, transition)去通知数组中定义的回调函数->bsp_button_event_handler处理按键按下,释放等事件,由m_registered_callback(event)调用将事件回调->最终调用到bsp_evt_handler函数

长按事件先由按键按下事件,启动一个长按键定时器(约1秒,可设置)->定时器时间到,回调button_timer_handler函数,此函数再直接调用bsp_button_event_handler函数->长按事件由m_registered_callback(event)调用将事件回调->最终调用到bsp_evt_handler函数

NRF52832 BSP使用分析相关推荐

  1. bsp的分析(其中使用buildroot文件夹建立rootfs)

    以下内容源于朱有鹏嵌入式课程的学习,如有侵权,请告知删除. 一.X210的bsp介绍 1.嵌入式linux产品的bsp介绍 ARM+linux形式的bsp,内容和结构都是相似的. bsp由芯片厂家或板 ...

  2. access2013数据库实验笔记_医学科研实验基础知识笔记(十):甲基化

    往期回顾 医学科研实验基础知识笔记(一):细胞增殖 医学科研实验基础知识笔记(二):细胞凋亡检测 医学科研实验基础知识笔记(三):细胞周期检测 医学科研实验基础知识笔记(四):细胞自噬研究策略 医学科 ...

  3. DM365的BSP源码分析-基于2.6.18内核

    DM365的BSP主要包含mach-davinci和plat-davinci两个目录(及相关头文件),BSP复杂庞大又极其重要,它主要完成了板级的初始化,比如内存映射,时钟和电源初始化,中断和IO初始 ...

  4. BSP板机支持包、linux启动分析、ARM裸机编程

    文章目录 一.BSP 二.驱动 驱动的基本要素 三.启动分析 1.uboot 2.uboot的作用 3.uboot相关命令 关键的内容: 1)bootargs,启动参数 2)启动命令 3)修改启动延时 ...

  5. 2440 wince 5.0 BSP之flash驱动分析

    作者:wogoyixikexie@gliet 这几天,使用立宇泰2440 开发板光盘的BSP放到手持机上,运行是没有问题了,但是却发现不了盘符.后来看串口打印信息,原来是页大小根本没有识别出来,本来是 ...

  6. 从零开始的nrf52832蓝牙开发--蓝牙BLE主函数分析

    关注.星标公众号,直达精彩内容 来源:https://blog.csdn.net/solar_Lan/article/details/88964043 工程目录中大部分文件都是官方 SDK 库中提供好 ...

  7. nrf52832 学习笔记(二)SDK框架分析

    nrf52832 学习笔记(二)SDK框架分析 个人对SDK框架的一些理解,如有错误欢迎斧正. flash 分区 在不包含DFU的情况下,nrf52832 flash划分为: MBR 0x000000 ...

  8. 如何自行分析定位SAP BSP错误

    The "BSP tag" I mentioned in the blog title means for example the tag chtmlb:configCellera ...

  9. 部署在SAP ABAP服务器上的SAP UI5应用,从bsp redirect(重定向)到ui5_ui5的原因分析

    Created by Jerry Wang on Aug 04, 2014 在浏览器中访问https:///sap/bc/bsp/sap/mymap/webcontent/index.html?sap ...

最新文章

  1. Core Graphics
  2. YJX_rxjh_10_2.5.2
  3. matlab 动态库 二次调用,LINUX matlab编译动态库调用崩溃
  4. python绘制3d坐标轴_matplotlib在python上绘制3D散点图实例详解
  5. HTML textarea控件
  6. Java取得操作系统的临时目录
  7. 苹果笔记本电脑好用吗_苹果这些让人超疑惑的配件,价格超贵而且真的好用吗?...
  8. 文末资源 | 官宣:GitHub私有仓库免费啦!--说微软收购GitHub是坏事的你站出来!...
  9. C++ 编译器生成默认构造函数的四种情况
  10. hadoop安装流程
  11. Tensor for argument #2 ‘mat1‘ is on CPU, but expected it to be on GPU (while checking arguments for
  12. 不同速度流体的剪切形成不同尺度的漩涡,看起来很像分形。
  13. Android手机电池耐用吗,手机电池是否还耐用?一招教你识别
  14. 获取淘宝商品分类详情API,抓取淘宝全品类目API接口分享(代码展示、参数说明)
  15. Android源码学习------SystemUI(二)
  16. 动态IP代理芝麻软件现在覆盖这些城市
  17. matlab模拟风场竖桥向时程,大跨度桥梁三维脉动风场的计算机模拟
  18. K8s安全管理:认证、授权、准入控制
  19. A Game of Thrones(84)
  20. 用微博帐号登录出错了! 对第三方应用进行授权时出现错误,请您联系第三方应用的开发者: 十五发芽或者稍后再试。 错误码:21322 重定向地址不匹配

热门文章

  1. python学习——如何求最大公约数
  2. C语言 itoa函数及atoi函数
  3. 0基础入行学习软件测试有哪些要求?往往只有这3点
  4. HPUoj1210: OY问题 [搜索](DFS
  5. 理解逻辑斯蒂回归模型
  6. NLTK01 《NLTK基础教程--用NLTK和Python库构建机器学习应用》
  7. Spark 写入 MySQL 乱码问题
  8. 子网掩码和IP地址的关系
  9. 100内奇数之和流程图_2019版路基工程清包工参考价+19种路基常用施工流程图
  10. 计算Grassmannian geodesic