STM32F103 外部中断控制LED灯

STM32F103C8T6 最小系统开发板使用 HAL 库通过 PC12 按键外部中断控制 PC13 LED

1. 项目概述

在本项目中,我们将使用 STM32F103C8T6 最小系统开发板,通过 HAL(Hardware Abstraction Layer)库 实现 PC12 按键外部中断控制 PC13 LED 的亮灭

2. 硬件设计

1. 硬件需求

  • STM32F103C8T6 最小系统开发板
  • STLink-V2 下载器(用于烧录程序)
  • 杜邦线
  • LED(若开发板无板载 LED)
  • 220Ω 电阻(若使用外部 LED)
  • 按键(若开发板无板载按键)
  • 10kΩ 上拉电阻(若使用外部按键)

2. 硬件连接

  1. PC13 → LED 正极
  2. LED 负极 → 220Ω 电阻 → GND
  3. PC12 → 按键
  4. 按键另一端 → GND
  5. PC12 上拉 10kΩ 电阻 → VCC

3. 软件设计

1. STM32 HAL 库简介

HAL 库是 ST 官方提供的 硬件抽象库,封装了底层寄存器操作,使开发更加简单。

2. 工程创建步骤(基于 STM32CubeMX)

  1. 打开 STM32CubeMX,创建新工程,选择 STM32F103C8T6
  2. 配置 PC13 作为 GPIO 输出模式
    • 找到 "PC13",设置为 GPIO_Output
  3. 配置 PC12 作为外部中断模式
    • 找到 "PC12",设置为 GPIO_EXTI12
    • 触发方式选择 下降沿触发(Falling Edge)
    • 在 NVIC(中断控制器)中,启用 EXTI 12 中断
  4. 配置时钟(默认 72MHz,无需修改)。
  5. 生成代码,选择 IDE 为 STM32CubeIDE 或 Keil

外部中断处理流程

EXTI基本概念

External(Extended)interrupt/event Controller,外部(扩展)中断事件控制

包含20个产生事件/中断请求的边沿检测器,共20条EXTI线(F1)

  • 中断:要进入NVIC,有相应的中断服务函数,需要CPU处理;
  • 事件:不进入NVIC,仅用于内部硬件自动控制,如:TIM,DMA,ADC

img

外部中断分组-7个外部中断函数

STM32 的 EXTI(外部中断)是这样分组的(以 STM32F1/F4 系列为例):

EXTI 线 对应引脚 NVIC 中断向量
EXTI0 0 EXTI0_IRQn
EXTI1 1 EXTI1_IRQn
EXTI2 2 EXTI2_IRQn
EXTI3 3 EXTI3_IRQn
EXTI4 4 EXTI4_IRQn
EXTI5~9 5~9 EXTI9_5_IRQn
EXTI10~15 10~15 EXTI15_10_IRQn

STM32仅有 EXTI0-4、EXTI9_5、EXTI15_10, 7个外部中断函数

同组 GPIO 共享一条中断线

img

EXTI0~EXTI15 作为GPIO中断线使用,同组的GPIO共享一条中断线。

比如 EXTI0 组,PA0作为了中断源,则此时PB0~PG0不能作为中断源。

程序中 PC12 作为中断源,则对应的中断向量是 EXTI15_10_IRQn。

外部中断中断处理流程框图

外部中断/事件控制器框图

img

  1. 边沿触发;
  2. 软件出发;
  3. 中断屏蔽/清楚;
  4. 事件屏蔽

4. 代码实现

1. main.c 代码

#include "main.h"

void SystemClock_Config(void);
static void MX_GPIO_Init(void);

int main(void)
{
    HAL_Init();             //1. 初始化 HAL 库
    SystemClock_Config();   //2. 配置  系统时钟
    MX_GPIO_Init();         //3. 初始化 GPIO

    while (1)
    {
        // 主循环,无需轮询按键状态,响应由中断处理
    }
}

/**
  * @brief GPIO 初始化
  */
static void MX_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_GPIOC_CLK_ENABLE();             // 使能 GPIOC 时钟
    
    // 配置 PC13 为推挽输出
    GPIO_InitStruct.Pin = GPIO_PIN_13;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);             // 初始化 PC13

    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);  // 默认关闭 LED
    
    // 配置 PC12 为外部中断输入
    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;      // 外部中断模式,触发条件为:下降沿
    GPIO_InitStruct.Pull = GPIO_PULLUP;               // 内部上拉电阻,使引脚默认为高电平.按键按下时,电平变低 → 触发中断
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);           // 初始化 PC12
    
    // 使能 EXTI 中断
    HAL_NVIC_SetPriority(EXTI15_10_IRQn, 2, 0);       // 设置中断优先级:EXTI15_10_IRQn:对应 PC12~PC15 的外部中断向量;SetPriority(2,0):主优先级 2,子优先级 0
    HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);               // 使能 EXTI 中断
}

/**
  * @brief 外部中断回调函数
  */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == GPIO_PIN_12)  // 判断是否为 PC12 触发
    {
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);  // 切换 LED 状态
    }
}

/**
  * @brief EXTI15_10 中断处理函数
  */
void EXTI15_10_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
}

2. 代码解析

  • HAL_GPIO_EXTI_Callback()外部中断回调函数,当按键按下时触发 LED 亮灭。
  • HAL_NVIC_SetPriority()HAL_NVIC_EnableIRQ():配置 PC12 外部中断的优先级和使能
  • HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12):调用 HAL 库处理 PC12 中断。

5. 烧录与测试

stlink

  1. 连接 STLink-V2
    • STLink-V2 SWDIO → STM32 SWDIO
    • STLink-V2 SWCLK → STM32 SWCLK
    • STLink-V2 GND → STM32 GND
    • STLink-V2 3.3V → STM32 3.3V
  2. 使用 STM32CubeProgrammer 或 Keil 进行烧录
  3. 烧录完成后,按下 RESET 运行程序

6. 总结

本教程介绍了 STM32F103C8T6 最小系统开发板 通过 PC12 按键外部中断控制 PC13 LED 亮灭 的详细过程,包括 硬件设计、软件配置、代码编写、烧录步骤,适用于 STM32 HAL 库 开发。希望能帮助你快速入门 STM32 按键外部中断的开发!

posted @ 2025-02-07 14:49  jeikerxiao  阅读(240)  评论(0)    收藏  举报