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);

相关推荐
网易独家音乐人Mike Zhou几秒前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
zy张起灵6 分钟前
48v72v-100v转12v 10A大功率转换电源方案CSM3100SK
经验分享·嵌入式硬件·硬件工程
PegasusYu3 小时前
STM32CUBEIDE FreeRTOS操作教程(九):eventgroup事件标志组
stm32·教程·rtos·stm32cubeide·free-rtos·eventgroup·时间标志组
lantiandianzi7 小时前
基于单片机的多功能跑步机控制系统
单片机·嵌入式硬件
文弱书生6567 小时前
输出比较简介
stm32
哔哥哔特商务网7 小时前
高集成的MCU方案已成电机应用趋势?
单片机·嵌入式硬件
跟着杰哥学嵌入式7 小时前
单片机进阶硬件部分_day2_项目实践
单片机·嵌入式硬件
电子科技圈8 小时前
IAR与鸿轩科技共同推进汽车未来
科技·嵌入式硬件·mcu·汽车
东芝、铠侠总代136100683939 小时前
浅谈TLP184小型平面光耦
单片机·嵌入式硬件·物联网·平面
lantiandianzi9 小时前
基于单片机中医药柜管理系统的设计
单片机·嵌入式硬件