中断小结:(用独立键盘控制LED的亮灭)
#include "stm32f10x.h" #include "stm32f10x_exti.h" #include "stm32f10x_rcc.h" #include "misc.h" unsigned char _it0=0,num=0; void RCC_Configuration(void); //时钟使能 void RCC_Configuration(void) { SystemInit(); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE,ENABLE); } void NVIC_Configuration(void);//nVIc使能 void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; NVIC_PriorityGroupConfig (NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel =EXTI9_5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //外部中断2 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能 NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel =EXTI3_IRQn; //外部中断9-5 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级1 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能 NVIC_Init(&NVIC_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5); GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource2); GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource3); EXTI_InitStructure.EXTI_Line =EXTI_Line5|EXTI_Line2|EXTI_Line3; EXTI_InitStructure.EXTI_Mode =EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger =EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd =ENABLE; EXTI_Init(&EXTI_InitStructure); } void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; // GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHZ; GPIO_Init(GPIOD,&GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_5); GPIO_SetBits(GPIOD,GPIO_Pin_6|GPIO_Pin_3); GPIO_InitStructure.GPIO_Pin =GPIO_Pin_2|GPIO_Pin_5|GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU; GPIO_Init(GPIOC,&GPIO_InitStructure); } void Delay(__IO uint32_t nCount) { for(; nCount != 0; nCount--); } void numm(void){ num=0; if(_it0==1){ //按键按下标志 if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==0){ //K1 Delay(0x3ffff); if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==0){ //按键消抖动 while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==0);//是否松开按键 num=1; //键值1 为K1按下 } } } else if(_it0==2){ //按键按下标志 if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)==0){ //K2 Delay(0x3ffff); if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)==0){ //按键消抖动 while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)==0);//是否松开按键 num=2; //键值2 为K2按下 } } } else if(_it0==3){ //按键按下标志 if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0){ //K3 Delay(0x3ffff); if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0){ //按键消抖动 while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0);//是否松开按键 num=3; //键值3 为K3按下 } } } _it0=0; } int main(void) { unsigned char a=0,b=0,c=0; RCC_Configuration(); //系统时钟设置及外设时钟使能 NVIC_Configuration(); /*对控制3个LED指示灯的IO口进行了初始化,将3个端口配置为推挽上拉输出,口线速度为50Mhz。 将中断线PC5,PC2,PC3配置为输入模式。(后面数字不能相同,相同的在一个中断单元中) 在配置某个口线时,首先应对它所在的端口的时钟进行使能。否则无法配置成功,由于用到了端口B和端口D,C,E, 因此要对这4个端口的时钟进行使能,同时由于用到复用IO口功能用于配置外部中断。因此还要使能AFIO(复用功能IO)时钟。*/ GPIO_Configuration(); while (1) { numm(); //键盘扫描程序 if(num==1&&a==0){GPIO_ResetBits(GPIOB, GPIO_Pin_5);a=1;} //K1 按下作处理 else if(num==1&&a==1){GPIO_SetBits(GPIOB, GPIO_Pin_5);a=0;} if(num==2&&b==0){GPIO_ResetBits(GPIOD, GPIO_Pin_6);b=1;} //K2 按下作处理 else if(num==2&&b==1){GPIO_SetBits(GPIOD, GPIO_Pin_6);b=0;} if(num==3&&c==0){GPIO_ResetBits(GPIOD, GPIO_Pin_3);c=1;} //K3 按下作处理 else if(num==3&&c==1){GPIO_SetBits(GPIOD, GPIO_Pin_3);c=0;} } }
/**************************************************************************** * 名 称:void EXTI9_5_IRQHandler(void) * 功 能:EXTI9-5中断处理程序 * 入口参数:无 * 出口参数:无 * 说 明: * 调用方法:无 ****************************************************************************/ void EXTI9_5_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line5) != RESET) //判别是否有键按下 { _it0=1; //按键中断标志 EXTI_ClearITPendingBit(EXTI_Line5); //清除中断请求标志 } } /**************************************************************************** * 名 称:void EXTI2_IRQHandler(void) * 功 能:EXTI2中断处理程序 * 入口参数:无 * 出口参数:无 * 说 明: * 调用方法:无 ****************************************************************************/ void EXTI2_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line2) != RESET) //判别是否有键按下 { _it0=2; //按键中断标志 EXTI_ClearITPendingBit(EXTI_Line2); //清除中断请求标志 } } /**************************************************************************** * 名 称:void EXTI3_IRQHandler(void) * 功 能:EXTI3中断处理程序 * 入口参数:无 * 出口参数:无 * 说 明: * 调用方法:无 ****************************************************************************/ void EXTI3_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line3) != RESET) //判别是否有键按下 { _it0=3; //按键中断标志 EXTI_ClearITPendingBit(EXTI_Line3); //清除中断请求标志 } }
extern unsigned char _it0;