C 语言按键驱动程序代码分析及优化
/**
-
@brief 按键驱动核心函数,驱动状态机。
-
@param handle: 按键句柄结构体。
-
@retval None / static void button_handler(struct Button handle) { uint8_t read_gpio_level = handle->hal_button_Level(handle->button_id); // 读取GPIO引脚电平
//ticks counter working.. if((handle->state) > 0) handle->ticks++; // 如果状态大于0,计数器递增
/------------按键去抖处理---------------/ if(read_gpio_level != handle->button_level) { //当前读取的电平值与上一次不相等 //continue read 3 times same new level change if(++(handle->debounce_cnt) >= DEBOUNCE_TICKS) { // 连续读取3次相同的电平值 handle->button_level = read_gpio_level; // 更新button_level handle->debounce_cnt = 0; // 清零debounce_cnt } } else { //电平值未发生变化,debounce_cnt清零 handle->debounce_cnt = 0; }
/-----------------状态机-------------------/ switch (handle->state) { case 0: if(handle->button_level == handle->active_level) { //按键按下 handle->event = (uint8_t)PRESS_DOWN; EVENT_CB(PRESS_DOWN); // 触发按下事件回调函数 handle->ticks = 0; // 计数器清零 handle->repeat = 1; // repeat次数为1 handle->state = 1; // 切换到状态1 } else { handle->event = (uint8_t)NONE_PRESS; // 未按下 } break;
case 1: if(handle->button_level != handle->active_level) { //松开按键 handle->event = (uint8_t)PRESS_UP; EVENT_CB(PRESS_UP); // 触发松开事件回调函数 handle->ticks = 0; // 计数器清零 handle->state = 2; // 切换到状态2 } else if(handle->ticks > LONG_TICKS) { // 长按开始 handle->event = (uint8_t)LONG_PRESS_START; EVENT_CB(LONG_PRESS_START); // 触发长按开始事件回调函数 handle->state = 5; // 切换到状态5 } break;
case 2: if(handle->button_level == handle->active_level) { //再次按下 handle->event = (uint8_t)PRESS_DOWN; EVENT_CB(PRESS_DOWN); // 触发按下事件回调函数 handle->repeat++; // repeat次数加1 EVENT_CB(PRESS_REPEAT); // 触发repeat事件回调函数 handle->ticks = 0; // 计数器清零 handle->state = 3; // 切换到状态3 } else if(handle->ticks > SHORT_TICKS) { //松开超时 if(handle->repeat == 1) { handle->event = (uint8_t)SINGLE_CLICK; EVENT_CB(SINGLE_CLICK); // 触发单击事件回调函数 } else if(handle->repeat == 2) { handle->event = (uint8_t)DOUBLE_CLICK; EVENT_CB(DOUBLE_CLICK); // 触发双击事件回调函数 } handle->state = 0; // 切换到状态0 } break;
case 3: if(handle->button_level != handle->active_level) { //松开按键 handle->event = (uint8_t)PRESS_UP; EVENT_CB(PRESS_UP); // 触发松开事件回调函数 if(handle->ticks < SHORT_TICKS) { handle->ticks = 0; handle->state = 2; //切换到状态2 } else { handle->state = 0; // 切换到状态0 } } else if(handle->ticks > SHORT_TICKS) { //长按松开 handle->state = 0; // 切换到状态0 } break;
case 5: if(handle->button_level == handle->active_level) { //继续保持按住 handle->event = (uint8_t)LONG_PRESS_HOLD; EVENT_CB(LONG_PRESS_HOLD); // 触发长按保持事件回调函数 } else { //松开 handle->event = (uint8_t)PRESS_UP; EVENT_CB(PRESS_UP); // 触发松开事件回调函数 handle->state = 0; // 重置状态 } break; default: handle->state = 0; // 重置状态 break; } }
原文地址: https://www.cveoy.top/t/topic/nsZz 著作权归作者所有。请勿转载和采集!