單片機按鍵長短按得識別原理
阿新 • • 發佈:2018-11-23
發生 eba 單位 tim4 停止 spa fin 按鍵 ble
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:時鐘預分頻數 //這裏使用的是定時器7 void 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 ) { } //長按 else if(timeKeyPressed>=timeCntClickLong &&timeKeyPressed<timeCntClickVeryLong) { } //超級長按 else if(timeKeyPressed>=timeCntClickVeryLong) { } }
單片機按鍵長短按得識別原理