一、前言背景
Nordic52810雖然是ARM的框架,但是GPIO的中斷與我們熟悉的STM32外部中斷使用完全不一樣,前面的文章裏LZ有講到過GPIO的結構圖,使能PIN腳的Sense信號檢測後,可觸發GPIOTE模塊的任務與事件
二、應用場景
1. 睡眠模式下的喚醒,使能藍牙協議棧後,使用的是sd_app_evt_wait,可被任意事件中斷喚醒
2. 不跑協議棧的話,可以進入system_off模式(官方提示功耗可在0.5uA)
由於睡眠狀態下,我需要板子能持續進行廣播,所以使用sd_app_evt_wait接口進入系統休眠
三、GPIOTE功能分類
GPIOTE做輸入模塊檢測使用的話,有兩種事件可供配置使用
PIN EVENT事件: 檢測單個引腳電平變化;
優點:響應快,引腳中斷之間互不干擾;
缺點:通道有限,最大支持8個引腳,功耗較高(使用高頻時鐘)
PORT EVENT事件:檢測到任意引腳電平變化,高電平、低電平;觸發DETECT Signal。
優點:通道不受限制,理論上所有引腳都可以配置,功耗低(使用低頻時鐘);
缺點:任意引腳中斷有效時,其他引腳中斷將無法觸發(這個就優點噁心,因爲是電平中斷,這個中斷就會一直保持,無法響應其他中斷)。即任意時刻如果有兩個中斷觸發,其中一個可能就會丟失
四、寄存器
GPIOTE模塊的寄存器並不是很多,主要是配置中斷禁用與使能與引腳的觸發方式
INTENSET:[RW IN0 - IN7]低7位控制PIN事件中斷使能(對應8路引腳) PORT[31] 最高位PORT事件中斷使能
寫1 Enable 使能中斷;
寫0 無效
INTENCLR: 禁用中斷;
同上,寫1 Disable 禁用中斷
CONFIG[0 - 7]:配置寄存器
MODE[0-1] 事件、任務的模式選擇(可讀寫)
PSEL[8-12] 佔用5bit(0 - 31),配置31個引腳關聯到對應的任務或事件(SET CLR OUT 可讀寫)
POLARITY[16-17] 配置級性,輸出模式下可進行引腳 低到高 高到低 翻轉
OUTINIT 任務模式下面引腳初始電平(0 低電平 1高電平)
五、程序實例
配置引腳前需要進行GPIOTE模塊的使能與優先級的配置,考慮到藍牙的功耗至上的原則,下面程序我配置的是PORT EVENT,
按鍵使用的PIN13,低電平觸發
#define BUTTON1_PIN 13
void InitButtonIO(void)
{
//必須先配置GPIOTE模塊
NRFX_IRQ_PRIORITY_SET(GPIOTE_IRQn, NRFX_GPIOTE_CONFIG_IRQ_PRIORITY);
NRFX_IRQ_ENABLE(GPIOTE_IRQn);
nrf_gpiote_event_clear(NRF_GPIOTE_EVENTS_PORT);
nrf_gpiote_int_enable(GPIOTE_INTENSET_PORT_Msk);
//上拉低電平觸發事件
nrf_gpio_cfg_sense_input(BUTTON1_PIN,NRF_GPIO_PIN_PULLUP,NRF_GPIO_PIN_SENSE_LOW);
return;
}
中斷入口的配置
當中斷觸發後,爲了防止一直進中斷,可以根據當前按鍵電平重新配置,這樣就不會一直進中斷了,燒錄代碼後,可見按鍵按下彈起LED燈也跟着進行翻轉
void GPIOTE_IRQHandler(void)
{
nrf_gpiote_event_clear(NRF_GPIOTE_EVENTS_PORT); //清中斷事件//判斷當前按鍵電平,設置觸發電平
if(nrf_gpio_pin_read(BUTTON1_PIN))
nrf_gpio_cfg_sense_set(BUTTON1_PIN, NRF_GPIO_PIN_SENSE_LOW);
else
nrf_gpio_cfg_sense_set(BUTTON1_PIN, NRF_GPIO_PIN_SENSE_HIGH);LedToggle();
}