nRF52832開發之GPIOTE淺析

一、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;
}

 

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