STM32自学笔记(三)外部中断

stm32每个IO口都可以作为外部中断输入口。F103支持共19个外部中断/事件请求。每个中断设有状态位,有独立的触发和屏蔽装置。STM32F103的19个外部中断为:

线0~15:对应IO口的输入中断

线16:连接到PVD输出

线17:连接到RTC时钟事件

线18:连接到USB唤醒事件

中断线与GPIO的映射

GPIO 的管脚 GPIOx.0~GPIOx.15(x=A,B,C,D,EF,G)分别对应中断线 0~15。这样每个中断线对应了最多 7 个 IO 口,以线 0 为例:它对应了 GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、 GPIOE.0、GPIOF.0、GPIOG.0。而中断线每次只能连接到一个IO口上,需要配置决定具体映射到哪个IO口。

通过函数 GPIO_EXTILineConfig() 配置GPIO与中断线的映射关系:

 GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2); 

这句代码将 中断线2 与 GPIOE 映射起来,显然就是GPIOE.2EXTI2中断线连接了.

外部中断的初始化

外部中断的初始化是通过函数 EXTI_Init() 实现的。配置过程与GPIO配置类似。以下是使用范例

  EXTI_InitTypeDef  EXTI_InitStructure;                   //实例化对象
  EXTI_InitStructure.EXTI_Line=EXTI_Line4;                //指定中断线4
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;     //中断
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发 
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;               //使能
  EXTI_Init(&EXTI_InitStructure);   //根据 EXTI_InitStruct 中指定的参数初始化外设EXTI寄存器上

既然是外部中断,涉及到中断就要设置NVIC中断优先级,这个不赘述了直接贴范例

  NVIC_InitTypeDef NVIC_InitStructure; 
  NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;             //使能按键外部中断通道 
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2 
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;        //响应优先级 2 
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;              //使能外部中断通道 
  NVIC_Init(&NVIC_InitStructure);                              //中断优先级分组初始化 

当然不能忘了在main()中进行中断总的分组

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置 NVIC 中断分组 2:2

中断服务函数

中断服务函数的名字是事先定义好的,共有6个,分别为:

  EXPORT  EXTI0_IRQHandler           
  EXPORT  EXTI1_IRQHandler        
  EXPORT  EXTI2_IRQHandler          
  EXPORT  EXTI3_IRQHandler         
  EXPORT  EXTI4_IRQHandler           
  EXPORT  EXTI9_5_IRQHandler         
  EXPORT  EXTI15_10_IRQHandler     
 

中断线0~4每条线对应一个中断函数

中断线5~9共用中断函数 EXTI9_5_IRQHandler

中断线10~15共用中断函数 EXTI15_10_IRQHandler

编写中断服务函数时常用到下面两个函数

  1. 判断某个中断线上的中断是否发生

      ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)

     

  2. 清除某个中断线上的中断标志位

      void EXTI_ClearITPendingBit(uint32_t EXTI_Line); 

    这个函数一般用在中断服务函数结束之前,清除中断的标志位

常用的中断服务函数格式为:

  void EXTI3_IRQHandler(void) 
  { 
      if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生     
      {   
          中断逻辑…   
          EXTI_ClearITPendingBit(EXTI_Line3);  //清除 LINE 上的中断标志位    
      }    
  } 

外部中断使用总结

使用IO口外部中断的一般步骤:(1~5步可以写在同一个函数中直接初始化好)

  1. 初始化IO口作为输入

    ......(将要用到的GPIO进行相应的初始化,这里不赘述了)

  2. 开启AFIO时钟

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);     //开启AFIO时钟

     

  3. 设置IO口与中断线的映射关系

      GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);  //将GPIOE.2作为外部中断

     

  4. 初始化线上中断,设置触发条件等

      EXTI_InitTypeDef  EXTI_InitStructure;                   //实例化对象
      EXTI_InitStructure.EXTI_Line=EXTI_Line4;                //指定中断线4
      EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;     //中断
      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发 
      EXTI_InitStructure.EXTI_LineCmd = ENABLE;               //使能
      EXTI_Init(&EXTI_InitStructure);             //根据指定的参数初始化外设EXTI寄存器

     

  5. 配置中断分组(NVIC),并使能中断

      NVIC_InitTypeDef NVIC_InitStructure; 
      NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;        //使能按键外部中断通道    
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2,     
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;   //子优先级 2    
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //使能外部中断通道 

     

  6. 编写中断服务函数

void EXTI3_IRQHandler(void) 
{ 
    if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生     
    {   
        中断逻辑…   
        EXTI_ClearITPendingBit(EXTI_Line3);  //清除 LINE 上的中断标志位    
    }    
}

 

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值