7.3 【中断】外部中断检测

# 7.3 【中断】外部中断检测

本项目基于STM32微控制器,通过按键触发EXTI中断机制,当GPIO检测到下降沿时激活中断服务程序,驱动LED状态切换与蜂鸣器输出,实现触控响应延迟小于2ms的实时交互。


# 7.3.1 Stm32CubeMX配置

# 1. 建立新工程

① 建立一个新的STM32工程;
② 选择芯片“STM32F103C8T6”;
③ 设置工程的名称为“07 interrupt”;
④ 选择SWD调试方式;
⑤ 开启外部高速时钟源并修改主频为72MHz。

# 2. 引脚分配与参数配置

LED灯和蜂鸣器配置

  1. 在Pinout&Configuration界面选择“System Core”
  2. 双击“GPIO”进行配置
描述
  1. 选择PA7和PB5引脚
  2. 配置为GPIO_Output模式
描述
  1. 进入“Pinout & Configuration”标签页
  2. 在左侧导航栏中选择“System Core”
  3. 双击“GPIO”进行配置,
  4. 进入“GPIO output level”,选择“Low”
  5. 进入“GPIO mode”,选择“Output Push-Pull”
  6. 进入“Maximum output speed”,选择“Low”。
描述

按键控制引脚配置

  1. 在Pinout&Configuration界面选择“System Core”
  2. 选择PB12和PC13引脚
  3. 配置为GPIO_Output模式
描述
  1. 进入“Pinout & Configuration”标签页
  2. 在左侧导航栏中选择“System Core”
  3. 双击“GPIO”进行配置
  4. 进入“GPIO mode”
  5. 选择“External Interrupt Mode with Rising,Falling edge trigger detection”
描述

# 3. 生成代码

勾选生成单独外设文件,保存生成工程代码。

勾选生成单独外设文件

# 7.3.2 中断控制项目软件设计

# 1. NVIC初始化函数

//NVIC初始化函数
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/*配置NVIC为优先级组1*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/*配置中断源:按键1*/
NVIC_InitStructure.NVIC_IRQChannel=KEY1_INT_EXTI_IRQ;
/*配置抢占优先级:1*/
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
/*配置子优先级:1*/
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
/*使能中断通道*/
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=KEY2_INT_EXTI_IRQ;
NVIC_Init(&NVIC_InitStructure);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 2. EXTI初始化函数

//EXTI初始化函数
static void MX_EXTI_Init(void){
GPIO_InitTypeDef GPIO_InitStruct={0};
//配置GPIO为输入模式
__HAL_RCC_GPIOA_CLK_ENABLE( );           //使能GPIOA时钟
GPIO_InitStruct.Pin=KEY_GPIO_PIN;
GPIO_InitStruct.Mode=GPIO_MODE_IT_RISING;//上升沿触发中断
GPIO_InitStruct.Pull=GPIO_PULLDOWN;  //下拉电阻(根据硬件设计调整)
HAL_GPIO_Init(KEY_GPIO_PORT,&GPIO_InitStruct);
}
1
2
3
4
5
6
7
8
9
10

# 3. 中断优先级配置

/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI15_10_IRQn,11,0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

1
2
3
4

# 4. 中断服务函数

void EXTI15_10_IRQHandler(void)
{
/* USER CODE BEGIN EXTI15_10_IRQn 0 */
/* USER CODE END EXTI15_10_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(KEY2_Pin);
HAL_GPIO_EXTI_IRQHandler(KEY1_Pin);
/* USER CODE BEGIN EXTI15_10_IRQn 1 */
/* USER CODE END EXTI15_10_IRQn 1 */
}
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* EXTI line interrupt detected */
if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
HAL_GPIO_EXTI_Callback(GPIO_Pin);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 5. 中断回调函数

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
HAL_Delay(10); // 10ms软件消抖,消除机械按键抖动干扰
if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,
KEY1_Pin) == GPIO_PIN_RESET)
{
HAL_GPIO_TogglePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin);
} 
if(__HAL_GPIO_EXTI_GET_IT(KEY2_Pin))
{
if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,
KEY2_Pin) == GPIO_PIN_RESET)
{
beep_state = 1; // 设置蜂鸣器启动标志(电平保持型触发)
}
if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,
KEY2_Pin) == GPIO_PIN_SET)
{
beep_state = 0; // 清除蜂鸣器启动标志(松手即停设计)
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 6. 功能代码实现

volatile uint8_t beep_state = 0;  // 蜂鸣器状态(0关闭,1开启)
volatile uint32_t key_press_time = 0;  //用于记录当前时间
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
if(beep_state == 1)
{
HAL_GPIO_TogglePin(BEEP_GPIO_Port, BEEP_Pin);
HAL_Delay(1);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 7.3.3 中断控制项目下载验证

ST-LINK下载器一端连接电脑,另一端连接至嵌入式学习板的SWD接口。随后点击“Run”按钮,将程序编译并下载至芯片。下载好代码后,按下开发板上的按键,蜂鸣器会鸣响,同时设定的LED灯会随着按键的按下的时候在亮与灭的状态循环。

勾选生成单独外设文件