1.轮询按键控制支持在代码中轮训对计数器进行计数达到消抖目的消抖计数可调#define KeyOut_TIME 50 //ms typedef enum { KEY_RESET, KEY1ON, KEY2ON, KEY3ON } keyMode; /******************************************************************************* 函数名称 KeyNum Key1_GetNum(void ) 功能描述 按键1控制代码 返 回 值 按键模式按下键码值 *******************************************************************************/ KeyNum Key1_GetNum(void ) { static u8 Key_Cnt 0; KeyNum key_num KEY_RESET; if (GPIO_ReadInputDataBit(KEY_PORT, KEY1_PIN) 0) //低电平有效 { Key_Cnt; if (Key_Cnt 250) { Key_Cnt 250; } } else { if(Key_Cnt KeyOut_TIME) { key_num KEY1ON; Key_Cnt 0; } } return key_num; }2.定时器计数实现长短按键功能支持在定时器中计数实现消抖和记录长按短按的功能#define CONFIRM_TIME 1 //按键消抖时间 1s #define LONGCONFIRM_TIME 10 //长按时间窗 10s typedef enum { KEY_RELEASE 0, KEY_CONFIRM, KEY_SHORTPRESS, KEY_LONGPRESS }KEY_STATE; typedef struct { KEY_STATE key_state; uint16_t Key_Time; // 记录按键按下的时间 (基准点时间) }KEY_TypeDef; typedef enum { Key_Shot 2, Key_Long 3, }Key_Value; // 键码值 /** brief 定时器实现按键扫描 * param None * retval 按键键码值 Key_Shot 短按, Key_Long 长按, 0 无按键 */ uint8_t Key_Scan(void) { static KEY_TypeDef Key; static uint16_t curtime 0; uint8_t keypress 0; keypress GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4); switch (Key.key_state) { case KEY_RELEASE: if(!keypress) { Key.key_state KEY_CONFIRM; Key.Key_Time RTC_SEC; // 如果有按键按下则立刻记录按键的时间 } break; case KEY_CONFIRM: if(!keypress) { curtime RTC_SEC; //消抖确认按钮是否是误触如果不是则记录当前时间 if((curtime - Key.Key_Time) CONFIRM_TIME ) //如果两次记录的时间差大于消抖时间则确认是短按 { Key.key_state KEY_SHORTPRESS; } } else { Key.key_state KEY_RELEASE; } break; case KEY_SHORTPRESS: if(keypress) //短按是否松手 { Key.key_state KEY_RELEASE; //松开按键后让其进入case0防止短按松开之后仍在响应 return Key_Shot; } else { curtime RTC_SEC; //如果按下按键不松按键时间开始增加,并将给长按重新计时 if((curtime - Key.Key_Time) LONGCONFIRM_TIME ) //一旦超过10s长按开始响应 { Key.key_state KEY_LONGPRESS; } } break; case KEY_LONGPRESS: if(keypress) // 长按是否松手 { Key.key_state KEY_RELEASE; //松开按键后让其进入case0防止长按松开之后仍在响应 return Key_Long; } break; default: Key.key_state KEY_RELEASE; break; } return 0; }