查看: 983|回复: 0

[经验] 深度刨析影响外部中断的原因都有哪些(1)【带程序和框图】

[复制链接]
  • TA的每日心情
    开心
    2019-11-4 13:48
  • 签到天数: 14 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2020-8-31 09:01:49 | 显示全部楼层 |阅读模式
    分享到:
    一、ARM Cortex-M4的中断体系
    1、定义 中断,意味着中途打断现在干的事情,要处理紧急的事情。

    二、嵌套向量中断控制寄存器STM32F4xx中文参考手册中文参考手册.pdf P233~P243
    1、NVIC特性无论是ARM Cortex M0/M3/M4 还是 ARM Cortex-A8/A53/A72/A73等等内核,都有NVIC。
    STM32F405xx/07xx 和 STM32F415xx/17xx 具有 82 个可屏蔽(能够通过代码进行开和关中断)中断通道,10个不可屏蔽(无法通过代码关闭该中断)的中断,16 个可编程优先级。
    向量意味就是中断源。
    向量表,也就是中断源表。
    2、外部中断/事件控制器 (EXti)多达 140 个 GPIO(STM32F405xx/07xx 和 STM32F415xx/17xx)通过以下方式连接到 16 个外部中断/事件线:
    另外七根 EXTI 线连接方式如下:
    ● EXTI 线 16 连接到 PVD 输出
    ● EXTI 线 17 连接到 RTC 闹钟事件
    ● EXTI 线 18 连接到 USB OTG FS 唤醒事件
    ● EXTI 线 19 连接到以太网唤醒事件
    ● EXTI 线 20 连接到 USB OTG HS(在 FS 中配置)唤醒事件
    ● EXTI 线 21 连接到 RTC 入侵和时间戳事件
    ● EXTI 线 22 连接到 RTC 唤醒事件

    3.库函数a.选择对应的GPIO引脚连接到相应的中断控制线
    • /**
    •   * @Brief  Selects the GPIO pin used as EXTI Line.
    •   * @param  EXTI_PortSourceGPIOx : selects the GPIO port to be used as source for
    •   *          EXTI lines where x can be (A..K) for STM32F42xxx/43xxx devices, (A..I)
    •   *          for STM32F405xx/407xx and STM32F415xx/417xx devices or (A, B, C, D and H)
    •   *          for STM32401xx devices.
    •   *
    •   * @param  EXTI_PinSourcex: specIFies the EXTI line to be configured.
    •   *           This parameter can be EXTI_PinSourcex where x can be (0..15, except
    •   *           for EXTI_PortSourceGPIOI x can be (0..11) for STM32F405xx/407xx
    •   *           and STM32F405xx/407xx devices and for EXTI_PortSourceGPIOK x can
    •   *           be (0..7) for STM32F42xxx/43xxx devices.
    •   *
    •   * @retval None
    •   */
    • void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex)

    [color=rgb(51, 102, 153) !important]复制代码

    b.根据EXTI_InitTypeDef结构体进行外部中断控制线0初始化
    • /**
    •   * @brief  Initializes the EXTI peripheral according to the specified
    •   *         parameters in the EXTI_InitStruct.
    •   * @param  EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure
    •   *         that contains the configuration information for the EXTI peripheral.
    •   * @retval None
    •   */
    • void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)

    [color=rgb(51, 102, 153) !important]复制代码

    c.根据NVIC_InitTypeDef结构体对中断向量进行配置
    • /**
    •   * @brief  Initializes the NVIC peripheral according to the specified
    •   *         parameters in the NVIC_InitStruct.
    •   * @NOTE   To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() //执行NVIC_Init前,必须调用NVIC_PriorityGroupConfig
    •   *         function should be calLED before.
    •   * @param  NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains
    •   *         the configuration information for the specified NVIC peripheral.
    •   * @retval None
    •   */
    • void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)

    [color=rgb(51, 102, 153) !important]复制代码

    • #include <stdio.h>
    • #include "stm32f4xx.h"
    • #include "sys.h"
    • GPIO_InitTypeDef   GPIO_InitStructure;
    • EXTI_InitTypeDef   EXTI_InitStructure;
    • NVIC_InitTypeDef   NVIC_InitStructure;
    • void delay(void)
    • {
    •     int i=0x500000;
    •     while(i--);
    • }
    • int main(void)
    • {
    •     RCC_AHB1PeriphclockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOF, ENABLE);
    •     /* Enable SYSCFG clock ,使能系统配置时钟*/
    •     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    •     /* Connect EXTI Line0 to PA0 pin,将PA0引脚连接到外部中断控制线0 */
    •     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
    •     /* 配置PF9引脚为输出模式 */
    •     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                    //第9根引脚
    •     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                //设置输出模式
    •     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                //推挽模式,增加驱动电流
    •     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;            //设置IO的速度为100MHz,频率越高性能越好,频率越低,功耗越低
    •     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;            //不需要上拉电阻
    •     GPIO_Init(GPIOF, &GPIO_InitStructure);
    •     /*    PA0 引脚配置为输入模式 */
    •     GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0 ;
    •     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    •     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    •     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    •     GPIO_Init(GPIOA, &GPIO_InitStructure);
    •     /* Configure EXTI Line0,配置外部中断控制线0 */
    •     EXTI_InitStructure.EXTI_Line = EXTI_Line0;                        //当前使用外部中断控制线0
    •     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;                //中断模式
    •     EXTI_InitStructure.EXTI_trigger = EXTI_Trigger_Rising;            //上升沿,也意味着按键松开的时候才触发中断
    •     EXTI_InitStructure.EXTI_LineCmd = ENABLE;                        //使能外部中断控制线0,让外部中断控制线0工作
    •     EXTI_Init(&EXTI_InitStructure);
    •     /* Enable and set EXTI Line0 Interrupt to the lowest priority */
    •     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                //允许外部中断控制线0触发中断
    •     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;    //抢占优先级为0xF
    •     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;            //响应优先级为0xF
    •     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能
    •     NVIC_Init(&NVIC_InitStructure);
    •     while(1)
    •     {
    •     }
    • }
    • void EXTI0_IRQHandler(void)
    • {
    •     //检查当前外部中断控制线0是否触发中断
    •     if(EXTI_GetITStatus(EXTI_Line0) == SET)
    •     {
    •         //添加用户代码
    •         PFout(9)=0;
    •         delay();
    •         PFout(9)=1;
    •         delay();
    •         /* Clear the EXTI line 0 pending bit,清空外部中断控制线0标志位,告诉CPU我已经完成当前中断请求,可以继续响应下一次的中断请求 */
    •         EXTI_ClearITPendingBit(EXTI_Line0);
    •     }
    • }

    [color=rgb(51, 102, 153) !important]复制代码

    • #include <stdio.h>
    • #include "stm32f4xx.h"
    • #include "sys.h"
    • GPIO_InitTypeDef   GPIO_InitStructure;
    • EXTI_InitTypeDef   EXTI_InitStructure;
    • NVIC_InitTypeDef   NVIC_InitStructure;
    • void delay(void)
    • {
    •     int i=0x500000;
    •     while(i--);
    • }
    • int main(void)
    • {
    •     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOF, ENABLE);
    •     /* Enable SYSCFG clock ,使能系统配置时钟*/
    •     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    •     /* Connect EXTI Line0 to PA0 pin,将PA0引脚连接到外部中断控制线0 */
    •     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
    •     /* 配置PF9引脚为输出模式 */
    •     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                    //第9根引脚
    •     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                //设置输出模式
    •     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                //推挽模式,增加驱动电流
    •     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;            //设置IO的速度为100MHz,频率越高性能越好,频率越低,功耗越低
    •     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;            //不需要上拉电阻
    •     GPIO_Init(GPIOF, &GPIO_InitStructure);
    •     /*    PA0 引脚配置为输入模式 */
    •     GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0 ;
    •     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    •     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    •     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    •     GPIO_Init(GPIOA, &GPIO_InitStructure);
    •     /* Configure EXTI Line0,配置外部中断控制线0 */
    •     EXTI_InitStructure.EXTI_Line = EXTI_Line0;                        //当前使用外部中断控制线0
    •     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;                //中断模式
    •     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;            //上升沿,也意味着按键松开的时候才触发中断
    •     EXTI_InitStructure.EXTI_LineCmd = ENABLE;                        //使能外部中断控制线0,让外部中断控制线0工作
    •     EXTI_Init(&EXTI_InitStructure);
    •     /* Enable and set EXTI Line0 Interrupt to the lowest priority */
    •     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                //允许外部中断控制线0触发中断
    •     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;    //抢占优先级为0xF
    •     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;            //响应优先级为0xF
    •     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能
    •     NVIC_Init(&NVIC_InitStructure);
    •     while(1)
    •     {
    •     }
    • }
    • void EXTI0_IRQHandler(void)
    • {
    •     //检查当前外部中断控制线0是否触发中断
    •     if(EXTI_GetITStatus(EXTI_Line0) == SET)
    •     {
    •         //添加用户代码
    •         PFout(9)=0;
    •         delay();
    •         PFout(9)=1;
    •         delay();
    •         /* Clear the EXTI line 0 pending bit,清空外部中断控制线0标志位,告诉CPU我已经完成当前中断请求,可以继续响应下一次的中断请求 */
    •         EXTI_ClearITPendingBit(EXTI_Line0);
    •     }
    • }

    [color=rgb(51, 102, 153) !important]复制代码


    4、中断优先级中断优先级的一个意义:出现多个中断同时触发,但是不能同时处理,所以先后顺序之分,要根据实际上的运行环境优先处理重要的中断。
    a.概述
    STM32对中断进行分组,共5组,组0~4。同时,对每个中断设置一个抢占优先级和一个响应优先级级。
    函数原型如下:
    • /**
    •   * @brief  Configures the priority grouping: pre-emption priority and subpriority.
    •   * @param  NVIC_PriorityGroup: specifies the priority grouping bits length.
    •   *   This parameter can be one of the following values:
    •   *     @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority  //没有抢占优先级
    •   *                                4 bits for subpriority   //4位设置响应优先级
    •   *     @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority  //1位抢占优先级,能设置2个中断抢占优先级
    •   *                                3 bits for subpriority   //3位设置响应优先级
    •   *     @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority  //2位抢占优先级,能设置4个中断抢占优先级
    •   *                                2 bits for subpriority   //2位设置响应优先级
    •   *     @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority  //3位抢占优先级,能设置8个中断抢占优先级
    •   *                                1 bits for subpriority   //1位设置响应优先级
    •   *     @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority  //4位抢占优先级,能设置16个中断抢占优先级
    •   *                                0 bits for subpriority   //没有响应优先级
    •   * @note   When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible.
    •   *         The pending IRQ priority will be managed only by the subpriority.
    •   * @retval None
    •   */
    • void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)

    [color=rgb(51, 102, 153) !important]复制代码

    只要开机初始化一次就可以了。

    b.抢占优先级与响应优先级区别
    1)高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
    2)抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
    3)抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
    4)无论是抢占优先级还是响应优先级,优先级数值越小,就代表优先级越高。

    如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;
    例:假定设置中断优先级组为2,然后设置中断3(RTC中断)的抢占优先级为2,响应优先级为1。
    中断6(外部中断0)的抢占优先级为3,响应优先级为0。中断7(外部中断1)的抢占优先级为2,响应优先级为0。
                                    
       中断7>中断3>中断6。
    • #include <stdio.h>
    • #include "stm32f4xx.h"
    • #include "sys.h"
    • GPIO_InitTypeDef   GPIO_InitStructure;
    • EXTI_InitTypeDef   EXTI_InitStructure;
    • NVIC_InitTypeDef   NVIC_InitStructure;
    • __IO uint32_t TimingDelay;
    • void delay(void)
    • {
    •     int i=0x5000000;
    •     while(i--);
    • }
    • void TimingDelay_Decrement(void)//滴答时钟的中断函数
    • {
    •     if (TimingDelay != 0)
    •     {
    •      TimingDelay--;
    •     }
    • }
    • void Delay(__IO uint32_t nTime)//延时函数
    • {
    •     TimingDelay = nTime;
    •     while(TimingDelay != 0);
    • }
    • int main(void)
    • {
    •     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOF, ENABLE);
    •     /* Enable SYSCFG clock ,使能系统配置时钟*/
    •     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    •     /* Connect EXTI Line0 to PA0 pin,将PA0引脚连接到外部中断控制线0 */
    •     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
    •     /* Connect EXTI Line2 to PE2 pin,将PE2引脚连接到外部中断控制线2 */
    •     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);
    •     /* Connect EXTI Line3 to PE3 pin,将PE3引脚连接到外部中断控制线3 */
    •     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);
    •     /* Connect EXTI Line4 to PE4 pin,将PE4引脚连接到外部中断控制线4 */
    •     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);
    •     /*    PA0 引脚配置为输入模式 */
    •     GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0 ;
    •     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    •     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    •     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    •     GPIO_Init(GPIOA, &GPIO_InitStructure);
    •     /*    PE2 PE3 PE4 引脚配置为输入模式 */
    •     GPIO_InitStructure.GPIO_Pin =GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4 ;
    •     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    •     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    •     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    •     GPIO_Init(GPIOE, &GPIO_InitStructure);
    •     /* Configure PF9 PF10 in output pushpull mode,配置PF9 PF10引脚为输出模式 */
    •     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;        //第9根和10根引脚
    •     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                //设置输出模式
    •     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                //推挽模式,增加驱动电流
    •     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;            //设置IO的速度为100MHz,频率越高性能越好,频率越低,功耗越低
    •     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;            //不需要上拉电阻
    •     GPIO_Init(GPIOF, &GPIO_InitStructure);
    •     /* Configure PE13 PE14 in output pushpull mode,配置PE13 PE14引脚为输出模式 */
    •     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14;        //第13根和14根引脚
    •     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                //设置输出模式
    •     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                //推挽模式,增加驱动电流
    •     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;            //设置IO的速度为100MHz,频率越高性能越好,频率越低,功耗越低
    •     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;            //不需要上拉电阻
    •     GPIO_Init(GPIOE, &GPIO_InitStructure);
    •     /* Configure EXTI Line0 2 3 4,配置外部中断控制线0 2 3 4*/
    •     EXTI_InitStructure.EXTI_Line = EXTI_Line0|EXTI_Line2|EXTI_Line3|EXTI_Line4;                        //当前使用外部中断控制线0 2 3 4
    •     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;                //中断模式
    •     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;            //上升沿,也意味着按键松开的时候才触发中断
    •     EXTI_InitStructure.EXTI_LineCmd = ENABLE;                        //使能外部中断控制线0 2 3 4 ,让外部中断控制线0 2 3 4工作
    •     EXTI_Init(&EXTI_InitStructure);
    •     //配置中断优先级的分组
    •     //配置支持4个抢占优先级,支持4个响应优先级
    •     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    •     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                //允许外部中断控制线0触发中断
    •     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;    //抢占优先级为0x3,最低优先级
    •     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;            //响应优先级为0x3,最低优先级
    •     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能
    •     NVIC_Init(&NVIC_InitStructure);
    •     //中断优先级数值越大,优先级就越小
    •     //数值0,优先级是最高
    •     NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;                //允许外部中断控制线2触发中断
    •     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级为0x3,最低优先级
    •     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;            //响应优先级为0x3,最低优先级
    •     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能
    •     NVIC_Init(&NVIC_InitStructure);
    •     NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;                //允许外部中断控制线3触发中断
    •     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;    //抢占优先级为0x3,最低优先级
    •     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;            //响应优先级为0x3,最低优先级
    •     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能
    •     NVIC_Init(&NVIC_InitStructure);
    •     NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;                //允许外部中断控制线4触发中断
    •     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;    //抢占优先级为0x3,最低优先级
    •     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;            //响应优先级为0x3,最低优先级
    •     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能
    •     NVIC_Init(&NVIC_InitStructure);
    •     PFout(9)=1;
    •     PFout(10)=1;
    •     PEout(13)=1;
    •     PEout(14)=1;
    •     if(SysTick_Config(SystemCoreClock / 1000))    //1ms中断一次
    •     {
    •       /* Capture error */
    •       while (1);//写初值成功---则进入while死循环-等待滴答时钟的中断到来
    •     }
    •     while(1)
    •     {
    •     }
    • }
    • void EXTI0_IRQHandler(void)
    • {
    •     //检查当前外部中断控制线0是否触发中断
    •     if(EXTI_GetITStatus(EXTI_Line0) == SET)
    •     {
    •         //添加用户代码
    •         PFout(9)=0;
    •         Delay(1000);//delay();
    •         PFout(9)=1;
    •         delay();
    •         /* Clear the EXTI line 0 pending bit,清空外部中断控制线0标志位,告诉CPU我已经完成当前中断请求,可以继续响应下一次的中断请求 */
    •         EXTI_ClearITPendingBit(EXTI_Line0);
    •     }
    • }
    • void EXTI2_IRQHandler(void)
    • {
    •     //检查当前外部中断控制线2是否触发中断
    •     if(EXTI_GetITStatus(EXTI_Line2) == SET)
    •     {
    •         //添加用户代码
    •         PFout(10)=0;
    •         delay();
    •         PFout(10)=1;
    •         delay();
    •         /* 清空外部中断控制线2标志位,告诉CPU我已经完成当前中断请求,可以继续响应下一次的中断请求 */
    •         EXTI_ClearITPendingBit(EXTI_Line2);
    •     }
    • }
    • void EXTI3_IRQHandler(void)
    • {
    •     //检查当前外部中断控制线3是否触发中断
    •     if(EXTI_GetITStatus(EXTI_Line3) == SET)
    •     {
    •         //添加用户代码
    •         PEout(13)=0;
    •         delay();
    •         PEout(13)=1;
    •         delay();
    •         /* 清空外部中断控制线3标志位,告诉CPU我已经完成当前中断请求,可以继续响应下一次的中断请求 */
    •         EXTI_ClearITPendingBit(EXTI_Line3);
    •     }
    • }
    • void EXTI4_IRQHandler(void)
    • {
    •     //检查当前外部中断控制线4是否触发中断
    •     if(EXTI_GetITStatus(EXTI_Line4) == SET)
    •     {
    •         //添加用户代码
    •         PEout(14)=0;
    •         delay();
    •         PEout(14)=1;
    •         delay();
    •         /* 清空外部中断控制线4标志位,告诉CPU我已经完成当前中断请求,可以继续响应下一次的中断请求 */
    •         EXTI_ClearITPendingBit(EXTI_Line4);
    •     }
    • }
    • exti0234

    [color=rgb(51, 102, 153) !important]复制代码


    c.注意事项

    1)一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2,设置好分组之后一般不会再改变分组。
    随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果。

    2)中断优先级设置步骤
    .系统运行后先设置中断优先级分组。调用函数:
    void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
    整个系统执行过程中,只设置一次中断分组。

    .针对每个中断,设置对应的抢占优先级和响应优先级:
    void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
    .如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。














    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条



    手机版|小黑屋|与非网

    GMT+8, 2025-1-13 13:41 , Processed in 0.109493 second(s), 15 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.