STM32_实验5_中断实验

通过外部中断来检测四个按键按下的状态:

WK_UP 控制蜂鸣器响和停

KEY0 控制 LED_R 互斥点亮

KEY1 控制 LED_G 互斥点亮

KEY2 控制 LED_B 互斥点亮。

中断的基本概念:

中断请求(IRQ):

当发生某个特定事件(例如硬件信号、定时器溢出等)时,相关的外部或内部设备会向处理器发出中断请求。这种请求通知处理器有事情需要处理。

中断服务程序(ISR):

当处理器接收到中断请求后,它会暂停当前的执行,保存当前的状态,并跳转到预先定义的中断服务程序(ISR)。ISR 是一段特定的代码,用于处理中断事件。

中断优先级:

处理器可以为不同的中断分配不同的优先级,以决定在多个中断发生时,哪个中断首先得到处理。高优先级的中断会抢占低优先级的中断。

中断响应流程:

中断触发:外部事件或内部条件触发中断请求。

中断信号:处理器收到中断信号,暂停当前任务。

保存状态:处理器保存当前执行状态,以便中断处理完成后能够恢复。

执行 ISR:跳转到中断服务程序,处理具体的中断事件。

恢复状态:中断处理完成后,恢复之前保存的状态,继续执行被中断的任务。

中断向量表:

中断向量表是一个存储中断服务程序入口地址的表格。处理器通过查找中断向量表来找到并执行相应的 ISR。

中断的类型:

外部中断:

外部中断(External Interrupt)指的是由外部事件触发的中断信号,用于处理来自微控制器外部的信号或事件。这种中断通常由外部硬件信号(如按钮、传感器或其他设备)产生,并被用于通知微控制器有重要事件需要处理。

外部中断的配置通常涉及设置中断触发条件(例如边沿触发或电平触发)、中断优先级和使能中断请求。STM32 微控制器通过 EXTI(External Interrupt/Event Controller)模块来配置外部中断。

外部中断广泛用于处理事件驱动任务,如按钮按下检测、外部信号捕获、时钟脉冲计数等。

内部中断:

由内部外设或系统模块产生的中断,如定时器溢出、USART 接收数据、ADC 转换完成等。

系统异常:

处理器内的异常事件,如硬件故障、内存管理错误等。

在 STM32 微控制器中,中断的设置和使用通常包括以下步骤:

配置外设或 GPIO:设置需要触发中断的外设或引脚。

配置中断线:设置 EXTI 模块或其他中断控制器,指定中断源和触发条件。

使能中断:在 NVIC 中使能相应的中断线,设置中断优先级。

编写 ISR:实现中断服务程序来处理特定的中断事件。

例如,配置一个定时器中断:

cpp 复制代码
// 定时器中断服务程序
void TIM1_UP_IRQHandler(void)
{
    if (TIM1->SR & TIM_SR_UIF)  // 检查更新中断标志
    {
        TIM1->SR &= ~TIM_SR_UIF; // 清除中断标志
        // 执行中断处理代码
    }
}
// 配置定时器并使能中断
void Timer_Init(void)
{
    // 初始化定时器
    // ...
    
    // 启用定时器中断
    HAL_NVIC_EnableIRQ(TIM1_UP_IRQn);
}

外部中断回调函数:

在 STM32 HAL 库中,HAL_GPIO_EXTI_Callback 是外部中断回调函数的标准命名。这个命名是由 HAL 库规定的,用于处理 GPIO 外部中断的回调。如果你想使用这个回调函数,你需要在你的代码中实现它,并在其中定义当外部中断触发时的具体行为。

cpp 复制代码
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == GPIO_PIN_0)
    {
        // 处理引脚 0 的外部中断
    }
    else if (GPIO_Pin == GPIO_PIN_1)
    {
        // 处理引脚 1 的外部中断
    }
    // 其他引脚的处理
}

注意: 这个命名是为了确保与 HAL 库的兼容性和一致性。如果你在自定义项目中使用不同的命名,可能会影响到 HAL 库的功能调用。

HAL_GPIO_TogglePin 函数(高/低翻转):

HAL_GPIO_TogglePin 是 STM32 HAL 库中的一个函数,用于翻转(切换)指定 GPIO 引脚的状态。这意味着,如果引脚当前的电平是高(GPIO_PIN_SET),函数会将其切换为低(GPIO_PIN_RESET);如果电平是低,函数则会将其切换为高。

函数原型:

void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

参数:

GPIOx :指定 GPIO 端口。例如:GPIOA, GPIOB, GPIOC 等。这个参数决定了要操作哪个 GPIO端口。
GPIO_Pin:指定要操作的 GPIO 引脚。可以是以下形式的掩码:GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2, ..., GPIO_PIN_n(n 是引脚编号),或者多个引脚的位掩码组合,例 如GPIO_PIN_0 | GPIO_PIN_1。

作用是将指定的 GPIO 引脚的状态从高电平翻转为低电平,或从低电平翻转为高电平。这对于需要周期性切换引脚状态的应用非常有用,例如控制 LED 的闪烁。

