一、硬件連接
按鍵名稱 | 引腳 | 控制方法 |
---|---|---|
LEFT | 26 | 按下觸發,產生低電平 |
RIGHT | 28 | 按下觸發,產生低電平 |
二、移植文件
注意:以下出現缺失common.h文件錯誤,去除即可。uint8改爲uint8_t或unsigned char或自己宏定義
鏈接:https://pan.baidu.com/s/1cGrkf-KvlWZHsutpHCBecA 提取碼:osrg
將 board_gpi.c 和 board_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 日
• 參考:青風電子社區