看硬件原理图
GPIO的C13和E0是两个按键,平时是高电平,当按键下去的时候就接地变成低电平。
开始软件配置:
宏定义两个按键
(仔细看是有必要的因为你看 GPIO_Pin_13和GPIO_PinSource13的排序是不同的)
#define TSKEY1GPIO GPIOC
#define TSKEY1GPIOPIN GPIO_Pin_13
#define TSKEY1IRQ EXTI15_10_IRQn
#define TSKEY1_ExtiPortsource GPIO_PortSourceGPIOC
#define TSKEY1_ExtiPin GPIO_PinSource13
#define TSKEY1_Line EXTI_Line13
#define TSKEY2GPIO GPIOE
#define TSKEY2GPIOPIN GPIO_Pin_0
#define TSKEY2IRQ EXTI0_IRQn
#define TSKEY2_ExtiPortsource GPIO_PortSourceGPIOE
#define TSKEY2_ExtiPin GPIO_PinSource0
#define TSKEY2_Line EXTI_Line0
初始化函数:
void TS_Key_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE| RCC_APB2Periph_AFIO,ENABLE ) ;
//RCC_APB2Periph_AFIO不能没有!!
GPIO_InitStructure.GPIO_Pin = TSKEY1GPIOPIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//MUST 如果是GPIO_Mode_IN_FLOATING则失败;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(TSKEY1GPIO, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TSKEY1IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
GPIO_EXTILineConfig(TSKEY1_ExtiPortsource, TSKEY1_ExtiPin);
EXTI_InitStructure.EXTI_Line = TSKEY1_Line;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling ;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
GPIO_InitStructure.GPIO_Pin = TSKEY2GPIOPIN ;
GPIO_Init(TSKEY2GPIO, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TSKEY2IRQ;
NVIC_Init(&NVIC_InitStructure);
GPIO_EXTILineConfig(TSKEY2_ExtiPortsource, TSKEY2_ExtiPin);
EXTI_InitStructure.EXTI_Line = TSKEY2_Line;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling ;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
现在就可以用中断了,到it.c去写服务程序吧。
int it=100;
u8 EXit_Delay(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)//消抖 延时以后去读 如果还是低电平 那就是中断!
{
OSTimeDlyHMSM(0, 0, 0, 100);
if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==RESET)
return 1;
else
return 0;
}
这里主要是因为init的时候是下降沿是中断,所以去读,如果是0那就真的是中断。
void EXTI0_IRQHandler(void)
{
OS_CPU_SR cpu_sr;
OS_ENTER_CRITICAL();
OSIntNesting++;
OS_EXIT_CRITICAL();
if(EXTI_GetITStatus(TSKEY2_Line) != RESET)
{
if( EXit_Delay(TSKEY2GPIO,TSKEY2GPIOPIN))
{
it+=10;
}
EXTI_ClearITPendingBit(TSKEY2_Line);
}
OSIntExit();
}
void EXTI15_10_IRQHandler(void)
{
OS_CPU_SR cpu_sr;
OS_ENTER_CRITICAL();
OSIntNesting++;
OS_EXIT_CRITICAL();
if(EXTI_GetITStatus(TSKEY1_Line) != RESET)
{
if( EXit_Delay(TSKEY1GPIO,TSKEY1GPIOPIN))
{
it-=5;
}
EXTI_ClearITPendingBit(TSKEY1_Line);
}
OSIntExit();
}
思考:
1对比文章
https://blog.csdn.net/tianshi_1988/article/details/52175434
为什么 GPIO_Mode_IPU成功 GPIO_Mode_IN_FLOATING失败;
2复用不能丢
3消抖是软件写的,如果你是上升沿触发的话,那就是延时一会读,是1
回答:
http://www.stmcu.org/module/forum/thread-616140-1-1.html