了解外部中断(EXTI)功能

         监测指定的GPIO口,当电平产生变化时,EXTI向NVIC发出中断申请,NVIC裁决后中断CPU的程序。

AFIO(数据选择器)选择PAx,PBx,PCx….中的一个引脚接入EXIT的通道x上,所以相同的pin口不能同时触发中断

  • 配置步骤 

    1. 配置RCC,把涉及到的始终外设打开,让时钟可以工作
    2. 配置GPIO,让端口设置为输入模式
    3. 配置AFIO,选择使用的GPIO,连接到EXTI
    4. 配置EXTI,选择边沿触发方式(上升沿低变高、下降沿高变低、双边沿、软件手动),选择触发响应方式(中断响 应、事件响应)
    5. 配置NVIC,给中断一个合适的优先级,通过NVIC中断就可进入到 CPU,CPU收到信号,跳转到对应的中断函数执行中断程序
     配置RCC
    /*开启时钟*/
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);		//开启GPIOB的时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);		//开启AFIO的时钟,外部中断必须开启AFIO的时钟
     配置GPIO

    EXTI 推荐使用浮空、上拉、下拉输入

    /*GPIO初始化*/
    	GPIO_InitTypeDef GPIO_InitStructure;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOB, &GPIO_InitStructure);				
    		//将PB14引脚初始化为上拉输入
    配置AFIO

    GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

    配置AFIO的数据选择器,来选择想要的中断引脚 (选择用作EXTI线的GPIO引脚。)

                                           (    GPIO_PortSourceGPIOX,GPIO_PinSourceX   )

                                            (  哪个GPIO上的中断源, 第几个引脚中断                   )

    	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
    //将外部中断的14号线映射到GPIOB,即选择PB14为外部中断引脚
    

    AFIO的第14个数据选择器被定义:输入端为GPIOB的PB14引脚

                                                             输出端为EXTI的第14个中断线路(下面EXTI来选)

    配置EXTI

     EXTI_DeInit(void);

    把EXTI的配置清除,恢复成上电默认的状态

    EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

    初始化EXTI外设(自己定义的结构体的地址)

    EXTI_InitTypeDef EXTI_InitStructure;	
                //定义结构体变量的名字
    	EXTI_InitStructure.EXTI_Line = EXTI_Line14;	
                //选择配置外部中断的14号线  
    	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
                 //指定外部中断线使能   中断线的新状态
    	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
                //指定外部中断线为中断模式   也可以是事件模式_Event
    	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;	
                //指定外部中断线为下降沿触发    也可是上升沿触发_Rising
    	
    EXTI_Init(&EXTI_InitStructure);		
                //将结构体变量的地址交给EXTI_Init,配置EXTI外设

    EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);

    可以把参数中的结构体变量赋值成一个默认值(结构体)

    EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);

           直接 手动   软件触发外部中断(中断线)

    FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);

    获得指定的标志位是否被置1 (中断线)

    EXTI_ClearFlag(uint32_t EXTI_Line);

    对置1的标志位进行清除(中断线)

    EXTI_ClearITPendingBit(EXTI_Line14);	//清除外部中断14号线的中断标志位
    

     EXTI_GetITStatus(uint32_t EXTI_Line);

    获取中断标志位是否被置1  (中断线)

    EXTI_GetITStatus(EXTI_Line14) == SET
    //返回SET或者RESET

    EXTI_ClearITPendingBit(uint32_t EXTI_Line);

    清除中断挂起标志位 (中断线)

    EXTI_ClearITPendingBit(EXTI_Line14);

    配置NVIC

    NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

    中断分组(抢占优先级和响应优先级)  (NVIC_PriortyGroup_X)

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);		
    //配置NVIC为分组2
    																
    //即抢占优先级范围:0~3,响应优先级范围:0~3
    																
    //此分组配置在整个工程中仅需调用一次
    																
    //若有多个中断,可以把此代码放在main函数内,while循环之前
    																
    //若调用多次配置分组的代码,则后执行的配置会覆盖先执行的配置
    	

    NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

            根据结构体里面的值初始化NVIC 

        NVIC_InitTypeDef NVIC_InitStructure;						
                //定义结构体变量 名字
    	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;	
    	        //选择配置NVIC的EXTI15_10线        10-15都在这里
    	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				
                //指定NVIC线路使能
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;	
                //指定NVIC线路的抢占优先级为1  0-15
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;			
                //指定NVIC线路的响应优先级为1  0-15
    	
        NVIC_Init(&NVIC_InitStructure);								
                //将结构体变量地址交给NVIC_Init,配置NVIC外设
    

    void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);

            设置中断向量表

    void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);

            系统低功耗配置

    void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);
     

     定义中断函数

    EXTI15_10_IRQHandler();

    此函数为中断函数,无需调用,中断触发后自动执行
      *           函数名为预留的指定名称,可以从启动文件复制
      *           请确保函数名正确,不能有任何差异,否则中断函数将不能进入

    void EXTI15_10_IRQHandler(void)
    {                                               //因为10-15号中断线都可触发
    	if (EXTI_GetITStatus(EXTI_Line14) == SET) //判断是否是外部中断14号线触发的中断
    	{
    		/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
    		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)
    		{
    			这是要执行的函数!!!
    		}
    		EXTI_ClearITPendingBit(EXTI_Line14);	//清除外部中断14号线的中断标志位
    										//中断标志位必须清除
    									//否则中断将连续不断地触发,导致主程序卡死
    	}
    }

    作者:氵羊——

    物联沃分享整理
    物联沃-IOTWORD物联网 » 了解外部中断(EXTI)功能

    发表回复