灵动微 FTHR-G0001 按键程序

分享作者:user202511308096
评测品牌:灵动微电子
评测型号:FTHR-G0001
发布时间:2025-12-18 09:03:51
1
概要
FTHR-G0001 按键控制led多种状态
开源口碑分享内容

感谢iceasy商城,感谢灵动微 冬天里送来的温暖

一段按键逻辑代码,

状态机单击,多击, 以及 单击加长按


void Key_Scan(void){

//    static u8 KeyState = 0;    // 按键状态机
    static uint8_t KeyTime = 0;     // 计时器
    static uint8_t KeyPressCount = 0;  // 按键次数计数(用于多击判断)
    static uint8_t ReleaseDebounceTime = 0;  // 松手消抖计时器
 
    switch (keyState){

			case STATE_IDLE: // 初始状态:等待按键按下
				KeyPressCount = 0;  // 强制清零按键计数
				FLAG_CLR(flag,FLAG_dojiflag);		
				FLAG_CLR(flag, FLAG_last_long_press);  // +++ 在这里重置长按标记 +++		
        if (!KEY_PIN) {
            keyState = STATE_DB_PRESS;  // 进入消抖确认状态
						KeyTime = 0;  // 消抖计时器重置
        }else {
					KeyPressCount = 0;
				}
        break;
    //---------------------------------------
			case STATE_DB_PRESS: // 消抖确认状态
        if (!KEY_PIN) {
        
 
				if(KeyTime<DEBOUNCE_TIME) {
					KeyTime++;
				}else{
						KeyTime = 0;
						keyState = STATE_PRESSED;  // 进入"短按/长按"判断	
						KeyPressCount = 0;
				}

        }else{
          
            keyState = STATE_IDLE;  // 返回初始状态(抖动忽略)
						KeyPressCount = 0;  
        }
        break;

    //---------------------------------------
    case STATE_PRESSED: // 短按/长按判断
        if (KEY_PIN) { // 按键已松开


            keyState = STATE_DB_RELEASE;       			// 进入"多击判断"状态
						ReleaseDebounceTime = 0; 											// 松手消抖计时器
        }else {

            if (++KeyTime >= LONG_PRESS_TIME){  			// 长按判定时间(例如300ms)  长按长按长按
//							FLAG_CLR(flag,FLAG_dojiflag); 
			if(!FLAG_GET(flag,FLAG_suodingflag)){
				 	 
			}else{
				
			}
						
		
							// 如果是第一次按下(KeyPressCount==0),判定为长按
							if(KeyPressCount == 0) {
									keyEvent = KEY_LONG_PRESS;
								
							} else {
						 
									keyState = STATE_WAIT_MULTI;
							}
            }
        }
        break;

    //---------------------------------------
case STATE_DB_RELEASE: // 多击判断(单击/双击/三击)
    if (!KEY_PIN){ 				// 再次按下
    
	  if (ReleaseDebounceTime >= DEBOUNCE_TIME){	  // 松手消抖处理
	  	  
        if (KeyTime >= DEBOUNCE_TIME){  // 消抖处理
            if (KeyTime < 6) { // 连击间隔小于50ms,忽略此次按键
                KeyPressCount--; // 回退按键计数
            }else{
                KeyPressCount++;  // 增加按键次数
            }
            KeyTime = 0;
            keyState = STATE_WAIT_MULTI;     // 进入"多击长按"判断
        }
	   }
    }else {		// 未按下

	if (++ReleaseDebounceTime >= DEBOUNCE_TIME)  // 松手消抖计时
	{    
        if (++KeyTime >= MULTI_PRESS_INTERVAL)  // 多击间隔时间(例如250ms)
        {
            // 根据计数确定最终按键值
            switch (KeyPressCount)
            {
                case 1: keyEvent = KEY_SINGLE_CLICK;  	// 单击
										 
										GPIO_WriteBit(GPIOA,GPIO_Pin_11,Bit_SET);
 
								break;  
                case 2: keyEvent = KEY_DOUBLE_CLICK;  // 双击
										GPIO_WriteBit(GPIOA,GPIO_Pin_11,Bit_RESET);

									
								break; 
                case 3: keyEvent = KEY_TRIPLE_CLICK;   // 三击

							
								break; 
                case 4: keyEvent = KEY_QUAD_CLICK;  // 4击

							

						
						
								break; 
                case 5: keyEvent = KEY_QUINTUPLE_CLICK; // 5击
									 
							
								break; 
                case 6: keyEvent = KEY_SEXTUPLE_CLICK;  // 6击
									if(!FLAG_GET(flag,FLAG_kgflag)){			//关机状态下查看电量

										
									}else{
										
									}
								break; 
                case 7: keyEvent = KEY_SEPTUPLE_CLICK;   break; // 7击
                case 8: keyEvent = KEY_OCTUPLE_CLICK;   break; // 8击
                case 9: keyEvent = KEY_NONUPLE_CLICK;   break; // 9击
                case 10: keyEvent = KEY_TEN_CLICK;  				 // 10击


								break; 
                default: keyEvent = KEY_NONE;           break; // 其他情况
            }
            KeyPressCount = 0; 
            keyState = STATE_IDLE;  // 返回初始状态
						KeyTime=0;
				} 
	}
    }
			break;
 
			case STATE_WAIT_MULTI: // 多击后的长按判断
        if (KEY_PIN) { // 按键松开
						ReleaseDebounceTime = 0;  // 重置松手消抖计时器
            keyState = STATE_DB_RELEASE;  // 返回多击判断(继续等待后续点击)
        }else{ 	// 按键仍按下
 
						FLAG_SET(flag,FLAG_dojiflag); 
 
            if (++KeyTime >= LONG_PRESS_TIME){  		// 长按判定时间
            
                // 根据当前点击次数判断长按类型
                switch (KeyPressCount)
                { 
//                case 1: Key_value = KEY_CLICK_LONG;   printf("1+1"); break;  	// 单击加长按
			case 2: keyEvent = KEY_SINGLE_THEN_LONG;     		// 1击加长按
								if(FLAG_GET(flag,FLAG_kgflag)){				//开机状态下档位+1
 							
									
								}else {

								}

						 break;  		
			case 3: keyEvent = KEY_DOUBLE_THEN_LONG;  			// 2击加长按
								if(FLAG_GET(flag,FLAG_kgflag)){				//开机状态下档位-1
 							
									
								}else {
										
								}

						 break;  		
			case 4: keyEvent = KEY_TRIPLE_THEN_LONG;	 			// 3击加长按
 
						 break;  		
			case 5: keyEvent = KEY_QUAD_THEN_LONG;    			// 4击加长按

						 break;  		
			case 6: keyEvent = KEY_QUINTUPLE_THEN_LONG;   	// 5击加长按
		
						 break;  		
			case 7: keyEvent = KEY_SEXTUPLE_THEN_LONG;	break;		// 6击加长按
			case 8: keyEvent = KEY_SEPTUPLE_THEN_LONG; 	break;		// 7击加长按
			case 9: keyEvent = KEY_OCTUPLE_THEN_LONG; 	break;		// 8击加长按
			case 10: keyEvent = KEY_NONUPLE_THEN_LONG; 	break;		// 9击加长按
			case 11: keyEvent = KEY_TEN_THEN_LONG; 			break;		// 10击加长按
			default: keyEvent = KEY_NONE;               break; 		// 其他情况
                }
		     KeyPressCount = 0; 
                 keyState = STATE_WAIT_IDLE;  // 进入释放等待
            }
        }
        break;

    case STATE_WAIT_IDLE: 									// 释放等待状态
			if(!FLAG_GET(flag,FLAG_suodingflag)){
//				wuji();
			}
				
        if (KEY_PIN) {

						KeyTime = 0;  
           
            KeyPressCount = 0;   					 // 重置按键计数
        } 
        break;
    }
}


全部评论
暂无评论
0/144