优雅
何谓优雅,就是看起来很爽,用起来也很爽的东西,顺带装装逼的那种,核心 API 如下:
/**
* 绑定方法
* @param event_type KEY_DOWN, KEY_UP
* @param callback 回调方法
* @param 移除监听句柄
* @return 是否绑定成功
*/
bool btn_bind_event(u8 event_type, ButtonCallback callback);
/**
* 移除按键事件绑定
* @param event_type KEY_DOWN, KEY_UP
* @param callback 待移除的回调函数
* @return 被移除的 listener 个数
*/
u8 btn_unbind_event(u8 event_type, ButtonCallback callback);
如上,这两个 API 是参考了前端的 .bind 和 .unbind 方法,用起来十分的爽,一个简单的按键触发蜂鸣器如下:
其中 key_code 映射的是按钮对应的端口,比如 P1^0 那么 key_code 就是 0
/**
* 根据按键报警,0号按键按下去蜂鸣器响
*/
void alarm_switch(ButtonEvent event)
{
if (event.key_code != 0)
{
return;
}
if (event.event_type == KEY_DOWN)
{
bee_alarm_open();
}
if (event.event_type == KEY_UP)
{
bee_alarm_close();
}
}
/**
* 初始化按键绑定事件
*/
void btn_init_listeners()
{
btn_bind_event(KEY_DOWN, alarm_switch);
btn_bind_event(KEY_UP, alarm_switch);
}
上述方法仅仅描述了按键函数的绑定,那么如何触发呢,也十分简单,轮询一下按钮状态即可,如下:
btn_press_buff 作用是消抖,不用 delay,根据循环次次数 (KEY_TRIGGER_TIMES) 消抖
btn_raise_event 就是触发 btn_bind_event 绑定的函数
/**
* 扫描按键状态,并触发相关回调,建议 10ms 调用一次
*/
void btn_poll_scan()
{
u8 key_code = 0;
for (; key_code < KEY_CODE_MAX; key_code += 1)
{
if (get_button_vol(key_code) == KEY_DOWN_VOL)
{
// 防止加法溢出,即用户按下去不松手的情况
if (btn_press_buff[key_code] < 250)
{
btn_press_buff[key_code] += 1;
}
if (btn_press_buff[key_code] == KEY_TRIGGER_TIMES)
{
btn_raise_event(KEY_DOWN, key_code);
}
}
else
{
if (btn_press_buff[key_code] > KEY_TRIGGER_TIMES)
{
btn_raise_event(KEY_UP, key_code);
}
btn_press_buff[key_code] = 0;
}
}
}
性能
此方法不仅长相优雅,它的性能也是不错的,可以看到没有任何的 delay
方法,只需要轮询 btn_poll_scan
即可,这里通过调度器任务来实现 10ms 精确扫描,如下:
// 函数:btn_poll_scan
// 参数:NULL
// 首次延迟:0 ms
// 调用周期:10 ms
// 任务类型:合作式
hsch_add_task(btn_poll_scan, NULL, 0, 10, SCH_COO_TYPE);
注:
- 对调度器不熟悉的可以参考,我的上一篇文章:一个不一样的流水灯
- 源码:https://github.com/ychost/HybSCH