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

简介:


 

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

 

 

从GPIO电平变化到产生中断事件的流程详解 

 

 1、GPIOTE概览

  nRF51上面有32个GPIO,由于在大多数情况下GPIO的状态变化都会触发应用程序执行一些动作。为了方便nRF51官方把该流程封装成了GPIOTE,全称:The GPIO Tasks and Events (GPIOTE) 。GPIOTE提供使用任务和事件访问GPIO引脚功能。此外,用这个lib你可以把让多个模块共用一个相同的GPIOTE中断,当GPIOTE发生中断,其中断处理程序会确定是那个引脚,并将该事件通知对应的模块。

            图:Users are being notified of a pin transition event(user表示各个模块)

 

GPIOTE的users必须配置相应的引脚,除非用在SENSE用途(在该用途下引脚应该被配置为GPIO_PIN_CNF_SENSE_Disabled)

模块需要指定那个引脚在何种电平变换下产生中断事件(电平变换类型——由低到高,由高变低,both)

Note

  尽管应用使用了Scheduler,但是GPTOTE的事件句柄还是直接来自GPTOTE中断句柄。

 

2、初始化GPIOTE模块

  初始化之前不能使用该模块的API,再次建议使用APP_GPIOTE_INIT代替app_gpiote_initIt来进行初始化,因为前者负责为每个user保留所需的内存(MAX_USERS指明最多需要多少分users,即多少个模块将注册并使用GPIOTE模块)

1 // Macro to initialize GPIOTE module and reserving necessary memory for each of user.
2 APP_GPIOTE_INIT(MAX_USERS);

note

  初始化只能一次!!!

 

3、GPIOTE的寄存器

  每个user必须注册自己以使自己在GPIO状态变化时被通知到。在注册时,user必须提供回调处理程序,以通知一个转换事件,以及自己感兴趣的引脚的转换方式。下图32位的bitmask是用来代表32GPIO引脚的。user能够将感兴趣事件注册为引脚由低到高或由高到低变化。

图:GPIO Pin representation using 32-bit bitmask 

 

  在注册成功时user被指派一个user id,user需要记下该id为后续向GPIOTE模块发请求提供唯一识别。该唯一识别是函数的一个输出参数p_user_id,如下:

复制代码
 1 // GPIOTE user identifier for the example module.
 2 static app_gpiote_user_id_t   m_example_user_id;// GPIOTE event handler.
 3 static void example_gpiote_event_handler(uint32_t event_pins_low_to_high, uint32_t event_pins_high_to_low);
 4 .
 5 .
 6 .
 7 uint32_t  low_to_high_bitmask = 0x0000000F; // Bitmask to be notified of transition from low to high for GPIO 0-3
 8 uint32_t  high_to_low_bitmask = 0x0000000E; // Bitmask to be notified of transition from high to low for GPIO 0-2
 9 uint32_t retval;retval = app_gpiote_user_register(&m_example_user_id,
10                                                   low_to_high_bitmask,
11                                                   high_to_low_bitmask, 
12                                                   example_gpiote_event_handler);
13                                                    
14 if (retval != NRF_SUCCESS){    
15     // Failed to register with user with GPIO module!
16 }
17 
18 .
19 .
20 .
复制代码

ps:默认情况下,初始化之后GPIOTE是失能的。因此,必须有一个user调用app_gpiote_user_enable来使能GPIOTE。

  

下面是一个用户注册的引脚状态变化事件的回调函数:

复制代码
 1 // GPIOTE event handler.
 2 void example_gpiote_event_handler (uint32_t event_pins_low_to_high, uint32_t event_pins_high_to_low)
 3 {    
 4     .    
 5     .    
 6     .    
 7     if (event_pins_low_to_high & 0x00000001)    
 8     {        
 9         // GPIO pin 0 transitioned from low to high.         
10         // Take necessary action.    
11     }    
12     if (event_pins_high_to_low & 0x00000004)    
13     {         
14         // GPIO pin 2 transitioned from high to low.         
15         // Take necessary action.    
16     } 
17     
18     .    
19     .    
20     .
21 }
复制代码

 

