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

发布时间:2024年01月20日

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

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

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); 对中断标志位进行清零。

文章来源:https://blog.csdn.net/weixin_57021249/article/details/135582998
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。