NRF52840学习历程(二)按键02事件中断

时间在2021125,寒假放假在家好好学一学

 

开发板:初雪的100出头那块 NRF52840 EVAL KIT

下载工具:JINLK V11(最好是JLINK V9以上 也有人用JLINK OB也行,其他的下载器STLINK,DAP不建议用)

版本号: KEIL5编程环境,CMSIS为5.3.0, NRF52840的CMSIS为8.35.0

参考资料: NRF52840-Eval-Kit-Schematic.pdf(原理图)

nRF5_SDK_17.0.2_d674dde(官方例程)

nRF5_SDK_17.0.0_offline_doc(官方文档)

青风NRF52832的按键章节

 

实现功能: 按键点灯

 

按键原理图

IO口为11和18,其中18为RESET按键,现在我还不会取消18的复位功能,暂时不用

配置IO为上啦输入,然后按键按下的时候为0电平,按键没有按或松开的时候为高电平

用到       nrf_gpio_cfg_input 配置为输入模式

代码

       nrf_gpio_cfg_input(11,NRF_GPIO_PIN_PULLUP );

 

因为按键只有1个,我再外置三个独立按键,IO为24,20,17,同样的另外一端接了地

使用的是GPIOTE外部中断,GPIO是通用输入输出引脚,T/E代表引脚为任务或者中断设置

添加文件

具体在E:\nRF52840\nRF5_SDK_17.0.2_d674dde\modules\nrfx\drivers\src里面找

GPIOTE只有8个通道,都是通过CONFIG[0~7]8个寄存器操作的

代码如下:

NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)
                           | (KEY0 << GPIOTE_CONFIG_PSEL_Pos)  
                           | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);

配置第一个通道NRF_GPIOTE->CONFIG[0]

其中 (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos) 为

其中(KEY0 << GPIOTE_CONFIG_PSEL_Pos)为

其中GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);为

 

 

即设置事件模式(EVENT),引脚为KEY0,然后高->低,即下降沿触发中断

 

然后开启中断

NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN0_Set << GPIOTE_INTENSET_IN0_Pos;// 使能中断CONFIG[0]:

中断函数:

void GPIOTE_IRQHandler(void)
{
    if ((NRF_GPIOTE->EVENTS_IN[0] == 1) &&   (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN0_Msk))
    {
        NRF_GPIOTE->EVENTS_IN[0] = 0; //中断事件清零
		 if(nrf_gpio_pin_read(KEY0)== 0)
		 {
			nrf_gpio_pin_toggle(LED0);
		 }			
    }
}

完整代码如下:


#include <stdbool.h>
#include <stdint.h>
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include "nrf_gpiote.h"


uint32_t LED0,LED1,LED2,LED3;
uint32_t KEY0,KEY1,KEY2,KEY3;



/**
 * @brief Function for application main entry.
 */
