使用PB1作为外部中断触发,按一次按键灯处于亮状态,在按一次灯灭。
1、先配置GPIO端口、复用管脚外设时钟使能GPIO_Config();
void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//PB1复用管脚时钟使能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12| GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//配置推挽输出,灯太亮,刺眼,故意把配置OD门,亮度暗一点
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//由于配置OD输出,顾这要上拉
GPIO_Init(GPIOD,&GPIO_InitStructure); //配置PB1管脚作为触发输入,因为PB1管脚直接接开关按钮到地,所以内部上拉让其管脚处于高电平状态,当开关按下时,PB1管脚被拉低,通过下降沿进行触发
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
2、配置嵌套向量中断控制NVIC_Config(void),使用不同通道时得注意,EXTI0~EXTI4对应的是EXTI0_IRQn、EXTI1_IRQn、EXTI2_IRQn、EXTI3_IRQn和EXTI4_IRQn,EXTI5~EXTI9都用EXTI9_5_IRQn这个通道,EXTI10~EXTI15都用EXTI15_10_IRQn这个通道。
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure; #ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; //由于使用的是PB1,对应的是EXTI1通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //中断使能
NVIC_Init(&NVIC_InitStructure);
}
3、中断管脚配置EXTI_Config(void)
void EXTI_Config(void)
{
EXTI_InitTypeDef EXTI_InitStructure; //PB1作为外部中断,得相连接
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB,EXTI_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);
}
5、主函数调用上面几个函数
int main(void)
{
Clock_Config();
GPIO_Config();
NVIC_Config();
EXTI_Config(); while ()
{ }
}
6、找中断函数名,函数名都已固定好,可以到startup_stm32f2xx.s中查找相关中断函数名,这里用的是EXTI1_IRQHandler()
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD ; Reserved
DCD ; Reserved
DCD ; Reserved
DCD ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler ; External Interrupts
DCD WWDG_IRQHandler ; Window WatchDog
DCD PVD_IRQHandler ; PVD through EXTI Line detection
DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line
DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line
DCD FLASH_IRQHandler ; FLASH
DCD RCC_IRQHandler ; RCC
DCD EXTI0_IRQHandler ; EXTI Line0
DCD EXTI1_IRQHandler ; EXTI Line1 //这里有,把EXTI1_IRQHandler 拷贝下来
DCD EXTI2_IRQHandler ; EXTI Line2
DCD EXTI3_IRQHandler ; EXTI Line3
DCD EXTI4_IRQHandler ; EXTI Line4
7、写中断函数,把拷贝的函数名copy到stm32f2xx_it.c文件中的任意位置
int flag = ;//定义全局变量
void EXTI1_IRQHandler()
{
EXTI_ClearITPendingBit(EXTI_Line1); //清除中断挂起位,方便下次中断进入,因中断产生,该位会自动置位,所以这里得手动清除
if(!flag)
{
flag = ~flag;
GPIO_SetBits(GPIOD,GPIO_Pin_12);
GPIO_SetBits(GPIOD,GPIO_Pin_13);
GPIO_SetBits(GPIOD,GPIO_Pin_14);
GPIO_SetBits(GPIOD,GPIO_Pin_15);
}
else
{
flag = ~flag;
GPIO_ResetBits(GPIOD, GPIO_Pin_12);
GPIO_ResetBits(GPIOD, GPIO_Pin_13);
GPIO_ResetBits(GPIOD, GPIO_Pin_14);
GPIO_ResetBits(GPIOD, GPIO_Pin_15);
}
}
OK,到此,中断处理函数就写好了,按一次按键灯处于亮状态,在按一次灯灭