二、中断使用

目录

1、中断优先级

2、中断分类

3、引脚中断


1、中断优先级

        STM32 中的中断优先级可以分为:抢占式优先级和响应优先级,响应优先级也称子优先级,每个中断源都需要被指定这两种优先级。抢占式优先级和响应优先级的区别:

                抢占优先级:抢占优先级高的中断可以打断正在执行的抢占优先级低的中断。

                响应优先级:抢占优先级相同,响应优先级高的中断不能打断响应优先级低的中断。

        还有一种情况就是当两个或者多个中断的抢占式优先级和响应优先级相同时,那么就遵循自然优先级,看中断向量表的中断排序,数值越小,优先级越高。


2、中断分类

(1)STM32F103中断

        STM32F103 的 EXTI 支持 19 个外部中断/事件请求,这些都是信息输入端,具体如下:

        EXTI 线 0~15:对应外部 IO 口的输入中断
        EXTI 线 16:连接到 PVD 输出
        EXTI 线 17:连接到 RTC 闹钟事件
        EXTI 线 18:连接到 USB 唤醒事件
        EXTI 线 19:连接到以太网唤醒事件

(2)STM32F407中断

        STM32F407 的 EXTI 支持 23 个外部中断/事件请求,这些都是信息输入端,具体如下:

        EXTI 线 0~15:对应外部 IO 口的输入中断
        EXTI 线 16:连接到 PVD 输出
        EXTI 线 17:连接到 RTC 闹钟事件
        EXTI 线 18:连接到 USB 唤醒事件
        EXTI 线 19:连接到以太网唤醒事件
        EXTI 线 20:连接到 USB OTG HS(在 FS 中配置)唤醒事件
        EXTI 线 21:连接到 RTC 入侵和时间戳事件
        EXTI 线 22:连接到 RTC 唤醒事件

(3)GPIO中断

        STM32 把 GPIO 管脚 GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G)分别对应中断线 0~15。这样子每个中断线对应了最多 7 个 IO 口,以线 0 为例:它对应了 GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0 和 GPIOG.0。而中断线每次只能连接到 1 个 IO 口上,这样就需要通过配置决定对应的中断线配置到哪个 GPIO 上了。


3、引脚中断

         初始化:

/**
* @brief 外部中断初始化程序
* @param 无
* @retval 无
*/
void extix_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;

    gpio_init_struct.Pin = GPIO_PIN_4;            /* KEY0 引脚 */
    gpio_init_struct.Mode = GPIO_MODE_IT_FALLING; /* 下升沿触发 */
    gpio_init_struct.Pull = GPIO_PULLUP;          /* 上拉 */
    HAL_GPIO_Init(GPIOE, &gpio_init_struct);      /* KEY0 引脚初始化 */

    gpio_init_struct.Pin= GPIO_PIN_3;             /* KEY1 引脚 */
    gpio_init_struct.Mode = GPIO_MODE_IT_FALLING; /* 下升沿触发 */
    gpio_init_struct.Pull = GPIO_PULLUP;          /* 上拉 */
    HAL_GPIO_Init(GPIOE, &gpio_init_struct);      /* KEY1 引脚初始化 */

    gpio_init_struct.Pin = GPIO_PIN_0;            /* WKUP 引脚 */
    gpio_init_struct.Mode = GPIO_MODE_IT_RISING;  /* 上升沿触发 */
    gpio_init_struct.Pull = GPIO_PULLDOWN;        /* 下拉 */
    HAL_GPIO_Init(GPIOA, &gpio_init_struct);      /* WKUP 引脚初始化 */

    HAL_NVIC_SetPriority(EXTI4_IRQn, 0, 2);    /* 抢占 0,子优先级 2 */
    HAL_NVIC_EnableIRQ(EXTI4_IRQn);            /* 使能中断线 4 */
    HAL_NVIC_SetPriority(EXTI3_IRQn, 1, 2);    /* 抢占 1,子优先级 2 */
    HAL_NVIC_EnableIRQ(EXTI3_IRQn);            /* 使能中断线 3 */
    HAL_NVIC_SetPriority(EXTI0_IRQn, 3, 2);    /* 抢占 2,子优先级 2 */
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);            /* 使能中断线 0 */
}

         中断函数:

