stm32之外部中断EXTI

来源:互联网 发布:怎么禁止装软件 编辑:程序博客网 时间:2024/06/05 19:22
  • EXTI (External interrupt) 就是指外部中断,通过GPIO检测输入脉冲,引起中断事件,打断原来的代码执行流程,进入到中断服务函数中进行处理,处理完后,再返回到中断之前的代码中执行。
  • STM32的中断
    Cortex内核具有强大的异常响应系统,它把能够打断当前代码执行流程的事件分为异常(exception)和中断(interrupt),并把它们用一个表管理起来,编号为0~15的称为内核异常,而16以上的则称为外部中断(外,相对内核而言),这个表就称为中断向量表。 
    而STM32对这个表重新进行了编排,把编号从-3至6的中断向量定义为系统异常,编号为负 的内核异常不能被设置优先级,如复位(Reset)、不可屏蔽中断 (NMI)、硬错误(Hardfault)。从编号7开始的为外部中断,这些中断的优先级都是可以自行设置的。
    中断向量表





  • NVIC中断控制器
    STM32的中断如此之多,配置起来并不容易,因此,我们需要一个强大而方便的中断控制器NVIC (Nested Vectored Interrupt Controller)。NVIC是属于Cortex内核的器件,不可屏蔽中断 (NMI)和外部中断都由它来处理,而SYSTICK不是由NVIC来控制的。
    NVIC结构成员
    NVIC_IRQChannel                                              需要配置的中断向量 
    NVIC_IRQChannelCmd                                    使能或关闭相应中断向量的中断响应 
    NVIC_IRQChannelPreemptionPriority   配置相应中断向量抢占优先级 
    NVIC_IRQChannelSubPriority   配置相应中断向量的响应优先级 
    抢占优先级和响应优先级
    STM32的中断向量具有两个属性,一个为抢占属性,另一个为响应属性,其属性编号越小,表明它的优先级别越高。 
    抢占,是指打断其它中断的属性,即因为具有这个属性,会出现嵌套中断(在执行中断服务函数A的过程中被中断B打断,执行完中断服务函数B再继续执行中断服务函数A),抢占属性由NVIC_IRQChannelPreemptionPriority的参数配置。 而响应属性则应用在抢占属性相同的情况下,当两个中断向量的抢占优先级相同时,如果两个中断同时到达,则先处理响应优先级高的中断,响应属性由NVIC_IRQChannelSubPriority的参数配置。
    例如,现在有三个中断向量: 
    中断向量  抢占优先级  响应优先级 
        A 0    0 
        B   1  0 
        C   1  1 
    若内核正在执行C的中断服务函数,则它能被抢占优先级更高的中断A断,由于B和C的抢占优先级相同,所以C不能被B打断。但如果B和C中是同时到达的,内核就会首先响应响应优先级别更高的B中断。  
    NVIC的优先级组 
    在配置优先级的时候,还要注意一个很重要的问题,中断种类的数量。NVIC只可以配置16种 中断向量的优先级,也就是说,抢占优先级和响应优先级的数量由一个4位的数字来决定,把这个4位数字的位数 分配成抢占优先级部分和响应优先级部分。
  • EXTI外部中断


    PAx~PGx端口的中断事件都连接到了EXTIx,即同一时刻EXTx只能相应一个端口的事件触发,不能够同一时间响应所有GPIO端口的事件,但可以分时复用。它可以配置为上升沿触发,下降沿触发或双边沿触发。




  • 按键中断实例
    实验要求:
    按K2对应LED2亮灭变化,按K3对应LED3亮灭变化.
    exti.h
    #ifndef __EXTI_H#define __EXTI_H#include "stm32f10x.h"void EXTI_Config(void);#endif

    exti.c
    #include "exti.h"//:配置嵌套向量中断控制器NVICstatic void NVIC_Configuration(void){  NVIC_InitTypeDef NVIC_InitStructure;    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//配置PC2为中断源  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;//配置PC3为中断源  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  NVIC_Init(&NVIC_InitStructure);}//:配置 中断模式void EXTI_Config(void){GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO,ENABLE);NVIC_Configuration();  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入  GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入  GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2); GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource3);   EXTI_InitStructure.EXTI_Line = EXTI_Line2;  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿中断  EXTI_InitStructure.EXTI_LineCmd = ENABLE;  EXTI_Init(&EXTI_InitStructure); EXTI_InitStructure.EXTI_Line = EXTI_Line3;  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿中断  EXTI_InitStructure.EXTI_LineCmd = ENABLE;  EXTI_Init(&EXTI_InitStructure); }

    stm32f10x_it.c
    #include "stm32f10x_it.h"extern u8 temp;void EXTI2_IRQHandler(void){  if(EXTI_GetITStatus(EXTI_Line2) != RESET)  //判别是否有键按下  {    temp=2;      //按键中断标志    EXTI_ClearITPendingBit(EXTI_Line2);  //清除中断请求标志  }}void EXTI3_IRQHandler(void){  if(EXTI_GetITStatus(EXTI_Line3) != RESET)  //判别是否有键按下  {    temp=3;      //按键中断标志    EXTI_ClearITPendingBit(EXTI_Line3);  //清除中断请求标志  }}
    main.c
    #include "stm32f10x.h"#include "exti.h"#include "led.h"u8 temp = 0x0;u8 num = 0x0;u8 flag2 = 0x1;u8 flag3 = 0x1;void Delay(__IO uint32_t nCount){  for(; nCount != 0; nCount--);}int main(void){LED_GPIO_Config();LED2( ON ); LED3( ON );EXTI_Config(); while(1)                            {if(temp == 2)//响应exti2{if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)==0){Delay(0x2ffff);while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)==0);flag2 = (~flag2)&0x01;LED2( flag2 );}temp = 0;}if(temp == 3)//响应exti3{if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0){Delay(0x2ffff);while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0);flag3 = (~flag3)&0x01;LED3( flag3 );}temp=0;}}}


0 0
原创粉丝点击