NRF52840 learning process (two) button 02 event interrupt

Time in 2021 Nian 1 Yue 25 Ri , winter vacation home, a good school to learn

 

Development Board : snow's 100 head piece NRF52840 EVAL KIT

Download tool: JINLK V11 (preferably JLINK V9 or higher, some people use JLINK OB, other downloaders STLINK, DAP are not recommended)

Version number: KEIL5 programming environment, CMSIS is 5.3.0, CMSIS of NRF52840 is 8.35.0

Reference material: NRF52840-Eval-Kit-Schematic.pdf (Schematic)

nRF5_SDK_17.0.2_d674dde (official routine)

nRF5_SDK_17.0.0_offline_doc (official document)

Qingfeng NRF52832 button chapter

 

Realization function: button light

 

Button schematic

The IO ports are 11 and 18, of which 18 is the RESET button. Now I will not cancel the reset function of 18, and I will not use it for the time being

Configure IO as up input, then when the button is pressed, it is 0 level, when the button is not pressed or released, it is high level

Use nrf_gpio_cfg_input to configure as input mode

Code

       nrf_gpio_cfg_input(11,NRF_GPIO_PIN_PULLUP );

 

Because there is only one button, I have three independent buttons externally, IO is 24, 20, 17, and the other end of the same is connected to the ground.

The GPIOTE external interrupt is used, GPIO is a general-purpose input and output pin, and T/E represents the pin for task or interrupt setting

add files

Specifically, find it in E:\nRF52840\nRF5_SDK_17.0.2_d674dde\modules\nrfx\drivers\src

GPIOTE has only 8 channels, all of which are operated through the 8 registers of CONFIG[0~7]

code show as below:

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);

Configure the first channel NRF_GPIOTE->CONFIG[0]

Where (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos) is

Where (KEY0 << GPIOTE_CONFIG_PSEL_Pos) is

Where GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos); is

 

 

That is, set the event mode (EVENT), the pin is KEY0, and then high->low, that is, the falling edge triggers the interrupt

 

Then turn on interrupt

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

Interrupt function:

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);
		 }			
    }
}

 

The complete code is as follows:


#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);
		 }			
    }
}

 

This kind of interrupt is very troublesome to write, because it is an operating register, and the stability is also very poor. Continue to interrupt in the next section

Guess you like

Origin blog.csdn.net/jwdeng1995/article/details/113107290