打印
[应用相关]

STM32基础-外部中断与优先级

[复制链接]
437|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
rzjvv|  楼主 | 2023-5-27 22:39 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
一,中断引脚

STM32F407有23个外部中断检测器,芯片多达 140 个 GPIO(STM32F405xx/07xx 和 STM32F415xx/17xx)通过以下方式连接到 16 个外部中断/事件线。如图所示

例如:PA0占用了EXTI0,其他PB0~PI0是不能使用的。


23个中断检测器中出来16个与引脚相连外,还有七个中断如下图。






使用特权

评论回复
沙发
rzjvv|  楼主 | 2023-5-27 22:39 | 只看该作者
二,软件配置中断

以A0为例配置外部中断,总共有如下步骤,1.打开外设时钟和系统配置时钟,2.初始化GPIO口

3.连接中断线  4.配置外部中断0  (EXTI_Mode有两种模式一种是中断模式,一种是事件模式。这里选中断模式)5.配置中断优先级。6.写中断服务函数。
// 初始化按键(外部中断)
void KEY_EXTI_Init(void)
{
        /* 1.打开外设时钟(为了低功耗,需要分别打开) */
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);   
                /* 打开系统配置时钟 */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

        /* 2.配置PA0,并初始化 */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                // 引脚
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;        // 模式:输入模式
        //GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;        // 输出类型(输入模式下,无效)
        //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;        // 端口速率(输入模式下,无效)
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;        // 上下拉选择:浮空
        GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        /* 3. PA0连接中断线0 */
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
       
        /* 4.配置外部中断0 */
        EXTI_InitStructure.EXTI_Line = EXTI_Line0;                                // 中断0
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;                // 中断模式
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发(按键按下)
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);
       
        /* 5.配置外部中断0的优先级 */
        NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;   //中断通道配置
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}

使用特权

评论回复
板凳
rzjvv|  楼主 | 2023-5-27 22:40 | 只看该作者
中断服务函数。
void EXTI0_IRQHandler(void)
{
        //if(EXTI_GetITStatus(EXTI_Line0) == SET)        // 是一样的
        if(EXTI_GetITStatus(EXTI_Line0) != RESET)
        {
                LED1 = ~LED1;

                /* 清空标志位,便于下次产生中断 */
                EXTI_ClearITPendingBit(EXTI_Line0);
        }
}

使用特权

评论回复
地板
rzjvv|  楼主 | 2023-5-27 22:40 | 只看该作者
注意:配置中断优先级时,要注意“NVIC_IRQChanne”,中断通道的配置,中断通道不同与中断线。是两个不同的东西。在STM32F407中,外部中断“0”到外部中断“4”有独立中断通道。外部中断5到外部中断9公用一个中断通道,外部中断10到外部中断15公用一个外部中断通道。当你想配置外部中断4以上的外部中断时,NVIC_IRQChanne配置参数有所变化,分别为EXTI9_5_IRQn(外部中断5到9),EXTI15_10_IRQn.中断服务函数的名字也改为void EXTI9_5_IRQHandler(void),与void EXTI15_10_IRQHandler(void).

思考:假如按键IO是 PE13 PE14,PE15,那么无论按下那个按键都会执行EXTI15_10_IRQHandler函数,那么咋判断是那个按键按下。

答案是:虽然公用中断通道,但中断线不同,在中断服务函数中用EXTI_GetITStatus(),判断是那条中断线触发。当然中断处理完毕后要清空中断,用EXTI_ClearITPendingBit()函数。

使用特权

评论回复
5
rzjvv|  楼主 | 2023-5-27 22:41 | 只看该作者
三.中断优先级

1.中断优先级分组函数,通常写在主函数当中,如下




// 中断优先级选择第2组:拥有4种抢占、4种响应。
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

一般选择第二组,因为他有四个抢占和四个响应可选,原因看下图。

使用特权

评论回复
6
rzjvv|  楼主 | 2023-5-27 22:42 | 只看该作者
2.抢占优先级与响应优先级(数字越小,级别越高)
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //中断通道配置
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级配置
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//响应优先级配置
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);

使用特权

评论回复
7
rzjvv|  楼主 | 2023-5-27 23:23 | 只看该作者
3.抢占优先级与响应优先级的区别

1)高抢占优先级是可以打断正在进行的低抢占优先级的中断。,抢占优先级若相同,则不会出现抢占的过程。

使用特权

评论回复
8
rzjvv|  楼主 | 2023-5-27 23:23 | 只看该作者
2)抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。先发生的函数执行完之后,在执行后发生的

使用特权

评论回复
9
rzjvv|  楼主 | 2023-5-27 23:46 | 只看该作者
3)抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行

使用特权

评论回复
10
rzjvv|  楼主 | 2023-5-27 23:56 | 只看该作者
4)抢占优先级和响应优先级完全相同的中断,假如同时发生,会按照硬件内部固定的优先级执行,如下图。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

204

帖子

1

粉丝