NRF52832学习笔记(4)——GPIO输入中断接口使用

一、硬件连接

按键名称 引脚 控制方法
LEFT 26 按下触发,产生低电平
RIGHT 28 按下触发,产生低电平

二、移植文件

注意:以下出现缺失common.h文件错误,去除即可。uint8改为uint8_t或unsigned char或自己宏定义
链接:https://pan.baidu.com/s/1cGrkf-KvlWZHsutpHCBecA 提取码:osrg
board_gpi.cboard_gpi.h 两个文件加入工程的Application文件夹下


2.1 board_gpi.h

#ifndef _BOARD_GPI_H_
#define _BOARD_GPI_H_

/*********************************************************************
 * INCLUDES
 */
#include "common.h"

/*********************************************************************
 * DEFINITIONS
 */
#define KEY_IRQ_ON              0
#define KEY_IRQ_OFF             1

#define KEY_LEFT_VALUE          0x01                // 中断值
#define KEY_RIGHT_VALUE         0x02

#define KEY_LEFT_IO             26                  // 左键
#define KEY_RIGHT_IO            28                  // 右键

#ifndef IRQ_DEBOUNCE_TIMEOUT
#define IRQ_DEBOUNCE_TIMEOUT            APP_TIMER_TICKS(20) // 超时时间(20ms)
#endif

/*********************************************************************
 * API FUNCTIONS
 */
void Board_KeyInit(void);
uint8 Board_GetKeyStatus(void);

#endif /* _BOARD_GPI_H_ */

2.2 board_gpi.c

/*********************************************************************
 * INCLUDES
 */
#include "nrf_drv_gpiote.h"
#include "app_timer.h" 
#include "app_error.h"

#include "board_gpi.h"

static void irqCallbackFunc(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action);
static void timer_irqDebounceCallback(void *arg);

/*********************************************************************
 * LOCAL VARIABLES
 */
APP_TIMER_DEF(s_irqDebounceTimer);                                                      // 中断消抖的定时器
static uint8 s_irqValue;                                                                // 中断值

/*********************************************************************
 * PUBLIC FUNCTIONS
 */
/**
 @brief 按键中断初始化函数
 @param 无
 @return 无
*/
void Board_KeyInit(void)
{
    ret_code_t errCode = nrf_drv_gpiote_init();                                         // GPIOE驱动初始化,如有其它GPIO中断只调用一次
    APP_ERROR_CHECK(errCode);
    
    nrf_drv_gpiote_in_config_t inConfig = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);         // 双边沿中断触发
    inConfig.pull = NRF_GPIO_PIN_PULLUP;                                                // 默认上拉
    inConfig.sense = NRF_GPIOTE_POLARITY_TOGGLE;
    
    errCode = nrf_drv_gpiote_in_init(KEY_LEFT_IO, &inConfig, irqCallbackFunc);
    errCode = nrf_drv_gpiote_in_init(KEY_RIGHT_IO, &inConfig, irqCallbackFunc);
    APP_ERROR_CHECK(errCode);
    nrf_drv_gpiote_in_event_enable(KEY_LEFT_IO, true);                  
    nrf_drv_gpiote_in_event_enable(KEY_RIGHT_IO, true); 

    app_timer_create(&s_irqDebounceTimer, APP_TIMER_MODE_SINGLE_SHOT, timer_irqDebounceCallback);
}

/**
 @brief 获取按键状态
 @param 无
 @return 1 - 伸出;0 - 缩进
*/
uint8 Board_GetKeyStatus(void)
{
    return nrf_gpio_pin_read(LOCK_SWITCH_IRQ_IO);
}


/*********************************************************************
 * LOCAL FUNCTIONS
 */
/**
 @brief IRQ中断回调函数
 @param pin -[in] 引脚
 @param action -[in] 动作
 @return 无
*/
static void irqCallbackFunc(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    s_irqValue = 0;                                                                     // 清除中断值

    if(nrf_gpio_pin_read(KEY_LEFT_IO) == KEY_IRQ_ON)                                    // 判断按键是否按下
    {
        s_irqValue |= KEY_LEFT_VALUE;                                                   // 保存中断值
    }
    
    if(nrf_gpio_pin_read(KEY_RIGHT_IO) == KEY_IRQ_ON)
    {
        s_irqValue |= KEY_RIGHT_VALUE;
    }

    app_timer_start(s_irqDebounceTimer, IRQ_DEBOUNCE_TIMEOUT, NULL);                    // 启动中断消抖的定时器
}

/**
 @brief IRQ中断消抖定时器的回调函数
 @param 无
 @return 无
*/
static void timer_irqDebounceCallback(void *arg)
{
    UNUSED_PARAMETER(arg);
    
    // 消抖
    if(nrf_gpio_pin_read(KEY_LEFT_IO) == KEY_IRQ_ON)                                    // 判断按键是否按下
    {
        s_irqValue |= KEY_LEFT_VALUE;                                                   // 保存中断值
    }
    if(nrf_gpio_pin_read(KEY_RIGHT_IO) == KEY_IRQ_ON)
    {
        s_irqValue |= KEY_RIGHT_VALUE;
    }
    
    if(irqValue & KEY_LEFT_VALUE)
    {
        // 应用程序
    }
    else if(irqValue & KEY_RIGHT_VALUE)
    {
        // 应用程序
    }
}

/****************************************************END OF FILE****************************************************/

三、API调用

需包含头文件 board_gpi.h

Board_KeyInit

功能 初始化按键引脚
函数定义 void Board_KeyInit(void)
参数
返回

四、SDK配置

点击 sdk_config.h 文件


选择 Configuration Wizard

nRF_Drivers 中勾选GPIOE相关选项

五、使用例子

如SDK15.3 中 ble_peripheral 的 ble_app_template 工程
main.c 中的 main 函数中

int main(void)
{
    bool erase_bonds;

    /*-------------------------- 外设驱动初始化 ---------------------------*/
    // Initialize.
    log_init();                                                                 // 日志驱动初始化                                                                  
    timers_init();                                                              // 定时器驱动初始化(在此加入自定义定时器)
    
    Board_KeyInit();                                                         // 按键中断驱动初始化                                                   
    
    /*-------------------------- 蓝牙协议栈初始化 ---------------------------*/
    power_management_init();
    ble_stack_init();                                                           // 协议栈初始化
    gap_params_init();
    gatt_init();
    advertising_init();                                                         // 广播初始化
    services_init();                                                            // 服务初始化
    conn_params_init();                                                         // 连接参数初始化
    peer_manager_init();
    
    /*-------------------------- 开启应用 ---------------------------*/
    // Start execution.
    NRF_LOG_INFO("Template example started."); 
    advertising_start(erase_bonds);                                             // 开启广播 
    application_timers_start();                                                 // 定时器应用开启(在此开启自定义定时器)  
    
    // Enter main loop.
    for(;;)
    {
        idle_state_handle();
    }
}

一旦产生中断则,经过消抖后,进入回调函数 timer_irqDebounceCallback()


• 由 Leung 写于 2019 年 12 月 21 日

• 参考:青风电子社区

你可能感兴趣的:(NRF52832学习笔记(4)——GPIO输入中断接口使用)