nRF52832-GPIOTE部分

GPIOTE部分学习思维导图

GPIOTE原理

1.1nRF52832寄存器类型

Task:任务寄存器,可以由程序或事件触发
Event:事件寄存器,事件可以产生中断和触发任务
Register:普通寄存器,和一般单片机的寄存器一样

1.2GPIOTE功能

GPIOTE每个通道可以使用的Task有三个
置位,清除,翻转
GPIOTE每个同奥的事件可以由以下的输入状态产生
上升沿,下降沿,任意电平跳变

1.3引脚Tasks和Events

1.4PORT事件

1.5相关寄存器

GPIOTE驱动库的使用

2.1任务/事件通道的分配

用于驱动引脚输出的GPIOTE任务或者用于在输入引脚电平变换时产生事件的
任务/事件通道数量时受限制的,驱动程序会管理这些通道,用户是决定不了哪个通道的,
也就是说通道分配由驱动程序完成,用户不能指定使用哪一个具体的通道。

2.2重要的API函数

函数功能:初始化GPIOTE通道
ret_code_t nrf_drv_gpiote_init	(	void 		)
函数功能:初始化GPIOTE输出引脚
ret_code_t nrf_drv_gpiote_out_init	(	
    nrf_drv_gpiote_pin_t 	pin,  //初始化引脚
    nrf_drv_gpiote_out_config_t const * 	p_config   //初始化结构体
)
nrf_drv_gpiote_out_config_t要包含以下三项内容
1)引脚的初始状态:高电平还是低电平
2)引脚动作:任务触发后引脚执行的动作,包括置位,清除和翻转
3)是否为GPIOTE引脚
函数功能:使能任务触发
void nrf_drv_gpiote_out_task_enable	(	nrf_drv_gpiote_pin_t 	pin	)	

2.3应用步骤

2.3.1GPIOTE输出应用步骤

注意:GPIOTE一般和PPI一起用,否则体现不了GPIOTE的优势
(1)初始化GPIOTE模块(在一个程序中GPIOTE只能初始化一次)
(2)初始化GPIOTE输出引脚
(3)是否使能任务触发,虽然使用的GPIOTE模块,但是仍可设置是任务
触发还是写GPIO寄存器,若使能了任务触发,则触发任务驱动引脚,否则写GPIO寄存器驱动引脚
(4)使能任务触发

2.3.2GPIOTE输入应用步骤

(1)初始化GPIOTE模块
(2)配置引脚为GPIO输入

ret_code_t nrf_drv_gpiote_in_init	(	
    nrf_drv_gpiote_pin_t 	pin,  //初始化的引脚
    nrf_drv_gpiote_in_config_t const * 	p_config,  //GPIOTE输入初始化结构体
    nrf_drv_gpiote_evt_handler_t 	evt_handler   //User function to be called when the configured transition occurs.
)

GPIOTE初始化结构体包括4项内容
1)Sense 配置引脚的Sense功能
高电平到低电平的变化产生事件
低电平到高电平的变化产生事件
任意电平变化产生事件
2)is_watcher 是否连接输入缓冲器
3)pull 是否开启上拉电阻
4)hi_accuracy 是否为高精度模式
(3)使能该引脚所在GPIOTE通道的事件模式

void nrf_drv_gpiote_in_event_enable	(	
    nrf_drv_gpiote_pin_t 	pin,
    bool 	int_enable   //True to enable the interrupt. Always valid for a high-accuracy pin
)

DEMO

包括PPI和GPIOTE两部分的应用

#include <stdint.h>
#include "nrf_drv_gpiote.h"
#include "app_error.h"
#include "nrf_drv_ppi.h"

//定义引脚
#define LED_2       18
#define BUTTON_0    16
//定义nrf_ppi_channel_t变量,用来保存PPI的信息
nrf_ppi_channel_t my_ppi_channel;

//初始化PPI
void PPI_Config()
{
	uint32_t err_code = NRF_SUCCESS;
	
	//1 初始化PPI
	err_code=nrf_drv_ppi_init(); 
	APP_ERROR_CHECK(err_code);
	//2 分配PPI通道
	err_code=nrf_drv_ppi_channel_alloc(&my_ppi_channel);
	APP_ERROR_CHECK(err_code);
	//3 配置PPI通道的EEP和TEP
	err_code=nrf_drv_ppi_channel_assign(my_ppi_channel,
	                           nrf_drv_gpiote_in_event_addr_get(BUTTON_0),
	                           nrf_drv_gpiote_out_task_addr_get(LED_2));
	APP_ERROR_CHECK(err_code);
	
	//4 使能PPI通道
	err_code=nrf_drv_ppi_channel_enable(my_ppi_channel);
    APP_ERROR_CHECK(err_code);
}
//初始化GPIOTE
void GPIOTE_Config()
{
	ret_code_t err_code;	
	//LED初始化为输出引脚
	err_code=nrf_drv_gpiote_init();
	APP_ERROR_CHECK(err_code);
	//配置结构体
	nrf_drv_gpiote_out_config_t led_config=GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
	err_code=nrf_drv_gpiote_out_init(LED_2,&led_config);
	APP_ERROR_CHECK(err_code);
	//使能任务触发
	nrf_drv_gpiote_out_task_enable(LED_2);
	
	
	//BUTTON初始化为输入引脚
	nrf_drv_gpiote_in_config_t button_config=GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
	button_config.pull=NRF_GPIO_PIN_PULLUP;  //开启上拉电阻
	err_code=nrf_drv_gpiote_in_init(BUTTON_0,&button_config,NULL);
	APP_ERROR_CHECK(err_code);
	nrf_drv_gpiote_in_event_enable(BUTTON_0,true);
}
/**********************************************************************************************
 * 描  述 : main函数
 * 入  参 : 无
 * 返回值 : 无
 ***********************************************************************************************/ 
int main(void)
{
	//初始化GPIOTE
	GPIOTE_Config();
	//初始化PPI
	PPI_Config();  //一定要先初始化GPIOTE,然后进行PPI的初始化
        
    
    while (true)
    {
    }     
}

参考资料
1 艾克姆科技 《nRF52832开发教程》

原文地址:https://www.cnblogs.com/Manual-Linux/p/9368983.html