战舰开发板V4——外部中断
战舰开发板V4——外部中断






什么是 NVIC? NVIC 即嵌套向量中断控制器,全称 Nested vectored interrupt controller。
X:Y = 4 个优先级位里面,X 个位用来控制能不能抢中断,Y 个位控制同时来了谁先跑。
EXTI0_IRQHandler→ EXTI0(1 根线)EXTI1_IRQHandler→ EXTI1(1 根线)EXTI2_IRQHandler→ EXTI2(1 根线)EXTI3_IRQHandler→ EXTI3(1 根线)EXTI4_IRQHandler→ EXTI4(1 根线)EXTI9_5_IRQHandler→ EXTI5、EXTI6、EXTI7、EXTI8、EXTI9(5 根线共用)EXTI15_10_IRQHandler→ EXTI10、EXTI11、EXTI12、EXTI13、EXTI14、EXTI15(6 根线共用)
总数:1+1+1+1+1+5+6 = 16 根外部中断线

#include "Exti.h"
/**
* @brief KEY0 外部中断服务程序
* @param 无
* @retval 无
*/
void KEY0_INT_IRQHandler(void)
{
/* 调用中断处理公用函数 清除KEY0所在中断线 的中断标志位 */
HAL_GPIO_EXTI_IRQHandler(KEY0_INT_GPIO_PIN);
/* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
__HAL_GPIO_EXTI_CLEAR_IT(KEY0_INT_GPIO_PIN);
}
/**
* @brief KEY1 外部中断服务程序
* @param 无
* @retval 无
*/
void KEY1_INT_IRQHandler(void)
{
/* 调用中断处理公用函数 清除KEY1所在中断线 的中断标志位,中断下半部在HAL_GPIO_EXTI_Callback执行 */
HAL_GPIO_EXTI_IRQHandler(KEY1_INT_GPIO_PIN);
/* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
__HAL_GPIO_EXTI_CLEAR_IT(KEY1_INT_GPIO_PIN);
}
/**
* @brief KEY2 外部中断服务程序
* @param 无
* @retval 无
*/
void KEY2_INT_IRQHandler(void)
{
/* 调用中断处理公用函数 清除KEY2所在中断线 的中断标志位,中断下半部在HAL_GPIO_EXTI_Callback执行 */
HAL_GPIO_EXTI_IRQHandler(KEY2_INT_GPIO_PIN);
/* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
__HAL_GPIO_EXTI_CLEAR_IT(KEY2_INT_GPIO_PIN);
}
/**
* @brief WK_UP 外部中断服务程序
* @param 无
* @retval 无
*/
void WKUP_INT_IRQHandler(void)
{
/* 调用中断处理公用函数 清除KEY_UP所在中断线 的中断标志位,中断下半部在HAL_GPIO_EXTI_Callback执行 */
HAL_GPIO_EXTI_IRQHandler(WKUP_INT_GPIO_PIN);
/* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
__HAL_GPIO_EXTI_CLEAR_IT(WKUP_INT_GPIO_PIN);
}
/**
* @brief 中断服务程序中需要做的事情
在HAL库中所有的外部中断服务函数都会调用此函数
* @param GPIO_Pin:中断引脚号
* @retval 无
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
delay_ms(20); /* 消抖 */
switch(GPIO_Pin)
{
case KEY0_INT_GPIO_PIN:
if (KEY0 == 0)
{
LED0_TOGGLE(); /* LED0 状态取反 */
LED1_TOGGLE(); /* LED1 状态取反 */
}
break;
case KEY1_INT_GPIO_PIN:
if (KEY1 == 0)
{
LED0_TOGGLE(); /* LED0 状态取反 */
}
break;
case KEY2_INT_GPIO_PIN:
if (KEY2 == 0)
{
LED1_TOGGLE(); /* LED1 状态取反 */
}
break;
case WKUP_INT_GPIO_PIN:
if (WK_UP == 1)
{
BEEP_TOGGLE(); /* 蜂鸣器状态取反 */
}
break;
}
}
/**
* @brief 外部中断初始化程序
* @param 无
* @retval 无
*/
void Extix_init(void)
{
GPIO_InitTypeDef GPIO_Init_Struct;
KEY0_GPIO_CLK_ENABLE(); /* KEY0时钟使能 */
KEY1_GPIO_CLK_ENABLE(); /* KEY1时钟使能 */
KEY2_GPIO_CLK_ENABLE(); /* KEY2时钟使能 */
WKUP_GPIO_CLK_ENABLE(); /* WKUP时钟使能 */
GPIO_Init_Struct.Pin = KEY0_INT_GPIO_PIN;
GPIO_Init_Struct.Mode = GPIO_MODE_IT_FALLING; /* 下升沿触发 */
GPIO_Init_Struct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(KEY0_INT_GPIO_PORT, &GPIO_Init_Struct); /* KEY0配置为下降沿触发中断 */
GPIO_Init_Struct.Pin = KEY1_INT_GPIO_PIN;
GPIO_Init_Struct.Mode = GPIO_MODE_IT_FALLING; /* 下升沿触发 */
GPIO_Init_Struct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_Init_Struct); /* KEY1配置为下降沿触发中断 */
GPIO_Init_Struct.Pin = KEY2_INT_GPIO_PIN;
GPIO_Init_Struct.Mode = GPIO_MODE_IT_FALLING; /* 下升沿触发 */
GPIO_Init_Struct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_Init_Struct); /* KEY2配置为下降沿触发中断 */
GPIO_Init_Struct.Pin = WKUP_INT_GPIO_PIN;
GPIO_Init_Struct.Mode = GPIO_MODE_IT_RISING; /* 上升沿触发 */
GPIO_Init_Struct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(WKUP_GPIO_PORT, &GPIO_Init_Struct); /* WKUP配置为下降沿触发中断 */
HAL_NVIC_SetPriority(KEY0_INT_IRQn, 0, 2); /* 抢占0,子优先级2 */
HAL_NVIC_EnableIRQ(KEY0_INT_IRQn); /* 使能中断线1 */
HAL_NVIC_SetPriority(KEY1_INT_IRQn, 1, 2); /* 抢占1,子优先级2 */
HAL_NVIC_EnableIRQ(KEY1_INT_IRQn); /* 使能中断线15 */
HAL_NVIC_SetPriority(KEY2_INT_IRQn, 2, 2); /* 抢占2,子优先级2 */
HAL_NVIC_EnableIRQ(KEY2_INT_IRQn); /* 使能中断线15 */
HAL_NVIC_SetPriority(WKUP_INT_IRQn, 3, 2); /* 抢占3,子优先级2 */
HAL_NVIC_EnableIRQ(WKUP_INT_IRQn); /* 使能中断线0 */
}
#ifndef __EXTI_H
#define __EXTI_H
#include "Delay.h"
#include "Led.h"
#include "Beep.h"
#include "Key.h"
/* 引脚 和 中断编号 & 中断服务函数 定义 */
#define KEY0_INT_GPIO_PORT GPIOE
#define KEY0_INT_GPIO_PIN GPIO_PIN_4
#define KEY0_INT_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0) /* PE口时钟使能 */
#define KEY0_INT_IRQn EXTI4_IRQn
#define KEY0_INT_IRQHandler EXTI4_IRQHandler
#define KEY1_INT_GPIO_PORT GPIOE
#define KEY1_INT_GPIO_PIN GPIO_PIN_3
#define KEY1_INT_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0) /* PE口时钟使能 */
#define KEY1_INT_IRQn EXTI3_IRQn
#define KEY1_INT_IRQHandler EXTI3_IRQHandler
#define KEY2_INT_GPIO_PORT GPIOE
#define KEY2_INT_GPIO_PIN GPIO_PIN_2
#define KEY2_INT_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0) /* PE口时钟使能 */
#define KEY2_INT_IRQn EXTI2_IRQn
#define KEY2_INT_IRQHandler EXTI2_IRQHandler
#define WKUP_INT_GPIO_PORT GPIOA
#define WKUP_INT_GPIO_PIN GPIO_PIN_0
#define WKUP_INT_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PA口时钟使能 */
#define WKUP_INT_IRQn EXTI0_IRQn
#define WKUP_INT_IRQHandler EXTI0_IRQHandler
void Extix_init(void); /* 外部中断初始化 */
#endif
浙公网安备 33010602011771号