/**
* @brief KEY0 外部中断服务程序
* @param 无
* @retval 无
*/
void KEY0_INT_IRQHandler(void)
{
    /* 调用中断处理公用函数 清除 KEY0 所在中断线 的中断标志位 */
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
    /* HAL 库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_4);
}


/**
* @brief KEY1 外部中断服务程序
* @param 无
* @retval 无
*/
void KEY1_INT_IRQHandler(void)
{
    /* 调用中断处理公用函数 清除 KEY1 所在中断线 的中断标志位 */
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);
    /* HAL 库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_3);
}


/**
* @brief WK_UP 外部中断服务程序
* @param 无
* @retval 无
*/
void WKUP_INT_IRQHandler(void)
{
    /* 调用中断处理公用函数 清除 KEY_UP 所在中断线 的中断标志位 */
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
    /* HAL 库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);
}

        中断回调函数:

/**
* @brief 中断服务程序中需要做的事情
 在 HAL 库中所有的外部中断服务函数都会调用此函数
* @param GPIO_Pin:中断引脚号
* @retval 无
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    delay_ms(20); /* 消抖 */

    switch(GPIO_Pin)
    {
        case GPIO_PIN_4:
        if (KEY0 == 0)
        {
            LED0_TOGGLE(); /* LED0 状态取反 */
            LED1_TOGGLE(); /* LED1 状态取反 */
        }
        break;

        case GPIO_PIN_3:
        if (KEY1 == 0)
        {
            LED0_TOGGLE(); /* LED0 状态取反 */
        }
        break;

        case GPIO_PIN_0:
        if (WK_UP == 1)
        {
            LED1_TOGGLE(); /* LED1 状态取反 */
        }
        break;
    }
}

        按下对应按键,执行对应回调函数,主函数只需要初始化 “extix_init(); ”,不需要调用。

<think>好的,用户想了解如何在HAL库中使用RTC中断,需要教程示例代码。首先,我得回忆一下STM32的RTC模块相关知识。RTC通常用于实时时钟功能,包括时间日期记录、闹钟周期性唤醒中断等。用户提到的HAL库,说明他们可能在使用CubeMX进行配置,这简化了初始化流程。 接下来,用户需要的是中断使用方法。RTC的中断类型可能有秒更新中断、闹钟中断、唤醒中断等。根据引用内容,引用[1]提到了秒更新中断的示例,引用[2]详细说明了RTC功能,包括时间设置闹钟,引用[3]则涉及HAL库初始化闹钟关闭问题。这些引用应该能帮助构建答案。 首先,应该分步骤讲解如何配置RTC中断使用CubeMX配置是常见做法,所以第一步是CubeMX的设置,包括启用RTC时钟源,配置日期时间格式,并启用相关的中断,比如秒更新或者闹钟中断。这里需要确保用户正确选择了时钟源,比如LSE或LSI,并配置预分频器。 然后是生成代码后的初始化步骤,可能需要用户手动开启中断,并编写中断回调函数。HAL库中,中断处理通常通过HAL_RTC_Init()函数,之后需要调用HAL_RTC_EnableIRQ()来开启中断。同时,用户需要重写对应的回调函数,比如HAL_RTCEx_RTCEventCallback()用于秒更新中断,或者HAL_RTC_AlarmAEventCallback()用于闹钟中断。 示例代码部分,需要提供初始化代码、中断回调函数,以及主循环中的处理。例如,在秒中断回调中,用户可以更新时间显示或执行其他任务。同时,要注意中断优先级配置,避免与其他中断冲突。 可能的问题点包括时钟源配置错误导致RTC不工作,中断未正确启用,或者回调函数没有正确重写。需要提醒用户检查这些部分。此外,引用[3]提到HAL_RTC_Init()的使用,需要确保初始化顺序正确,并在必要时重新配置闹钟或其他功能。 用户可能还关心如何设置闹钟中断,所以在相关部分可以加入闹钟配置的示例,比如使用HAL_RTC_SetAlarm_IT()函数,并处理其回调。同时,引用[2]提到不同型号的STM32可能有差异,建议用户查阅具体芯片手册。 最后,生成相关问题,可能包括如何调整RTC精度、处理唤醒中断、低功耗模式下的使用等。这些都是RTC常见应用场景,帮助用户进一步探索。</think>### STM32 HAL库RTC中断使用教程 #### 一、CubeMX基础配置 1. **启用RTC时钟源** - 在`RCC`配置中选择LSE(外部低速晶振)或LSI(内部低速RC振荡器)作为RTC时钟源 - 配置预分频器(Asynchronous Prescaler)实现1Hz时钟基准 2. **设置中断参数** - 在RTC配置界面勾选`Activate Clock Source``Activate Calendar` - 启用`RTC global interrupt`(NVIC设置中) 示例配置路径: ```c RTC_HandleTypeDef hrtc; // RTC句柄声明 ``` #### 、关键代码实现 1. **中断服务函数重写** ```c // 秒更新中断回调函数 void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc) { static uint8_t counter = 0; counter++; if(counter >= 60) { // 每分钟执行的操作 counter = 0; } } ``` 2. **中断使能函数** ```c // 在初始化后调用 HAL_RTCEx_EnableIT(&hrtc, RTC_IT_SEC); // 启用秒中断 ``` #### 三、完整代码流程 ```c /* 1. 系统初始化 */ HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_RTC_Init(); // CubeMX生成的初始化函数 /* 2. 中断优先级设置 */ HAL_NVIC_SetPriority(RTC_IRQn, 0, 0); HAL_NVIC_EnableIRQ(RTC_IRQn); /* 3. 主循环 */ while (1) { // 其他应用逻辑 HAL_Delay(1000); } ``` #### 四、调试要点 1. 使用`__HAL_RTC_SECOND_GET_FLAG()`函数验证秒中断标志 2. 通过STM32CubeMonitor实时监控RTC寄存器状态 3. 注意后备域供电(VBAT引脚连接)对RTC数据保持的影响[^2]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无敌暴龙战士朵拉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值