一、GPIOTE原理
1.概念
1)nRF52832的GPIO只能作爲通用的輸入輸出使能,它作爲輸入時無法產生中斷的,這時候就需要通過GPIOTE實現這種效果了;
2)GPIOTE(GPIO任務和事件),是在GPIO的基礎上引入任務和事件;
3)通過任務和事件來操作IO,任務是針對輸出的,它可以讓IO輸出不同的動作,而事件針對輸入,IO的狀態變化會置位事件寄存器,從而產生事件中斷。
2.原理
1)nRF52832的GPIOTE共有8個通道,每個通道都可以分配給一個引腳,分配的引腳可以配置爲任務模式或事件模式;
2)GPIOTE每個通道都有SET、CLR和OUT任務,其中SET任務讓引腳輸出高電平,CLR任務讓引腳輸出低電平,OUT任務可以通過配置對引腳執行置位、清零和翻轉操作;
3)GPIOTE每個通道的事件都可以配置爲三種輸入狀態:上升沿、下降沿和任意電平跳變;
4)任務和事件通過CONFIG[n](n=0~7)寄存器配置,每個CONFIG[n]寄存器可配置一個對應編號OUT[n](n=0~7)任務寄存器和IN[n]事件寄存器;
5)當通過CONFIG寄存器配置某個引腳由SET、CLR和OUT任務寄存器或IN事件寄存器控制後,該引腳只能被GPIOTE模塊寫操作,正常的GPIO寫入無效;
6)當在同一個GPIOTE通道中同時觸發了有衝突的任務,這些任務的執行級別由高到低依次爲:OUT-->CLR-->SET;
7)GPIOTE除了8個通道外,還包含一個PORT事件,PORT事件是多個引腳通過GPIO DETECT信號產生的事件。
二、GPIOTE寄存器(n=0~7)
1.OUT任務寄存器
OUT[n]:對CONFIG[n].PSEL指定的引腳進行寫操作,引腳動作由CONFIG[n].POLARITY中的配置決定
2.TASKS_SET任務寄存器
TASKS_SET[n]:對CONFIG[n].PSEL指定的引腳進行寫操作,引腳動作爲輸出高電平
3.TASKS_CLR任務寄存器
TASKS_CLR[n]:對CONFIG[n].PSEL指定的引腳進行寫操作,引腳動作爲輸出低電平
4.EVENT_IN事件寄存器
EVENT_IN[n]:CONFIG[n].PSEL指定的引腳產生的事件
5.通用寄存器
1)INTENSET:使能中斷
2)INTENCLR:禁止中斷
3)CONFIG[n]:OUT[n],SET[n],CLR[n]和IN[n]的配置
三、編程分析
sdk版本:nRF5_SDK_15.2.0_9412b96
1.GPIOTE輸出流程
1)初始化GPIOTE模塊
2)初始化GPIOTE輸出引腳
3)是否使能任務模式
2.GPIOTE輸入流程
1)初始化GPIOTE模塊
2)配置引腳爲GPIOTE輸入
3)使能事件模式
3.相關庫函數使用
//頭文件:nrf_drv_gpiote.h
1)ret_code_t nrf_drv_gpiote_init(void)
功能:初始化GPIOTE模塊
2)ret_code_t nrf_drv_gpiote_out_init(nrf_drv_gpiote_pin_t pin,nrf_drv_gpiote_out_config_t const *p_config)
功能:初始化GPIOTE輸出引腳,輸出引腳初始化設置中會設定引腳的動作(低電平到高電平、高電平到低電平或者翻轉狀態)和初始化狀態(高電平或低電平)
3)void nrf_drv_gpiote_out_uninit(nrf_drv_gpiote_pin_t pin)
功能:釋放GPIOTE輸出引腳
4)void nrfx_gpiote_out_task_enable(nrfx_drv_gpiote_pin_t pin)
功能:使能GPIOTE輸出引腳的任務模式
5)void nrfx_gpiote_out_task_disable(nrfx_drv_gpiote_pin_t pin)
功能:禁止GPIOTE輸出引腳的任務模式
6)觸發任務驅動引腳函數
1>nrf_drv_gpiote_set_task_trigger(nrf_drv_gpiote_pin_t pin)
功能:收到觸發GPIOTE SET任務,觸發後,對應的引腳輸出高電平
2>nrf_drv_gpiote_clr_task_trigger(nrf_drv_gpiote_pin_t pin)
功能:收到觸發GPIOTE CLR任務,觸發後,對應的引腳輸出低電平
3>nrf_drv_gpiote_out_task_trigger(nrf_drv_gpiote_pin_t pin)
功能:收到觸發GPIOTE OUT任務,觸發後,對應的引腳輸出狀態翻轉
7)ret_code_t nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t pin,nrf_drv_gpiote_in_config_t const *p_config,nrf_drv_gpiote_evt_handler_t evt_handler)
功能:初始化GPIOTE輸入引腳,
8)void nrfx_gpiote_in_event_enable(nrfx_drv_gpiote_pin_t pin,bool int_enable)
功能:使能GPIOTE輸入引腳
4.代碼編寫
1)GPIOTE輸出流程實例
#include "boards.h"
#include "nrf_delay.h"
#include "nrf_drv_gpiote.h"
int main(void)
{
ret_code_t err_code;
//初始化GPIOTE模塊
err_code = nrf_drv_gpiote_init();
APP_ERROR_CHECK(err_code);
//定義GPIOTE輸出初始化結構體並賦值
nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
//初始化GPIOTE輸出引腳
err_code = nrf_drv_gpiote_out_init(LED_1,&config);
APP_ERROR_CHECK(err_code);
//使能任務模式
nrf_drv_gpiote_out_task_enable(LED_1);
while(true)
{ //觸發任務
nrf_drv_gpiote_out_task_trigger(LED_1);
nrf_delay_ms(150);
}
return 0;
}
2)GPIOTE輸入流程實例
#include "boards.h"
#include "nrf_drv_gpiote.h"
//事件回調函數
void in_pin_handler(nrf_drv_gpiote_pin_t pin,nrf_gpiote_polarity_t action)
{
if (pin == BUTTON_1)
nrf_gpio_pin_toggle(LED_1);
if (action == NRF_GPIOTE_POLARITY_HITOLO)
nrf_gpio_pin_toggle(LED_2);
else if (action == NRF_GPIOTE_POLARITY_LOTOHI)
nrf_gpio_pin_toggle(LED_3);
else if (action == NRF_GPIOTE_POLARITY_TOGGLE)
nrf_gpio_pin_toggle(LED_4);
}
int main(void)
{
ret_code_t err_code;
//初始化開發板上的LED燈
bsp_board_init(BSP_INIT_LEDS);
//初始化GPIOTE模塊
err_code = nrf_drv_gpiote_init();
APP_ERROR_CHECK(err_code);
//配置下降沿產生事件
//nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
//配置上升沿產生事件,false表示
nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(false);//true表示高精度,false表示低精度
//配置任意電平變化產生事件
//nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
//配置引腳爲內部上拉
config.pull = NRF_GPIO_PIN_PULLUP;
//配置引腳爲GPIOTE輸入
err_code = nrf_drv_gpiote_in_init(BUTTON_1,&config,in_pin_handler);
APP_ERROR_CHECK(err_code);
//使能事件模式
nrf_drv_gpiote_in_event_enable(BUTTON_1,true);
while(true)
{
}
return 0;
}