STM32F429之外部中断

7个中断通道在NVRC中使用

7个中断服务函数EXPORT  EXTI9_5_IRQHandler     

22个中断线

中断源为任意想要连接的GPIO,用那个连哪个SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

配置NVRC—配置GPIO(打开SYSCFG时钟)—连接中断源到GPIO—配置中断EXTI—编写中断服务函数

具体如下

STM32F4的每个IO都可以作为外部中断的中断输入口,这点也是STM32F4的强大之处。STM32F407的中断控制器支持22个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F407的22个外部中断为:

EXTI线0~15:对应外部IO口的输入中断。

EXTI线16:连接到PVD输出。

EXTI线17:连接到RTC闹钟事件。

EXTI线18:连接到USB OTG FS唤醒事件。

扫描二维码关注公众号,回复: 1577626 查看本文章

EXTI线19:连接到以太网唤醒事件。

EXTI线20:连接到USB OTG HS(在FS中配置)唤醒事件。

EXTI线21:连接到RTC入侵和时间戳事件。

EXTI线22:连接到RTC唤醒事件。


GPIO跟中断线的映射关系图:

库函数配置外部中断的步骤:

1)      使能IO口时钟,初始化IO口为输入

    GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHB1PeriphClockCmd(KEY1_INT_GPIO_CLK|KEY2_INT_GPIO_CLK ,ENABLE);

  GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;
 
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;                

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);

2)      开启SYSCFG时钟,设置IO口与中断线的映射关系。

/*使用GPIO外部中断时必须使能SYSCFG时钟*/

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

配置GPIO与中断线的映射关系(连接中断源到GPIO引脚)

SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

将中断线0与GPIOA映射起来,那么很显然是GPIOA.0与EXTI0中断线连接了。

3)      初始化线上中断,设置触发条件等。

EXTI_InitTypeDef  EXTI_InitStructure;

EXTI_InitStructure.EXTI_Line=EXTI_Line4;  (选择中断源)(EXTI_Line0~EXTI_Line15)

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  (中断模式)(分为中断和事件event)

EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Falling;(下降沿触发)(上升沿触发Rising,任意电平触发Rising_Fallingr)

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

 EXTI_Init(&EXTI_InitStructure);             //初始化外设EXTI寄存器

上面的例子设置中断线4上的中断为下降沿触发。

4)      配置中断分组(NVIC),并使能中断。

设置中断线2的中断优先级。 在野火例程中,将NVRC设置成一个函数static void NVIC_Configuration(void) 在void EXTI_Key_Config(void)里调用。

NVIC_InitTypeDef  NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;  //使能按键外部中断通道中断线0-4每个中断线对应一个通道中断线5-9共用EXTI9_5_IRQ,中断线10-15共用EXTI15_10_IRQ

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;  //抢占优先级2,

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;             //响应优先级2

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                //使能外部中断通道

NVIC_Init(&NVIC_InitStructure);                          //中断优先级分组初始化

5)      编写中断服务函数。

中断服务函数的名字是在MDK中事先有定义的。这里需要说明一下,STM32F4的IO口外部中断函数只有7个,分别为:

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。

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

void EXTI3_IRQHandler(void)

{

if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生    

       { …中断逻辑…

        EXTI_ClearITPendingBit(EXTI_Line3);  //清除LINE上的中断标志位 

       }           

}

总结一下使用IO口外部中断的一般步骤:

1)使能IO口时钟,初始化IO口为输入。

2)使能SYSCFG时钟,设置IO口与中断线的映射关系。

3)初始化线上中断,设置触发条件等。

4)配置中断分组(NVIC),并使能中断。

5)编写中断服务函数。

简单例程如下

#include "stm32f4xx.h"
#include "stm32f4xx_exti.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_syscfg.h"

void main(void)
{
config();//初始化
while(1);

}



void config(void)
{
   //中断IO口初始化
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);   //
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	//GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOD, &GPIO_InitStructure);  

//中断初始化
EXTI_InitTypeDef EXTI_InitStructure;

	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource13);
	EXTI_ClearITPendingBit(EXTI_Line13);
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;	
	EXTI_InitStructure.EXTI_Line = EXTI_Line13;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);

//中断配置初始化
	/* Configures the nested vectored interrupt controller. */
	NVIC_InitTypeDef NVIC_InitStructure;

	/* Enable the USARTx Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
}



//中断函数
void EXTI15_10_IRQHandler(void)	
{
	
	if( EXTI_GetITStatus(EXTI_Line13) != RESET )
	{
		EXTI_ClearITPendingBit(EXTI_Line13);//清中断
	}
}
 


猜你喜欢

转载自blog.csdn.net/duidaifen3896/article/details/79552973
今日推荐