stm32f103c8t6外部中断及相关问题(HAL库)

(上述图片来自正点原子)

本次实验内容为利用按键触发外部中断,使得灯泡实现亮灭,并且观察不同优先级下中断的现象。

exti.c文件里,①初始化中断

void exti_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;                  /* 定义结构体 */
    
    __HAL_RCC_GPIOB_CLK_ENABLE();                       /* 使能时钟 */
    __HAL_RCC_GPIOA_CLK_ENABLE();                       /* 使能时钟 */
    
    gpio_init_struct.Pin = GPIO_PIN_0;                  /* 引脚配置 */
    gpio_init_struct.Mode = GPIO_MODE_IT_RISING;        /* 上升沿模式 */
    gpio_init_struct.Pull = GPIO_PULLDOWN;              /* 引脚下拉 */
    HAL_GPIO_Init(GPIOB, &gpio_init_struct);
    
    gpio_init_struct.Pin = GPIO_PIN_10;                 /* 引脚配置 */
    gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;       /* 下降沿模式 */
    gpio_init_struct.Pull = GPIO_PULLUP;                /* 引脚上拉 */
    HAL_GPIO_Init(GPIOA, &gpio_init_struct);
    
    HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 1);         /* 设置优先级,抢占优先级为0,响应优先级为1,先比较抢占再比较响应,数字越小级别越高,响应优先级高 */
    HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);                 /* 使能中断 */
    
    HAL_NVIC_SetPriority(EXTI0_IRQn, 1, 2);             /* 设置优先级,抢占优先级为1,响应优先级为2 */
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);                     /* 使能中断 */
}

注意事项:

(1)设定优先级时,HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority),32f103中IRQn只有七个,分别是EXTI0_IRQn,EXTI1_IRQn,EXTI2_IRQn,EXTI3_IRQn,EXTI4_IRQn,EXTI9_5_IRQn,EXTI15_10_IRQn,即0~4线是分开的,5~9与10~15是合并的,总共有7条中断线。

(2) 中断优先级比较规则:先比较抢占再比较响应,数字越小级别越高,响应优先级高。一次只能执行一个中断进程。

(3)设置上升沿有一个注意事项,JTAG是有默认几个引脚为上拉的,此时软件置为下拉将不起作用。SWD对应I/O引脚也有某些复用规则。如下图:

②中断回调处理机制:

当触发中断时,将跳转到下面函数

void EXTI15_10_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);        /* 调用中断处理公用函数GPIO_PIN_10清除所在中断线 的中断标志位,中断下半部在HAL_GPIO_EXTI_Callback执行 */
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_10);        /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
}

调用中断处理公用函数 清除GPIO_PIN_10所在中断线 的中断标志位,中断下半部在HAL_GPIO_EXTI_Callback执行。

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    delay_ms(20);
    

    switch(GPIO_Pin)
    {
        case GPIO_PIN_10:
            if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_10) == 1)
            {
                HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
                delay_ms(5000);
                HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
            }
            break;
        case GPIO_PIN_0:
            if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == 1)
            {
                HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_6);
            }
            break;
    }

}

执行完callback函数,回到 EXTI0_IRQHandler执行__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0); 对中断标志位进行清零。

  • 16
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

成为不掉头发的工程师

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

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

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

打赏作者

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

抵扣说明:

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

余额充值