使用STM32设置GPIO中断

使用S™ 32设置GPIO中断

中断示例

设计一个按键中断的实例。设置两个中断:EXTI0、EXTI9,

在EXTI9的中断服务之程序中实现LED灯的控制

按键中断实例设计:EXTI0和EXTI9

根据提供的电路图,我将设计一个基于STM32的按键中断系统,其中两个按键分别连接到EXTI0和EXTI9引脚,并通过EXTI9的中断服务程序控制LED灯组。

硬件连接分析

从电路图可以看出:

  • 两个按键Key ButtonWakeup Button通过上拉/下拉电阻连接到微控制器
  • EXTI0连接到第一个按键输入
  • EXTI9连接到第二个按键输入
  • 四个LED灯(带限流电阻)连接到微控制器的GPIO引脚

STM32代码实现

c 复制代码
#include "stm32f10x.h"  // 假设使用STM32F10x系列,可根据实际芯片修改

// LED相关定义
#define LED_PORT          GPIOB
#define LED_PIN_ALL       (GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11)
#define LED_ALL_ON()      GPIO_SetBits(LED_PORT, LED_PIN_ALL)
#define LED_ALL_OFF()     GPIO_ResetBits(LED_PORT, LED_PIN_ALL)

// 按键相关定义
#define KEY0_PORT         GPIOA
#define KEY0_PIN          GPIO_Pin_0    // EXTI0对应PA0
#define KEY1_PORT         GPIOA
#define KEY1_PIN          GPIO_Pin_9    // EXTI9对应PA9

// 中断标志位
volatile uint8_t Key0Pressed = 0;
volatile uint8_t Key1Pressed = 0;

// LED状态变量
volatile uint8_t ledState = 0;  // 0:全灭, 1:交替闪烁, 2:全部点亮

/*
 * 函数名:EXTI0_IRQHandler
 * 描述:EXTI0中断服务程序
 * 输入:无
 * 输出:无
 */
 外部中断函数EXTI0_IRQHandler
void EXTI0_IRQHandler(void)
{
    // 检查是否是KEY0触发的中断
    if(EXTI_GetITStatus(EXTI_Line0) != RESET)
    {
        // 清除中断标志位
        EXTI_ClearITPendingBit(EXTI_Line0);
        
        // 设置按键0被按下的标志
        Key0Pressed = 1;
    }
}

/*
 * 函数名:EXTI9_5_IRQHandler
 * 描述:EXTI9-5中断服务程序
 * 输入:无
 * 输出:无
 */
 EXTI9-5中断服务程序
 EXTI9中断服务程序中实现了三种LED控制模式
void EXTI9_5_IRQHandler(void)
{
    // 检查是否是KEY1触发的中断
    if(EXTI_GetITStatus(EXTI_Line9) != RESET)
    {
        // 清除中断标志位
        EXTI_ClearITPendingBit(EXTI_Line9);
        
        // 设置按键1被按下的标志
        Key1Pressed = 1;
        
        // 控制LED灯
        switch(ledState)
        {
            case 0:  // 全灭
                LED_ALL_ON();
                ledState = 1;
                break;
                
            case 1:  // 全部点亮
                LED_ALL_OFF();
                ledState = 2;
                break;
                
            case 2:  // 交替闪烁模式
                GPIO_Write(LED_PORT, (GPIO_ReadOutputData(LED_PORT) ^ LED_PIN_ALL));
                break;
        }
    }
}

/*
 * 函数名:KEY_Init
 * 描述:初始化按键GPIO和中断
 * 输入:无
 * 输出:无
 */
void KEY_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    
    // 使能GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    // 配置KEY0和KEY1为浮空输入
    GPIO_InitStructure.GPIO_Pin = KEY0_PIN | KEY1_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(KEY0_PORT, &GPIO_InitStructure);
    
    // 使能AFIO时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    
    // 配置KEY0为EXTI0中断线
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
    配置EXIT线
    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);
    
    // 配置KEY1为EXTI9中断线
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource9);
    
    EXTI_InitStructure.EXTI_Line = EXTI_Line9;
    EXTI_Init(&EXTI_InitStructure);
    
    // 配置NVIC中断优先级
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
    NVIC_Init(&NVIC_InitStructure);
}

/*
 * 函数名:LED_Init
 * 描述:初始化LED GPIO
 * 输入:无
 * 输出:无
 */
void LED_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    // 使能GPIOB时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    
    // 配置LED端口为推挽输出
    GPIO_InitStructure.GPIO_Pin = LED_PIN_ALL;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_PORT, &GPIO_InitStructure);
    
    // 初始状态:全灭
    LED_ALL_OFF();
}

int main(void)
{
    // 初始化按键和LED
    KEY_Init();
    LED_Init();
    
    while(1)
    {
        // 检查KEY0是否被按下
        if(Key0Pressed)
        {
            // 短暂延时,消除抖动
            for(volatile uint32_t i = 0; i < 10000; i++);
            
            // 处理按键事件
            // 这里可以添加其他功能
            
            // 清除标志位
            Key0Pressed = 0;
        }
        
        // 检查KEY1是否被按下
        if(Key1Pressed)
        {
            // 短暂延时,消除抖动
            for(volatile uint32_t i = 0; i < 10000; i++);
            
            // 清除标志位
            Key1Pressed = 0;
        }
        
        // 可以在这里添加其他主循环逻辑
    }
}

代码说明

  1. 硬件配置

    • EXTI0连接到PA0引脚
    • EXTI9连接到PA9引脚
    • 四个LED灯连接到PB8-PB11引脚
  2. 中断配置

    • EXTI0和EXTI9均配置为下降沿触发
    • 为两个中断分配了相同的优先级
  3. LED控制

    • EXTI9中断服务程序中实现了三种LED控制模式:
      • 全灭 → 全部点亮 → 交替闪烁
    • 使用ledState变量跟踪当前LED状态
  4. 按键消抖

    • 在主循环中通过延时实现简单的按键消抖
  5. 中断标志位

    • 使用Key0Pressed和Key1Pressed变量作为中断标志位

这个设计实现了按键检测和LED控制的基本功能,可以根据实际需求进一步扩展和优化。

相关推荐
森焱森1 小时前
水下航行器外形分类详解
c语言·单片机·算法·架构·无人机
小殷学长3 小时前
【单片机毕业设计17-基于stm32c8t6的智能倒车监测系统】
stm32·单片机·课程设计
TESmart碲视5 小时前
HKS201-M24 大师版 8K60Hz USB 3.0 适用于 2 台 PC 1台显示器 无缝切换 KVM 切换器
单片机·嵌入式硬件·物联网·游戏·计算机外设·电脑·智能硬件
small_wh1te_coder6 小时前
硬件嵌入式学习路线大总结(一):C语言与linux。内功心法——从入门到精通,彻底打通你的任督二脉!
linux·c语言·汇编·嵌入式硬件·算法·c
花落已飘6 小时前
STM32中实现shell控制台(shell窗口输入实现)
stm32·单片机·嵌入式硬件
花落已飘6 小时前
STM32中实现shell控制台(命令解析实现)
stm32·shell
没有钱的钱仔7 小时前
STM32低功耗模式全面指南
css·stm32·css3
牵牛老人8 小时前
Qt处理USB摄像头开发说明与QtMultimedia与V4L2融合应用
stm32·单片机·qt
宇钶宇夕9 小时前
针对工业触摸屏维修的系统指南和资源获取途径
单片机·嵌入式硬件·自动化
和风化雨10 小时前
stm32的三种开发方式
stm32·单片机·嵌入式硬件