1. 程式人生 > >單片機按鍵長短按得識別原理

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

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

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