STM32之外部中断

作者: paranoid 分类: STM32 发布时间: 2021-07-22 11:37

一、什么是中断

中断是指通过硬件来改变CPU的运行方向。单片机在行程序的过程中,外部设备向CPU发出中断请求信号,要求CPU暂时中断当前程序的执行而转去抗行相应的处理程序,待处理程序执行完毕后,再继续执行原来被中断的程序。这种程序在执行过程中由于外界的原因而被中间打断的情况称为“中断”。

💡 大概就是能开小差,突然有个什么事更急,就放下手上的事,完成急事后,回来继续完成之前的事情。

二、中断管理方法NVIC

分组配置是在寄存器SCB->AIRCR中配置

AIRCR[10:8] IP bit[7:4]
分配情况
分配结果
0 111 0 : 4 0位抢占优先级, 4位响应优先级
1 110 1 : 3 1位抢占优先级, 3位响应优先级
2 101 2 : 2 2位抢占优先级, 2位响应优先级
3 100 3 : 1 3位抢占优先级, 1位响应优先级
4 011 4 : 0 4位抢占优先级, 0位响应优先级

💡 分配结果中的位数表示的是二进制,如2位表示2²,可写0, 1, 2, 3。

抢占优先级 Vs 响应优先级

  1. 高优先级的抢占优先级可以打断正在进行的低抢占优先级中断。

    注意: 值越小说明级越高。

  2. 抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。

  3. 抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。

  4. 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先抗行。

特别强调

一般情况下,系统代码执行过程中,只设置一次中断优先级分组,设置好分组之后,一般不会再改变分组。

随意改变分组会导致已经编写好的程序中断管理混乱,程序出现意想不到的执行结果。

三、外部中断

  1. 加入外部中断固件库 stm32f10x_exti.c

  2. HARDWARE中的中断模块EXTI.c编写

    1. 使用外部中断,需要开启复用时钟

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    2. 中断线映射

      GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
    3. 中断初始化函数 EXTI_Init(&EXTI_InitStructure);

      参数 代码 可选
      中断线 EXTI_Line EXTI_Line0~19
      中断模式 EXTI_Mode EXTI_Mode_Interrupt 外部中断
      EXTI_Mode_Event 事件中断
      触发方式 EXTI_Trigger 上升沿、下降沿
      上升/下降沿同时触发
      使能 EXTI_LineCmd ENABLE / DISABLE
    4. 配置NVIC优先级 NVIC_Init(&NVIC_InitStructure)

      参数 代码 可选
      中断请求通道 NVIC_IRQChannel EXTIx_IRQn
      抢占优先级 NVIC_IRQChannelPreemptionPriority 0x00~0x0n
      响应优先级 NVIC_IRQChannelSubPriority 0x00~0x0n
      使能 NVIC_IRQChannelCmd ENABLE / DISABLE
    5. 外部中断服务程序函数编写void EXTIx_IRQHandler(void)

      void EXTI0_IRQHandler(void)
      {
          delay_ms(10);//消抖
          if(WK_UP==1)         //WK_UP按键
          {                
              BEEP=!BEEP; 
          }
          EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位  
      }
  3. 主函数main.c中的使用(主循环外)

    1. 设置NVIC中断分组 NVIC_PriorityGroupConfig();
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
    //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    1. 外部中断初始化
    EXTIX_Init();

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

发表评论

邮箱地址不会被公开。