实验开始:

  1. 具体的 pgio 引脚配置如下,蜂鸣器和 RGB 灯和以前一样配置,按键 KEY0(PD10) 、KEY1(PD9)、KEY2(PD8) 、WK_UP(PC13) 配置外部中断模式。配置串口 1 用于调试。

2、将按键 KEY0(PD10) 、KEY1(PD9)、KEY2(PD8) 配置为下降沿触发的外部中断模式,按键 WK_UP(PC13) 配置为上升沿触发的外部中断模式。这里举例为按键 WK_UP(PC13) 配置为上升沿触发的外部中断模式。

NVIC 使能中断线路组

(配置完生成代码)

EXTI (External Interrupt) line [9:5] 是 STM32 微控制器中的一个外部中断线路组,用于处理 GPIO 引脚 5 到 9 的外部中断请求。这一组中的每一条中断线都可以连接到对应的 GPIO 引脚,当引脚的电平发生变化时,触发相应的中断服务程序(ISR)。

3、在 HAL 库中,中断运行完后会先进入相对应的中断回调函数,处理完该函数后,才会退出中断。我们一般将中断需要处理代码会放在中断回调函数中去运行。

中断回调函数:void HAL_GPIO_EXTI_Callback*(uint16_t GPIO_Pin);

这里在 main.c 里可以定义 void HAL_GPIO_EXTI_Callback*(uint16_t GPIO_Pin); 函数编写逻辑代码,完成本实验。主函数可以空置,只需等待中断触发外部中断回调函数即可。

cpp 复制代码
/* USER CODE BEGIN 4 */
// 外部中断回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    switch (GPIO_Pin)
    {
        case GPIO_PIN_8: // KEY2
            HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_9);
            printf("LED_B state transition\n");
            break;
        case GPIO_PIN_9: // KEY1
            HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_8);
            printf("LED_G state transition\n");
            break;
        case GPIO_PIN_10: // KEY0
            HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_7);
            printf("LED_R state transition\n");
            break;
        case GPIO_PIN_13: // WK_UP
            HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_2);
            printf("beep state transition\n");
            break;
        default:
            break;
    }
}
/* USER CODE END 4 */

中断优先级的配置

在 STM32 中,中断优先级通常分为两个部分:

抢占优先级(Preemption Priority) : 决定了中断之间的优先处理顺序。抢占优先级高的中断可以打断抢占优先级低的中断。

响应优先级(Sub Priority): 决定了具有相同抢占优先级的中断的处理顺序。

通过以下函数可以设置中断优先级:

HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority);

示例:配置中断优先级

假设有三个中断源,分别是 EXTI0、EXTI1 和 EXTI2。我们希望 EXTI0 拥有最高的优先级,EXTI1 次之,EXTI2 优先级最低。可以通过以下代码设置:

// 设置 EXTI0 中断优先级为最高(抢占优先级 0,响应优先级 0)

HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(EXTI0_IRQn);

// 设置 EXTI1 中断优先级为次高(抢占优先级 1,响应优先级 0)

HAL_NVIC_SetPriority(EXTI1_IRQn, 1, 0);

HAL_NVIC_EnableIRQ(EXTI1_IRQn);

// 设置 EXTI2 中断优先级为最低(抢占优先级 2,响应优先级 0)

HAL_NVIC_SetPriority(EXTI2_IRQn, 2, 0);

HAL_NVIC_EnableIRQ(EXTI2_IRQn);

相关推荐
manhuami200742 分钟前
51单片机ALE引脚的作用 - 锁存地址和输出时钟信号并不冲突
单片机·嵌入式硬件·51单片机
搬砖的小码农_Sky1 小时前
单片机如何入门?
单片机·嵌入式硬件
Q23553688721 小时前
60V恒流IC SL8443B内置功率MOS 支持2.5A电流 降压LED恒流驱动芯片
单片机·嵌入式硬件
暮雪倾风2 小时前
【STM32-HAL库】TEMT6000光照强度传感器(STM32F407ZGT6)(附带工程下载链接)
stm32·单片机·嵌入式硬件
三菱-Liu2 小时前
三菱FX5U CPU实时监视功能GX LogViewer Version
驱动开发·嵌入式硬件·硬件工程·制造
板子小哥3 小时前
Lua语法基础全面剖析(中篇)
开发语言·嵌入式硬件·junit·单元测试·硬件工程·lua·1024程序员节
Industio_触觉智能4 小时前
瑞芯微RK3566/RK3568 Android11下该如何默认屏蔽导航栏/状态栏?看这篇文章就懂了
嵌入式硬件·物联网·rk3568·rk3566·鸿蒙开发板
陌夏微秋4 小时前
00 硬件、嵌入式硬件知识-目录篇
linux·stm32·单片机·嵌入式硬件·mcu·ubuntu
yava_free5 小时前
OpenMV的无人驾驶智能小车模拟系统
c语言·c++·stm32
Whappy0015 小时前
4. STM32之TIM实验--输出比较(PWM输出,电机,四轴飞行器,智能车,机器人)--(实验2:PWM驱动舵机)
stm32·嵌入式硬件·机器人