二、中断使用

目录

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(); ”,不需要调用。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

无敌暴龙战士朵拉

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

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

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

打赏作者

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

抵扣说明:

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

余额充值