🔬 实验09:外部中断——按键

📌 实验目标
  • 掌握 EXTI 外部中断的配置方法
  • 学会编写中断服务函数
  • 理解中断触发方式(上升沿/下降沿)
  • 实现按键中断控制 LED

一、实验内容

  1. 配置 GPIO 为外部中断输入
  2. 设置下降沿触发方式
  3. 编写 EXTI 中断服务函数
  4. 按键中断控制 LED 亮灭切换

二、配置步骤

  1. 使能 GPIO 和 AFIO 时钟
  2. GPIO 初始化为浮空/上拉输入
  3. gpio_extilineconfig 映射到 EXTI
  4. 配置 EXTI 中断线(触发方式、使能)
  5. 配置 NVIC(中断优先级、使能)
  6. 编写中断服务函数

三、示例代码

main.c(外部中断控制 LED)
#include "stm32f10x.h"

void EXTI0_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

    // PA0 上拉输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 映射 PA0 → EXTI0
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);

    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void EXTI0_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line0) != RESET)
    {
        // 延时消抖
        uint32_t i;
        for (i = 0; i < 10000; i++);
        if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0)
        {
            GPIO_ToggleBits(GPIOB, GPIO_Pin_0);
        }
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}

int main(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    EXTI0_Config();
    while (1);
}
💡 这段代码怎么用?
  1. 对照 6 步流程读代码:①时钟 ②GPIO 输入 ③GPIO_EXTILineConfig 映射 ④EXTI 触发方式 ⑤NVIC 优先级 ⑥服务函数
  2. KEY 通常接 下降沿 触发(按下为低);若想改成松手触发,把 EXTI_Trigger_Falling 改为 EXTI_Trigger_Rising(对应实验任务 1)
  3. 中断里做了 10ms 延时消抖 + 电平二次确认,比轮询更省 CPU——这就是「外部中断有什么用」

四、参考资料

资料文件
外部中断 PPT实验4 外部中断—按键.pptx
实验指导书外部中断—按键 实验指导书.docx
3 按键模板工程3keys-template.rar