GPIO EXTI中断的使用
1、N32G430C8L7_STB板卡带有三个用户按键,我们初始化key1 key2 按键,当按键按下时,在中断处理函数里输出我们的打印信息。
2、根据芯片手册上N32G430C8L7有24 条中断线,16条分配给GPIO使用,其余八条分配如下:
3、16条中断线与gpio的对应关系,在芯片手册上映射关系如下,但是我觉得是错的。
贴一张GD32 的映射图:(这个对应关系是对的)
4、KEY1 – PA4 对应EXTI4
KEY2 – PA5 对应EXTI5
新增key_input.h key_input.c 文件
#ifndef __KEY_INPUT_H__
#define __KEY_INPUT_H__
#include "main.h"
#define KEY1_INPUT_PORT GPIOA
#define KEY1_INPUT_PIN GPIO_PIN_4
#define KEY1_INPUT_EXTI_LINE EXTI_LINE4
#define KEY1_INPUT_PORT_SOURCE EXTI_LINE_SOURCE4
#define KEY1_INPUT_PIN_SOURCE AFIO_EXTI_PA4
#define KEY1_INPUT_IRQn EXTI4_IRQn
#define KEY2_INPUT_PORT GPIOA
#define KEY2_INPUT_PIN GPIO_PIN_5
#define KEY2_INPUT_EXTI_LINE EXTI_LINE5
#define KEY2_INPUT_PORT_SOURCE EXTI_LINE_SOURCE5
#define KEY2_INPUT_PIN_SOURCE AFIO_EXTI_PA5
#define KEY2_INPUT_IRQn EXTI9_5_IRQn
// extern func
void key_input_init(void);
#endif //__KEY_INPUT_H__
Key_input.c
#include "key_input.h"
// 开发板有用户按键三个,key1---PA4 key2---PA5 key3----PA6
// PA6用作了串口2的功能
// 所以这里只用Key1 Key2
static void key_input_exti_nvic_init(IRQn_Type IRQChannel)
{
NVIC_InitType NVIC_InitStructure;
/* Set key input interrupt priority */
NVIC_InitStructure.NVIC_IRQChannel = IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_SUB_PRIORITY_1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Initializes(&NVIC_InitStructure);
}
static void key_input_exti_line_init(uint8_t EXTI_line_source, uint32_t pin_source ,uint32_t EXTI_Line)
{
EXTI_InitType EXTI_InitStructure;
/* Configure key EXTI Line to key input Pin */
GPIO_EXTI_Line_Set(EXTI_line_source, pin_source);
/* Configure key EXTI line */
EXTI_InitStructure.EXTI_Line = EXTI_Line;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Peripheral_Initializes(&EXTI_InitStructure);
}
static void key_input_exti_gpio_init(GPIO_Module* GPIOx, uint16_t Pin)
{
GPIO_InitType GPIO_InitStructure;
/* Enable the GPIO Clock */
if (GPIOx == GPIOA)
{
RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA);
RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);
}
else if (GPIOx == GPIOB)
{
RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);
RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);
}
else if (GPIOx == GPIOC)
{
RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOC);
RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);
}
else if (GPIOx == GPIOD)
{
RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOD);
RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);
}
else
{
return;
}
if (Pin <= GPIO_PIN_ALL)
{
GPIO_Structure_Initialize(&GPIO_InitStructure);
GPIO_InitStructure.Pin = Pin;
GPIO_InitStructure.GPIO_Pull = GPIO_PULL_UP;
GPIO_Peripheral_Initialize(GPIOx, &GPIO_InitStructure);
}
}
// extern func
void key_input_init(void)
{
// init key1
key_input_exti_gpio_init(KEY1_INPUT_PORT,KEY1_INPUT_PIN);
key_input_exti_line_init(KEY1_INPUT_PORT_SOURCE,KEY1_INPUT_PIN_SOURCE,KEY1_INPUT_EXTI_LINE);
key_input_exti_nvic_init(KEY1_INPUT_IRQn);
// init key2
key_input_exti_gpio_init(KEY2_INPUT_PORT,KEY2_INPUT_PIN);
key_input_exti_line_init(KEY2_INPUT_PORT_SOURCE,KEY2_INPUT_PIN_SOURCE,KEY2_INPUT_EXTI_LINE);
key_input_exti_nvic_init(KEY2_INPUT_IRQn);
}
main.c
int main(void)
{
char *note1 = "Runing in Bootloader\r\n";
led_init();
usart1_init();
key_input_init();
SysTick_Delay_Ms(1000);
Usart1_SendString(note1,strlen(note1));
//Jump_To_App(0x08006000);
while(1)
{
GPIO_Pin_Toggle(LED2_GPIO_PORT, LED1_GPIO_PIN);
SysTick_Delay_Ms(1000);
}
}
中断处理函数:
char *note = "in EXTI9_5_IRQHandler \r\n";
char *note2 = "in EXTI4_IRQHandler \r\n";
// exti 5 - 9 line handler fuc
void EXTI9_5_IRQHandler(void)
{
if (RESET != EXTI_Interrupt_Status_Get(KEY2_INPUT_EXTI_LINE))
{
Usart1_SendString(note,strlen(note));
EXTI_Interrupt_Status_Clear(KEY2_INPUT_EXTI_LINE);
}
}
// key1 pa4 irq function
void EXTI4_IRQHandler(void)
{
if (RESET != EXTI_Interrupt_Status_Get(KEY1_INPUT_EXTI_LINE))
{
Usart1_SendString(note2,strlen(note2));
EXTI_Interrupt_Status_Clear(KEY1_INPUT_EXTI_LINE);
}
}
5、烧录后,按下key1 key2 中断处理函数里会有相关打印
如图: