stm32正点原子学习笔记(28)外部中断
同一时间,只能有一个IO口映射到中断线,例如,当PA0做了外部中断0时,PB0等就不能作为外部中断0了。
main.c
1 #include "exti.h" 2 3 int main(void) 4 { 5 delay_init(); 6 LedInit(); 7 Exti_Init(); 8 9 while(1) 10 { 11 12 } 13 }
led.c
1 #include"led.h" 2 3 void LedInit() 4 { 5 GPIO_InitTypeDef GPIO_InitStructure; 6 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOA,ENABLE); //使能PD/PA端口时钟 7 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出 8 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1-->PD.2 端口配置 9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz 10 GPIO_Init(GPIOD, &GPIO_InitStructure); //初始化GPIOD.2 11 LED1on; 12 13 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //LED0-->PA.8 端口配置 14 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOD.2 15 LED0off; 16 }
led.h
1 #ifndef __LED_H 2 #define __LED_H 3 4 #include<stm32f10x.h> 5 6 #define LED1on GPIO_ResetBits(GPIOD,GPIO_Pin_2) 7 #define LED1off GPIO_SetBits(GPIOD,GPIO_Pin_2) 8 #define LED0on GPIO_ResetBits(GPIOA,GPIO_Pin_8) 9 #define LED0off GPIO_SetBits(GPIOA,GPIO_Pin_8) 10 11 #define LED0 PAout(8)// PA8 12 #define LED1 PDout(2)// PD2 13 14 void LedInit(void); 15 16 17 #endif
key.c
1 #include"key.h" 2 3 //按键初始化函数 4 void KEY_Init(void) //IO初始化 5 { 6 GPIO_InitTypeDef GPIO_InitStructure; 7 8 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);//使能PORTA,PORTC时钟 9 10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_13;//KEY0-KEY1 11 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入 12 GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC1、13 13 14 //初始化 WK_UP-->GPIOA.0 下拉输入 15 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 16 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉 17 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0 18 19 } 20 21 unsigned char KEY_Scan(unsigned char mode) 22 { 23 static u8 key_up=1;//按键按松开标志 24 if(mode)key_up=1; //支持连按 25 if(key_up&&(KEY0==0||KEY1==0||WK_UP==1)) 26 { 27 delay_ms(10);//去抖动 28 key_up=0; 29 if(KEY0==0)return KEY0_PRES; 30 else if(KEY1==0)return KEY1_PRES; 31 else if(WK_UP==1)return WKUP_PRES; 32 } 33 else if(KEY0==1&&KEY1==1&&WK_UP==0) 34 key_up=1; 35 return 0;// 无按键按下 36 }
key.h
1 #ifndef __KEY_H 2 #define __KEY_H 3 4 #include"sys.h" 5 #include"delay.h" 6 7 #define KEY0 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1)//读取按键0 8 #define KEY1 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)//读取按键1 9 10 #define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键3(WK_UP) 11 12 #define KEY0_PRES 1 //KEY0按下 13 #define KEY1_PRES 2 //KEY1按下 14 15 #define WKUP_PRES 4 //KEY_UP按下(即WK_UP/KEY_UP) 16 17 void KEY_Init(void);//IO初始化 18 u8 KEY_Scan(u8 mode); 19 20 #endif
exti.c
1 #include "exti.h" 2 3 void Exti_Init() 4 { 5 // GPIO_InitTypeDef GPIO_InitStructure; 6 EXTI_InitTypeDef EXTI_InitStructure; 7 NVIC_InitTypeDef NVIC_InitStructure; 8 9 // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE); 10 11 // GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD; 12 // GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0; 13 // GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; 14 // GPIO_Init(GPIOA,&GPIO_InitStructure); 15 // 16 // GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; 17 // GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_13; 18 // GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; 19 // GPIO_Init(GPIOC,&GPIO_InitStructure); 20 KEY_Init(); 21 22 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//使能复用功能时钟 23 24 //key0(PC1)中断线以及中断初始化配置 下降沿触发 25 GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource1); 26 27 EXTI_InitStructure.EXTI_Line=EXTI_Line1; 28 EXTI_InitStructure.EXTI_LineCmd=ENABLE; 29 EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; 30 EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling; 31 EXTI_Init(&EXTI_InitStructure); 32 33 //key1(PC13)中断线以及中断初始化配置 下降沿触发 34 GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource13); 35 36 EXTI_InitStructure.EXTI_Line=EXTI_Line13; 37 EXTI_Init(&EXTI_InitStructure); 38 39 //WK_UP(PA0)中断线以及中断初始化配置 上升沿触发 40 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); 41 42 EXTI_InitStructure.EXTI_Line=EXTI_Line0; 43 EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising; 44 EXTI_Init(&EXTI_InitStructure); 45 46 47 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 48 49 //key0(PC1)所在外部中断通道1 50 NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn;//stm32f10x.h 51 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; 52 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2; 53 NVIC_InitStructure.NVIC_IRQChannelSubPriority=2; 54 NVIC_Init(&NVIC_InitStructure); 55 56 //key1(PC13)所在外部中断通道10~15 57 NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;//stm32f10x.h 58 NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; 59 NVIC_Init(&NVIC_InitStructure); 60 61 //WK_UP(PA0)所在外部中断通道0 62 NVIC_InitStructure.NVIC_IRQChannel=EXTI0_IRQn;//stm32f10x.h 63 NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; 64 NVIC_Init(&NVIC_InitStructure); 65 66 } 67 68 void EXTI1_IRQHandler() 69 { 70 delay_ms(10); 71 if(KEY0==0) 72 { 73 LED0=!LED0; 74 } 75 EXTI_ClearITPendingBit(EXTI_Line1); 76 } 77 78 79 void EXTI15_10_IRQHandler() 80 { 81 //正点原子加了判断,但可以不用加判断, 82 // delay_ms(10); 83 // if(KEY1==0) 84 // { 85 LED1=!LED1; 86 // } 87 EXTI_ClearITPendingBit(EXTI_Line13); 88 } 89 90 void EXTI0_IRQHandler() 91 { 92 delay_ms(10); 93 if(WK_UP==1) 94 { 95 LED0=!LED0; 96 LED1=!LED1; 97 } 98 EXTI_ClearITPendingBit(EXTI_Line0); 99 }
exti.h
1 #ifndef __exti_H 2 #define __exti_H 3 #include "delay.h" 4 #include "key.h" 5 #include "led.h" 6 7 void Exti_Init(void); 8 9 #endif