4、Enable/Disable GPIOTE

  一个注册过的user能够在任何时间失能或使能GPIOTE模块。当GPIOTE失能时事件将不能被接收,初始化之后GPIOTE默认是失能的。下面例子展示失能或使能GPIOTE模块:

复制代码
 1 uint32_t retval;
 2 
 3 // Enable notifications for example user module which is already registered.
 4 retval = app_gpiote_user_disable(m_example_user_id);
 5 if (retval != NRF_SUCCESS)
 6 {    
 7     // Enabling notifications failed. Take corrective/needed action.    
 8     .
 9     .
10 } 
11 
12  . 
13  . 
14  .
15 // Enable notifications for example user module which is already registered.
16 retval = app_gpiote_user_enable(m_example_user_id);
17 if (retval != NRF_SUCCESS)
18 {    
19     // Enabling notifications failed. Take corrective/needed action.    
20     .    
21     .
22 }
复制代码

 

5、Reading GPIOTE State

  一个注册过的user能够通过读取状态信息获取GPIOs的当前状态。

复制代码
 1 uint32_t retval;
 2 uint32_t gpio_pin_state;
 3 
 4 retval = app_gpiote_pins_state_get(m_example_user_id,&gpio_pin_state);
 5 if (retval != NRF_SUCCESS)
 6 {    
 7     // Failed to read state information. Take corrective action.
 8 }else{
 9     .    
10     .    
11     if (gpio_pins_state & 0x00000006) // Checks if pin one and two are set    
12     {        
13         // Take necessary action    
14     }    
15     .    
16     .
17 }
复制代码


相关文章
|
机器人 开发工具
阿里云RPA(机器人流程自动化)干货系列之十二:创建自定义SDK函数
导读:本文是阿里云RPA(机器人流程自动化)干货系列之十二,上篇介绍了采用编码模式开发了一个简单的RPA应用,如果自带的SDK函数不满足开发需求的话可以自行创建一个,本篇就介绍如何创建一个自定义SDK函数。 1)打开Studio客户端,点击”新建编码模式应用”,在弹出来的对话框中选择“自定义SDK” 2)编写一段应用代码,我们就直接打印一
6658 0
|
5天前
|
JavaScript Java Maven
云效产品使用常见问题之android sdk 构建出aar后,上传到私有maven仓库失败如何解决
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
3月前
|
安全 开发工具 Android开发
几个Flutter常见诊断错误与解决Android toolchain - develop for Android devices X Unable to locate Android SDK
几个Flutter常见诊断错误与解决Android toolchain - develop for Android devices X Unable to locate Android SDK
287 0
|
6月前
|
API 开发工具 Android开发
解决 Android App 上架 Google play后 ,签名变更,第三方sdk无法登录
解决 Android App 上架 Google play后 ,签名变更,第三方sdk无法登录
148 0
|
Java 语音技术 开发工具
Android 讯飞离线语音听写/离线语音识别SDK
Android 讯飞离线语音听写/离线语音识别SDK
391 0
Android 讯飞离线语音听写/离线语音识别SDK
|
3月前
|
开发工具 Android开发
Android获取SDK的版本信息
Android获取SDK的版本信息
39 0
|
4月前
|
编解码 Java 开发工具
Android端接入视频生产 Java SDK
Android端接入视频生产 Java SDK
40 1
|
8月前
|
Java 开发工具 Android开发
逻辑清晰,详解社交源码Android开发SDK
前篇我们讲解了有关如何在IOS平台开发集成SDK,那么今天来给大家简单讲解下如何在社交源码Android客户端上开发集成 SDK。
逻辑清晰,详解社交源码Android开发SDK
|
8月前
|
Java 开发工具 Android开发
Android Studio (Android SDK) 配置与使用
Android Studio (Android SDK) 配置与使用
1050 0