7.3 【中断】外部中断检测

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

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


# 7.3.1 Stm32CubeMX配置

# 1. 建立新工程

  • 选择芯片型号:STM32F103C8T6
  • 工程名称:07 interrupt
  • 调试方式:SWD
  • 主频配置:72MHz(启用外部高速时钟源)

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

PB0配置

  • 模式:GPIO_Output
  • 输出电平:Low
  • 输出模式:推挽输出
  • 输出速度:Low
GPIO配置界面

PA7配置

  • 模式:GPIO_Output
  • 输出电平:Low
  • 输出模式:推挽输出
  • 输出速度:Low
PA7配置

PB12配置

  • 模式:External Interrupt Mode(Rising/Falling edge触发)
PB12中断配置

# 3. 生成代码

  • 在Code Generator中勾选“为每个外设生成独立文件”
  • 保存并生成工程代码(快捷键Ctrl+S)

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

# 1. NVIC初始化函数

配置中断优先级组与通道,代码完全保留:

//代码清单7-6 NVIC初始化函数 static void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //其他通道配置... }


### 2. EXTI初始化函数

配置外部中断触发条件,代码未改动:

```c
//代码清单7-7 EXTI初始化函数
static void MX_EXTI_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_GPIOA_CLK_ENABLE();
    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
11
12
13
14
15

# 3. 中断服务函数

处理EXTI15_10中断请求,代码保留完整:

//代码清单7-9 中断服务函数
void EXTI15_10_IRQHandler(void) {
    HAL_GPIO_EXTI_IRQHandler(KEY2_Pin);
    HAL_GPIO_EXTI_IRQHandler(KEY1_Pin);
}
1
2
3
4
5

# 4. 中断回调函数

实现按键消抖与状态切换逻辑:

//代码清单7-10 中断回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
    HAL_Delay(10); //消抖
    if (GPIO_Pin == KEY1_Pin) {
        HAL_GPIO_TogglePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin);
    }
    if (GPIO_Pin == KEY2_Pin) {
        beep_state = (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_RESET) ? 1 : 0;
    }
}
1
2
3
4
5
6
7
8
9
10

# 5. 主功能代码

主循环控制蜂鸣器脉冲输出:

//代码清单7-11 项目功能实现代码
volatile uint8_t beep_state = 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

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

下载代码后,按下按键可观察到:

  • LED状态切换
  • 蜂鸣器鸣响

实验效果演示: