1. 程式人生 > >微控制器按鍵長短按得識別原理

微控制器按鍵長短按得識別原理

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)
            {
            }
        }