STM32上PB3作为外部中断IO口无法正常使用
问题描述:
通过按键外部中断来控制蜂鸣器,当使用PB3作为中断IO口时,不管怎么样都控制不了。仿真发现根本就没有进入外部中断服务函数
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PB3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //PB3设置成输入,
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB
}
void key_exti(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
KEY_Init(); // 按键端口初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能时钟
/***************************************************************
** 功能: KEY6初始化函数
** 参数: GPIOB3
** 返回值:
****************************************************************/
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource3);
EXTI_InitStructure.EXTI_Line=EXTI_Line3;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI3_IRQHandler(void)
{
Delay(3000);//消抖
if(key6==0)
{
KEEP_ON;
}
EXTI_ClearITPendingBit(EXTI_Line3); //清除LINE3上的中断标志位
}
原因分析:
在网上查了很多资料,绝大多数都提到了GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);并且说明了函数调用的顺序要非常严谨
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE)
我自己尝试了很多次也没有成功
解决方案:
在尝试过程中,我无意间将另外一个按键的初始化函数调用了出来,然后PB3突然就可以正常使用了!!!!
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//PA1
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU; //设置成上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PB3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //PB3设置成输入,
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB
}
void key_exti(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
KEY_Init(); // 按键端口初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能时钟
/***************************************************************
** 功能: KEY1初始化函数
** 参数: GPIOA1
** 返回值:
****************************************************************/
//GPIOA.1
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_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/***************************************************************
** 功能: KEY6初始化函数
** 参数: GPIOB3
** 返回值:
****************************************************************/
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource3);
EXTI_InitStructure.EXTI_Line=EXTI_Line3;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
就很莫名其妙,突然就成功了,有大佬给我解释一下嘛。