RYMCU

一个优雅的按键程序

ychost 2 年前
# param # callback

优雅

何谓优雅,就是看起来很爽,用起来也很爽的东西,顺带装装逼的那种,核心 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);

注:

  1. 对调度器不熟悉的可以参考,我的上一篇文章:一个不一样的流水灯
  2. 源码:https://github.com/ychost/HybSCH
后发布评论