关于Keil5配置EXIT外部中断的问题(我怀疑是不是keil5软件的BUG呢????)

我之前从未遇到过的问题,反复对比了代码,以为是自己眼睛瞎掉了,查了大半天也没查出来是哪里的问题,今天一早进行反复对比,发现了惊人的秘密。。。。。

开始是这样的,我通过keil5配置了外部中断,Init_CS1238AD函数体内部代码如下:

	GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	EXTI_InitTypeDef EXTI_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);  

	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_1|GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; 
	GPIO_Init(GPIOA, &GPIO_InitStructure);
		
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;      
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource1);
  	EXTI_InitStructure.EXTI_Line=EXTI_Line1;
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  	EXTI_Init(&EXTI_InitStructure);	  	

  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource5);
  	EXTI_InitStructure.EXTI_Line=EXTI_Line5;
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  	EXTI_Init(&EXTI_InitStructure);	  

  	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;	
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;		
  	NVIC_Init(&NVIC_InitStructure);

  	NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;	
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;				
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;					
  	NVIC_Init(&NVIC_InitStructure);

然而,程序死活也进入不了中断,对比了正点原子的代码(正点原子代码是将GPIO初始化和EXIT初始化分别放到了两个函数里面),等同于我上面的代码,也没有对比出问题来,可算把我眼睛丑瞎了也没有瞅出问题来。。。。。

后来排查发现惊人的秘密!!!!!!!!!!!!!!!!!!!!!

1、在同一个函数初始化GPIO和外部中断时,将定义

	GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	EXTI_InitTypeDef EXTI_InitStructure;

EXIT的结构体放到最前面就可以进入中断了!(我怀疑是不是Keil5的问题呢,我用IAR的时候没有出现定义先后的问题,而且对于定义一个局部变量,有那么强的要求规则吗?不懂!)。改完如下:

	EXTI_InitTypeDef EXTI_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

 这样就可以了。。。。。不知为什么????!!!!

2、将GPIO的初始化和EXIT的初始化,放到两个函数里面,然后统一调用两个初始化函数,也是可以的!代码如下:

void BSP_GPIO_Init(void)
{
		GPIO_InitTypeDef GPIO_InitStructure;
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

		GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_1|GPIO_Pin_5;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;   
		GPIO_Init(GPIOA, &GPIO_InitStructure);
		
		GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;      
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
		GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void BSP_EXIT_Init(void)
{
	EXTI_InitTypeDef EXTI_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource1);
	EXTI_InitStructure.EXTI_Line=EXTI_Line1;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStructure);	  


	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource5);
	EXTI_InitStructure.EXTI_Line=EXTI_Line5;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStructure);	  	
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;			
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;				
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;						
	NVIC_Init(&NVIC_InitStructure);

	NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;		
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;				
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;							
	NVIC_Init(&NVIC_InitStructure);	
}
void Init_CS1238AD(void)
{
	BSP_GPIO_Init();
	BSP_EXIT_Init();
}

哎……反正就是这样就可以了……

另外附上 一个STM32的外部中断开启关闭某一外部中断的操作吧……

void CS1238DATA_EXIT_ENABLE(void)
{
	EXTI->IMR |= EXTI_Line1;
}
void CS1238DATA_EXIT_DISABLE(void)
{
	EXTI->IMR &= ~(EXTI_Line1);
}

猜你喜欢

转载自blog.csdn.net/zhengshifeng123/article/details/119052563