zl程序教程

您现在的位置是:首页 >  其他

当前栏目

SimonLiu的ESP8266与AliOS Things 学习教程系列之十四:ESP8266配网--key.c之按键事件分析

事件教程学习 分析 -- 系列 Key 按键
2023-09-11 14:21:24 时间

欢迎加入交流群: ESP8266 AliOS Things 群 号: 107723112
系列文章目录:
SimonLiu的ESP8266与AliOS Things 学习教程系列目录

对aos入门的人来说,配网是一件很头疼的事情,但是基本上aos对现有支持的芯片做好了适配。我们以ESP8266为例来分析一下key.c源码如何实现按键配网和清除配网信息的。

源文件: platform/mcu/esp8266/bsp/key.c

  1. 宏定义。GPIO_Pin_14作为配网按键。
#define KEY_GPIO_PIN GPIO_Pin_14
#define KEY_GPIO_MODE GPIO_Mode_Input
#define KEY_GPIO_PULLUP GPIO_PullUp_DIS
#define KEY_GPIO_INTRTYPE GPIO_PIN_INTR_NEGEDGE
  1. 按键初始化并且启用下降沿中断,注册中断回调。
void key_gpio_init(void)
{
    GPIO_ConfigTypeDef key_gpio_cnf;

    gpio_intr_handler_register(key_gpio_isr, NULL);

    key_gpio_cnf.GPIO_Pin = KEY_GPIO_PIN;
    key_gpio_cnf.GPIO_Mode = KEY_GPIO_MODE;
    key_gpio_cnf.GPIO_Pullup = KEY_GPIO_PULLUP;
    key_gpio_cnf.GPIO_IntrType = KEY_GPIO_INTRTYPE;
    gpio_config(&key_gpio_cnf);

    key_gpio_enable_isr();
}
  1. 按键中断回调中判断是否GPIO14按下,如果是调用handle_elink_key()
   static void key_gpio_isr(void *arg)
{
    uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);

    GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);

    if (gpio_status & (1 << 14))
        handle_elink_key();
}
  1. 中断回调调用handle_elink_key()判断是不是一次新按键事件(gpio_value == 0 && elink_time == 0),如果是,先记录按键发生时间,并且通过aos_schedule_call()来执行key_poll_func()
static void handle_elink_key()
{
    uint32_t level = GPIO_INPUT_GET(14);

    if ((level == 0) && (elink_time == 0)) {
        elink_time = aos_now_ms();
        aos_schedule_call(key_poll_func, NULL);
       // aos_loop_schedule_work(0, key_proc_work, NULL, NULL, NULL);
    }
}
  1. key_poll_func(void *arg)判断按键(短按、长按、长长按),通过aos_post_event()分别向系统发出不同的按键事件。
static void key_poll_func(void *arg)
{
    uint32_t level = GPIO_INPUT_GET(14);
    uint64_t diff;

    if (level == 0) {
        aos_post_delayed_action(10, key_poll_func, NULL);
    } else {
        diff = aos_now_ms() - elink_time;
        if (diff > 6000) { /*long long press */
            elink_time = 0;
            aos_post_event(EV_KEY, CODE_BOOT, VALUE_KEY_LLTCLICK);
        } else if (diff > 2000) { /* long press */
            elink_time = 0;
            aos_post_event(EV_KEY, CODE_BOOT, VALUE_KEY_LTCLICK);
        } else if (diff > 40) { /* short press */
            elink_time = 0;
            aos_post_event(EV_KEY, CODE_BOOT, VALUE_KEY_CLICK);
            if (click_callback) click_callback();
        } else {
            aos_post_delayed_action(10, key_poll_func, NULL);
        }
    }
}
  1. 在linkkit_example项目中,app_entry.c注册了按键事件回调。
    aos_register_event_filter(EV_KEY, linkkit_key_process, NULL);

  2. 按键事件回调linkkit_key_process中判断如果是短按VALUE_KEY_CLICKdo_awss_active();进入配网模式。如果是长按VALUE_KEY_LTCLICK就清除配网信息。

   void linkkit_key_process(input_event_t *eventinfo, void *priv_data)
{
    if (eventinfo->type != EV_KEY) {
        return;
    }
    LOG("awss config press %d\n", eventinfo->value);

    if (eventinfo->code == CODE_BOOT) {
        if (eventinfo->value == VALUE_KEY_CLICK) {

            do_awss_active();
        } else if (eventinfo->value == VALUE_KEY_LTCLICK) {
            do_awss_reset();
        }
    }
}