單片機按鍵長短按得識別原理


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM