发 帖  
原厂入驻New

[经验] 简单讲下外部中断(1)【带程序和框图】

2020-8-31 07:56:11  225 外部中断 ARM STM32
分享
2
一、ARM Cortex-M4的中断体系
1、定义 中断,意味着中途打断现在干的事情,要处理紧急的事情。
1.png
二、嵌套向量中断控制寄存器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 唤醒事件
2.png
3.库函数a.选择对应的GPIO引脚连接到相应的中断控制线
  1. /**
  2.   * [url=home.php?mod=space&uid=2666770]@Brief[/url]  Selects the GPIO pin used as EXTI Line.
  3.   * [url=home.php?mod=space&uid=3142012]@param[/url]  EXTI_PortSourceGPIOx : selects the GPIO port to be used as source for
  4.   *          EXTI lines where x can be (A..K) for STM32F42xxx/43xxx devices, (A..I)
  5.   *          for STM32F405xx/407xx and STM32F415xx/417xx devices or (A, B, C, D and H)
  6.   *          for STM32401xx devices.  
  7.   *            
  8.   * @param  EXTI_PinSourcex: specifies the EXTI line to be configured.
  9.   *           This parameter can be EXTI_PinSourcex where x can be (0..15, except
  10.   *           for EXTI_PortSourceGPIOI x can be (0..11) for STM32F405xx/407xx
  11.   *           and STM32F405xx/407xx devices and for EXTI_PortSourceGPIOK x can   
  12.   *           be (0..7) for STM32F42xxx/43xxx devices.
  13.   *            
  14.   * @retval None
  15.   */
  16. void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex)
复制代码
b.根据EXTI_InitTypeDef结构体进行外部中断控制线0初始化
  1. /**
  2.   * @brief  Initializes the EXTI peripheral according to the specified
  3.   *         parameters in the EXTI_InitStruct.
  4.   * @param  EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure
  5.   *         that contains the configuration information for the EXTI peripheral.
  6.   * @retval None
  7.   */
  8. void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
复制代码
c.根据NVIC_InitTypeDef结构体对中断向量进行配置
  1. /**
  2.   * @brief  Initializes the NVIC peripheral according to the specified
  3.   *         parameters in the NVIC_InitStruct.
  4.   * [url=home.php?mod=space&uid=1902110]@NOTE[/url]   To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() //执行NVIC_Init前,必须调用NVIC_PriorityGroupConfig
  5.   *         function should be calLED before.
  6.   * @param  NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains
  7.   *         the configuration information for the specified NVIC peripheral.
  8.   * @retval None
  9.   */
  10. void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
复制代码
  1. #include <stdio.h>
  2. #include "stm32f4xx.h"
  3. #include "sys.h"

  4. GPIO_InitTypeDef   GPIO_InitStructure;

  5. EXTI_InitTypeDef   EXTI_InitStructure;

  6. NVIC_InitTypeDef   NVIC_InitStructure;

  7. void delay(void)
  8. {
  9.     int i=0x500000;
  10.    
  11.     while(i--);
  12. }


  13. int main(void)
  14. {

  15.     RCC_AHB1PeriphclockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOF, ENABLE);

  16.     /* Enable SYSCFG clock ,使能系统配置时钟*/
  17.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

  18.     /* Connect EXTI Line0 to PA0 pin,将PA0引脚连接到外部中断控制线0 */
  19.     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
  20.    
  21.    

  22.     /* 配置PF9引脚为输出模式 */
  23.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                    //第9根引脚
  24.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                //设置输出模式
  25.     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                //推挽模式,增加驱动电流
  26.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;            //设置IO的速度为100MHz,频率越高性能越好,频率越低,功耗越低
  27.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;            //不需要上拉电阻
  28.     GPIO_Init(GPIOF, &GPIO_InitStructure);

  29.     /*    PA0 引脚配置为输入模式 */
  30.     GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0 ;
  31.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  32.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  33.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  34.     GPIO_Init(GPIOA, &GPIO_InitStructure);
  35.    
  36.    
  37.     /* Configure EXTI Line0,配置外部中断控制线0 */
  38.     EXTI_InitStructure.EXTI_Line = EXTI_Line0;                        //当前使用外部中断控制线0
  39.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;                //中断模式
  40.     EXTI_InitStructure.EXTI_trigger = EXTI_Trigger_Rising;            //上升沿,也意味着按键松开的时候才触发中断
  41.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;                        //使能外部中断控制线0,让外部中断控制线0工作
  42.     EXTI_Init(&EXTI_InitStructure);

  43.     /* Enable and set EXTI Line0 Interrupt to the lowest priority */
  44.     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                //允许外部中断控制线0触发中断
  45.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;    //抢占优先级为0xF
  46.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;            //响应优先级为0xF
  47.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能
  48.     NVIC_Init(&NVIC_InitStructure);
  49.    
  50.    
  51.     while(1)
  52.     {



  53.     }

  54. }

  55. void EXTI0_IRQHandler(void)
  56. {
  57.     //检查当前外部中断控制线0是否触发中断
  58.     if(EXTI_GetITStatus(EXTI_Line0) == SET)
  59.     {
  60.         
  61.         //添加用户代码
  62.         PFout(9)=0;
  63.         delay();
  64.         
  65.         PFout(9)=1;
  66.         delay();        
  67.      
  68.         /* Clear the EXTI line 0 pending bit,清空外部中断控制线0标志位,告诉CPU我已经完成当前中断请求,可以继续响应下一次的中断请求 */
  69.         EXTI_ClearITPendingBit(EXTI_Line0);
  70.     }
  71. }
复制代码
  1. #include <stdio.h>
  2. #include "stm32f4xx.h"
  3. #include "sys.h"

  4. GPIO_InitTypeDef   GPIO_InitStructure;

  5. EXTI_InitTypeDef   EXTI_InitStructure;

  6. NVIC_InitTypeDef   NVIC_InitStructure;

  7. void delay(void)
  8. {
  9.     int i=0x500000;
  10.    
  11.     while(i--);
  12. }


  13. int main(void)
  14. {

  15.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOF, ENABLE);

  16.     /* Enable SYSCFG clock ,使能系统配置时钟*/
  17.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

  18.     /* Connect EXTI Line0 to PA0 pin,将PA0引脚连接到外部中断控制线0 */
  19.     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
  20.    
  21.    

  22.     /* 配置PF9引脚为输出模式 */
  23.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                    //第9根引脚
  24.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                //设置输出模式
  25.     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                //推挽模式,增加驱动电流
  26.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;            //设置IO的速度为100MHz,频率越高性能越好,频率越低,功耗越低
  27.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;            //不需要上拉电阻
  28.     GPIO_Init(GPIOF, &GPIO_InitStructure);

  29.     /*    PA0 引脚配置为输入模式 */
  30.     GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0 ;
  31.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  32.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  33.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  34.     GPIO_Init(GPIOA, &GPIO_InitStructure);
  35.    
  36.    
  37.     /* Configure EXTI Line0,配置外部中断控制线0 */
  38.     EXTI_InitStructure.EXTI_Line = EXTI_Line0;                        //当前使用外部中断控制线0
  39.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;                //中断模式
  40.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;            //上升沿,也意味着按键松开的时候才触发中断
  41.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;                        //使能外部中断控制线0,让外部中断控制线0工作
  42.     EXTI_Init(&EXTI_InitStructure);

  43.     /* Enable and set EXTI Line0 Interrupt to the lowest priority */
  44.     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                //允许外部中断控制线0触发中断
  45.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;    //抢占优先级为0xF
  46.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;            //响应优先级为0xF
  47.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能
  48.     NVIC_Init(&NVIC_InitStructure);
  49.    
  50.    
  51.     while(1)
  52.     {



  53.     }

  54. }

  55. void EXTI0_IRQHandler(void)
  56. {
  57.     //检查当前外部中断控制线0是否触发中断
  58.     if(EXTI_GetITStatus(EXTI_Line0) == SET)
  59.     {
  60.         
  61.         //添加用户代码
  62.         PFout(9)=0;
  63.         delay();
  64.         
  65.         PFout(9)=1;
  66.         delay();        
  67.      
  68.         /* Clear the EXTI line 0 pending bit,清空外部中断控制线0标志位,告诉CPU我已经完成当前中断请求,可以继续响应下一次的中断请求 */
  69.         EXTI_ClearITPendingBit(EXTI_Line0);
  70.     }
  71. }
复制代码
3.png
4、中断优先级中断优先级的一个意义:出现多个中断同时触发,但是不能同时处理,所以先后顺序之分,要根据实际上的运行环境优先处理重要的中断。
a.概述
STM32对中断进行分组,共5组,组0~4。同时,对每个中断设置一个抢占优先级和一个响应优先级级
函数原型如下:
  1. /**
  2.   * @brief  Configures the priority grouping: pre-emption priority and subpriority.
  3.   * @param  NVIC_PriorityGroup: specifies the priority grouping bits length.
  4.   *   This parameter can be one of the following values:
  5.   *     [url=home.php?mod=space&uid=2583231]@arg[/url] NVIC_PriorityGroup_0: 0 bits for pre-emption priority  //没有抢占优先级
  6.   *                                4 bits for subpriority   //4位设置响应优先级
  7.   *     @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority  //1位抢占优先级,能设置2个中断抢占优先级
  8.   *                                3 bits for subpriority   //3位设置响应优先级
  9.   *     @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority  //2位抢占优先级,能设置4个中断抢占优先级
  10.   *                                2 bits for subpriority   //2位设置响应优先级
  11.   *     @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority  //3位抢占优先级,能设置8个中断抢占优先级
  12.   *                                1 bits for subpriority   //1位设置响应优先级
  13.   *     @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority  //4位抢占优先级,能设置16个中断抢占优先级
  14.   *                                0 bits for subpriority   //没有响应优先级
  15.   * @note   When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible.
  16.   *         The pending IRQ priority will be managed only by the subpriority.
  17.   * @retval None
  18.   */
  19. void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
