stm32f103
按键长短按得识别原理
需要一个定时器,用来计算按键按下的时间,可以一秒钟检测100次, 设置初始化为10ms的中断,比如使用定时4作为按键时间计算的定时器
比如我们需要4种模式,轻触,短按,长按,超级长按
#define clickTypeTouch 1 //轻触#define clickTypeShort 2 //短按#define clickTypeLong 3 //长按#define clickTypeVeryLong 4 //非常长的长按#define timeCntClickTouch 500 //ms内为短按#define timeCntClickShort 1000 //ms内为短按#define timeCntClickLong 2000//ms内,且大于短按时间为长按#define timeCntClickVeryLong 5000//ms的按键时间为非常长,用于进入高级模式
//这里时钟选择为APB1的2倍,而APB1为36M//arr:自动重装值。//psc:时钟预分频数//这里使用的是定时器7void TIM4_Init(u16 arr,u16 psc){ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 TIM_ITConfig( //使能或者失能指定的TIM中断 TIM4, TIM_IT_Update , ENABLE //使能 ); NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //TIM中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 TIM_Cmd(TIM4, ENABLE); //使能TIMx外设 }
然后设置一个变量用来累计按键按下的时间,没按键按下的时候, 一直循环累计时间,从0到溢出,有按键按下的时候,立即清空,重新开始累计
首先初始化按键端口
void keyIOInit(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11; //LED0-->PA.8 端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA}
u16 timeKeyPressed; //按键按下的时间 10ms 步进
设置两个常量,用来区别按键的状态,是按下还是释放
#define keyStatusPressed 0#define keyStatusReleased 1
定时器的中断,累计时间
void TIM4_IRQHandler(void) //中断{ if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 { TIM_ClearITPendingBit(TIM4, TIM_IT_Update ); //清除TIMx的中断待处理位:TIM 中断源 timeKeyPressed+=10; //10ms的中断 }}
这个键,我叫做设置键,什么时候开始给设置键开始计算按下时间呢?
设置键被按下 而且 按键状态还是释放
需要几个常量标志和几个变量
u8 statusCntingKeyTime; //是否开始计算按键时间#define statusCnting 1#define statusNotCnting 0
//设置键按下,且之前没开始计时的时候,开始计算按下时间
if(keySet==keyStatusPressed && statusCntingKeyTime==statusNotCnting ) { timeKeyPressed=0; //设置键按下后,重新开始计时 statusCntingKeyTime=statusCnting;//开始计算按下时间 }
当按键松开后,统计一下,按下的时间为多长
//松手后统计按下时间 if(keySet==keyStatusReleased && statusCntingKeyTime==statusCnting) { statusCntingKeyTime=statusNotCnting;//停止计时 //轻触 if(timeKeyPressed<=timeCntClickTouch ) { } //短按 else if(timeKeyPressed>=timeCntClickShort &&timeKeyPressed=timeCntClickLong &&timeKeyPressed =timeCntClickVeryLong) { } }