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 日

• 參考:青風電子社區

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章