复制代码
只要开机初始化一次就可以了。

b.抢占优先级与响应优先级区别
1)高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
2)抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
3)抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
4)无论是抢占优先级还是响应优先级,优先级数值越小,就代表优先级越高。
4.png
如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;
例:假定设置中断优先级组为2,然后设置中断3(RTC中断)的抢占优先级为2,响应优先级为1。
中断6(外部中断0)的抢占优先级为3,响应优先级为0。中断7(外部中断1)的抢占优先级为2,响应优先级为0。
                                
   中断7>中断3>中断6。
  1. #include <stdio.h>
  2. #include "stm32f4xx.h"
  3. #include "sys.h"

  4. GPIO_InitTypeDef   GPIO_InitStructure;

  5. EXTI_InitTypeDef   EXTI_InitStructure;

  6. NVIC_InitTypeDef   NVIC_InitStructure;

  7. __IO uint32_t TimingDelay;

  8. void delay(void)
  9. {
  10.     int i=0x5000000;
  11.    
  12.     while(i--);
  13. }

  14. void TimingDelay_Decrement(void)//滴答时钟的中断函数
  15. {
  16.     if (TimingDelay != 0)
  17.     {
  18.      TimingDelay--;
  19.     }
  20. }


  21. void Delay(__IO uint32_t nTime)//延时函数
  22. {

  23.     TimingDelay = nTime;

  24.     while(TimingDelay != 0);
  25. }


  26. int main(void)
  27. {

  28.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOF, ENABLE);

  29.     /* Enable SYSCFG clock ,使能系统配置时钟*/
  30.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

  31.     /* Connect EXTI Line0 to PA0 pin,将PA0引脚连接到外部中断控制线0 */
  32.     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
  33.    
  34.     /* Connect EXTI Line2 to PE2 pin,将PE2引脚连接到外部中断控制线2 */
  35.     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);
  36.    
  37.     /* Connect EXTI Line3 to PE3 pin,将PE3引脚连接到外部中断控制线3 */
  38.     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);

  39.     /* Connect EXTI Line4 to PE4 pin,将PE4引脚连接到外部中断控制线4 */
  40.     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);   
  41.    
  42.    
  43.    
  44.     /*    PA0 引脚配置为输入模式 */
  45.     GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0 ;
  46.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  47.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  48.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  49.     GPIO_Init(GPIOA, &GPIO_InitStructure);

  50.     /*    PE2 PE3 PE4 引脚配置为输入模式 */
  51.     GPIO_InitStructure.GPIO_Pin =GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4 ;
  52.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  53.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  54.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  55.     GPIO_Init(GPIOE, &GPIO_InitStructure);

  56.     /* Configure PF9 PF10 in output pushpull mode,配置PF9 PF10引脚为输出模式 */
  57.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;        //第9根和10根引脚
  58.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                //设置输出模式
  59.     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                //推挽模式,增加驱动电流
  60.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;            //设置IO的速度为100MHz,频率越高性能越好,频率越低,功耗越低
  61.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;            //不需要上拉电阻
  62.     GPIO_Init(GPIOF, &GPIO_InitStructure);

  63.    
  64.     /* Configure PE13 PE14 in output pushpull mode,配置PE13 PE14引脚为输出模式 */
  65.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14;        //第13根和14根引脚
  66.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                //设置输出模式
  67.     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                //推挽模式,增加驱动电流
  68.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;            //设置IO的速度为100MHz,频率越高性能越好,频率越低,功耗越低
  69.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;            //不需要上拉电阻
  70.     GPIO_Init(GPIOE, &GPIO_InitStructure);   
  71.    
  72.    
  73.     /* Configure EXTI Line0 2 3 4,配置外部中断控制线0 2 3 4*/
  74.     EXTI_InitStructure.EXTI_Line = EXTI_Line0|EXTI_Line2|EXTI_Line3|EXTI_Line4;                        //当前使用外部中断控制线0 2 3 4
  75.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;                //中断模式
  76.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;            //上升沿,也意味着按键松开的时候才触发中断
  77.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;                        //使能外部中断控制线0 2 3 4 ,让外部中断控制线0 2 3 4工作
  78.     EXTI_Init(&EXTI_InitStructure);

  79.     //配置中断优先级的分组
  80.     //配置支持4个抢占优先级,支持4个响应优先级
  81.    
  82.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  83.    
  84.     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                //允许外部中断控制线0触发中断
  85.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;    //抢占优先级为0x3,最低优先级
  86.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;            //响应优先级为0x3,最低优先级
  87.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能
  88.     NVIC_Init(&NVIC_InitStructure);
  89.    
  90.     //中断优先级数值越大,优先级就越小
  91.     //数值0,优先级是最高
  92.    
  93.     NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;                //允许外部中断控制线2触发中断
  94.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级为0x3,最低优先级
  95.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;            //响应优先级为0x3,最低优先级
  96.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能
  97.     NVIC_Init(&NVIC_InitStructure);


  98.     NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;                //允许外部中断控制线3触发中断
  99.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;    //抢占优先级为0x3,最低优先级
  100.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;            //响应优先级为0x3,最低优先级
  101.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能
  102.     NVIC_Init(&NVIC_InitStructure);
  103.    

  104.     NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;                //允许外部中断控制线4触发中断
  105.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;    //抢占优先级为0x3,最低优先级
  106.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;            //响应优先级为0x3,最低优先级
  107.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能
  108.     NVIC_Init(&NVIC_InitStructure);   
  109.    
  110.     PFout(9)=1;
  111.     PFout(10)=1;   
  112.     PEout(13)=1;
  113.     PEout(14)=1;

  114.     if(SysTick_Config(SystemCoreClock / 1000))    //1ms中断一次
  115.     {
  116.       /* Capture error */
  117.       while (1);//写初值成功---则进入while死循环-等待滴答时钟的中断到来
  118.     }
  119.    
  120.     while(1)
  121.     {



  122.     }

  123. }

  124. void EXTI0_IRQHandler(void)
  125. {
  126.     //检查当前外部中断控制线0是否触发中断
  127.     if(EXTI_GetITStatus(EXTI_Line0) == SET)
  128.     {
  129.         
  130.         //添加用户代码
  131.         PFout(9)=0;
  132.         Delay(1000);//delay();
  133.         
  134.         PFout(9)=1;
  135.         delay();        
  136.      
  137.         /* Clear the EXTI line 0 pending bit,清空外部中断控制线0标志位,告诉CPU我已经完成当前中断请求,可以继续响应下一次的中断请求 */
  138.         EXTI_ClearITPendingBit(EXTI_Line0);
  139.     }
  140. }


  141. void EXTI2_IRQHandler(void)
  142. {
  143.     //检查当前外部中断控制线2是否触发中断
  144.     if(EXTI_GetITStatus(EXTI_Line2) == SET)
  145.     {
  146.         
  147.         //添加用户代码
  148.         PFout(10)=0;
  149.         delay();
  150.         
  151.         PFout(10)=1;
  152.         delay();        
  153.      
  154.         /* 清空外部中断控制线2标志位,告诉CPU我已经完成当前中断请求,可以继续响应下一次的中断请求 */
  155.         EXTI_ClearITPendingBit(EXTI_Line2);
  156.     }
  157. }

  158. void EXTI3_IRQHandler(void)
  159. {
  160.     //检查当前外部中断控制线3是否触发中断
  161.     if(EXTI_GetITStatus(EXTI_Line3) == SET)
  162.     {
  163.         
  164.         //添加用户代码
  165.         PEout(13)=0;
  166.         delay();
  167.         
  168.         PEout(13)=1;
  169.         delay();        
  170.      
  171.         /* 清空外部中断控制线3标志位,告诉CPU我已经完成当前中断请求,可以继续响应下一次的中断请求 */
  172.         EXTI_ClearITPendingBit(EXTI_Line3);
  173.     }
  174. }


  175. void EXTI4_IRQHandler(void)
  176. {
  177.     //检查当前外部中断控制线4是否触发中断
  178.     if(EXTI_GetITStatus(EXTI_Line4) == SET)
  179.     {
  180.         
  181.         //添加用户代码
  182.         PEout(14)=0;
  183.         delay();
  184.         
  185.         PEout(14)=1;
  186.         delay();        
  187.      
  188.         /* 清空外部中断控制线4标志位,告诉CPU我已经完成当前中断请求,可以继续响应下一次的中断请求 */
  189.         EXTI_ClearITPendingBit(EXTI_Line4);
  190.     }
  191. }

  192. exti0234
复制代码
5.png
c.注意事项

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

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

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

注:
启动文件startup_stm32f40_41xxx.s看汇编代码
系统时钟SysTick,Cortex M3与M4权威指南.pdf P313
定时器TIM,STM32F4xx中文参考手册.pdf P392
https://www.cnblogs.com/worldsing/p/3433529.html








相关经验

评论

高级模式
您需要登录后才可以回帖 登录 | 注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
发经验
关闭

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

快速回复 返回顶部 返回列表