• [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 }

    历史关联文章

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

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

    @beautifulzzzz 2016-01-01 continue~  

  • 相关阅读:
    Vsftpd 3.0.2 正式版发布
    Putdb WebBuilder 6.5 正式版本发布
    SoaBox 1.1.6 GA 发布,SOA 模拟环境
    pynag 0.4.6 发布,Nagios配置和插件管理
    Percona Playback 0.4,MySQL 负荷回放工具
    xombrero 1.3.1 发布,微型 Web 浏览器
    Hypertable 0.9.6.4 发布,分布式数据库
    libmemcached 1.0.11 发布
    CryptoHeaven 3.7 发布,安全邮件解决方案
    Android Activity生命周期
  • 原文地址:https://www.cnblogs.com/zjutlitao/p/5093082.html
Copyright © 2020-2023  润新知