int main(void)
{
	LED0 =  NRF_GPIO_PIN_MAP(0,13);
	LED1 =  NRF_GPIO_PIN_MAP(0,14);
	LED2 =  NRF_GPIO_PIN_MAP(1,9);
	LED3 =  NRF_GPIO_PIN_MAP(0,16);

	KEY0 =  NRF_GPIO_PIN_MAP(0,11);
	KEY1 =  NRF_GPIO_PIN_MAP(0,24);
	KEY2 =  NRF_GPIO_PIN_MAP(0,20);
	KEY3 =  NRF_GPIO_PIN_MAP(0,17);

	nrf_gpio_cfg_output(LED0);
	nrf_gpio_cfg_output(LED1);
	nrf_gpio_cfg_output(LED2);
	nrf_gpio_cfg_output(LED3);

	nrf_gpio_pin_set(LED0);
	nrf_gpio_pin_set(LED1);
	nrf_gpio_pin_set(LED2);
	nrf_gpio_pin_set(LED3);
	
	nrf_gpio_cfg_input(KEY0,NRF_GPIO_PIN_PULLUP );
	nrf_gpio_cfg_input(KEY1,NRF_GPIO_PIN_PULLUP );
	nrf_gpio_cfg_input(KEY2,NRF_GPIO_PIN_PULLUP );
	nrf_gpio_cfg_input(KEY3,NRF_GPIO_PIN_PULLUP );
	
	NVIC_EnableIRQ(GPIOTE_IRQn);//中断嵌套设置
	
    NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)
                           | (KEY0 << GPIOTE_CONFIG_PSEL_Pos)  
                           | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
						   
	 // 设置事件模式(EVENT),引脚为KEY0,然后高->低,即下降沿触发中断	 
    NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN0_Set << GPIOTE_INTENSET_IN0_Pos;// 使能中断类型:


    NRF_GPIOTE->CONFIG[1] =  (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)
                           | (KEY1 << GPIOTE_CONFIG_PSEL_Pos)  
                           | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
						   
	 // 设置事件模式(EVENT),引脚为KEY1,然后高->低,即下降沿触发中断	 
    NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN1_Set << GPIOTE_INTENSET_IN1_Pos;// 使能中断类型:


    NRF_GPIOTE->CONFIG[2] =  (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)
                           | (KEY2 << GPIOTE_CONFIG_PSEL_Pos)  
                           | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
						   
	 // 设置事件模式(EVENT),引脚为KEY2,然后高->低,即下降沿触发中断 
    NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN2_Set << GPIOTE_INTENSET_IN2_Pos;// 使能中断类型:


    NRF_GPIOTE->CONFIG[3] =  (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)
                           | (KEY3 << GPIOTE_CONFIG_PSEL_Pos)  
                           | (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
						   
	 // 设置事件模式(EVENT),引脚为KEY3,然后高->低,即下降沿触发中断	 
    NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN3_Set << GPIOTE_INTENSET_IN3_Pos;// 使能中断类型:


	while(1)
	{
//		if(0 == nrf_gpio_pin_read(KEY0))
//		{
//			nrf_delay_ms(10); //xiaodou
//			if(0 == nrf_gpio_pin_read(KEY0))
//			{
//				nrf_gpio_pin_toggle(LED0);
//				
//				while(0 == nrf_gpio_pin_read(KEY0)); //songshou
//			}
//		}
				
	}
	
}

void GPIOTE_IRQHandler(void)
{
    if ((NRF_GPIOTE->EVENTS_IN[0] == 1) &&   (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN0_Msk))
    {
        NRF_GPIOTE->EVENTS_IN[0] = 0; //中断事件清零
		 if(nrf_gpio_pin_read(KEY0)== 0)
		 {
			nrf_gpio_pin_toggle(LED0);
		 }			
    }
    if ((NRF_GPIOTE->EVENTS_IN[1] == 1) &&   (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN1_Msk))
    {
        NRF_GPIOTE->EVENTS_IN[1] = 0; //中断事件清零
		 if(nrf_gpio_pin_read(KEY1)== 0)
		 {
			nrf_gpio_pin_toggle(LED1);
		 }			
    }
    if ((NRF_GPIOTE->EVENTS_IN[2] == 1) &&   (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN2_Msk))
    {
        NRF_GPIOTE->EVENTS_IN[2] = 0; //中断事件清零
		 if(nrf_gpio_pin_read(KEY2)== 0)
		 {
			nrf_gpio_pin_toggle(LED2);
		 }			
    }
    if ((NRF_GPIOTE->EVENTS_IN[3] == 1) &&   (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN3_Msk))
    {
        NRF_GPIOTE->EVENTS_IN[3] = 0; //中断事件清零
		 if(nrf_gpio_pin_read(KEY3)== 0)
		 {
			nrf_gpio_pin_toggle(LED3);
		 }			
    }
}

这种中断写起来非常麻烦,因为是操作的寄存器,而且稳定性也非常不好, 下节继续搞中断

猜你喜欢

转载自blog.csdn.net/jwdeng1995/article/details/113107290