Nordic52810入門篇 - IO外部中斷(GPIOTE任務與事件)

一、前言背景

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();
}

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