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信号产生的事件。
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;
}