查看: 197|回复: 2
收起左侧

乐鑫的这个按键处理程序也不错。

[复制链接]
     

540

主题

5574

帖子

1万

积分

版主

 楼主| 发表于 2017-9-13 13:13 | 显示全部楼层 |返回版面||阅读模式
乐鑫的也不错:
中断方式,回调函数。

可以很方便完成某个按键的短按功能和长按功能等等。

  1. /*
  2. * ESPRESSIF MIT License
  3. *
  4. * Copyright (c) 2016 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
  5. *
  6. * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
  7. * it is free of charge, to any person obtaining a copy of this software and associated
  8. * documentation files (the "Software"), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10. * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
  11. * to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in all copies or
  14. * substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. *
  23. */

  24. #include "ets_sys.h"
  25. #include "os_type.h"
  26. #include "osapi.h"
  27. #include "mem.h"
  28. #include "gpio.h"
  29. #include "user_interface.h"

  30. #include "driver/key.h"

  31. LOCAL void key_intr_handler(void *arg);

  32. /******************************************************************************
  33. * FunctionName : key_init_single
  34. * Description  : init single key's gpio and register function
  35. * Parameters   : uint8 gpio_id - which gpio to use
  36. *                uint32 gpio_name - gpio mux name
  37. *                uint32 gpio_func - gpio function
  38. *                key_function long_press - long press function, needed to install
  39. *                key_function short_press - short press function, needed to install
  40. * Returns      : single_key_param - single key parameter, needed by key init
  41. *******************************************************************************/
  42. struct single_key_param *ICACHE_FLASH_ATTR
  43. key_init_single(uint8 gpio_id, uint32 gpio_name, uint8 gpio_func, key_function long_press, key_function short_press)
  44. {
  45.     struct single_key_param *single_key = (struct single_key_param *)os_zalloc(sizeof(struct single_key_param));
  46.        
  47.         //os_printf("+++ %s         single_key: 0x%x       gpio_id:%d   gpio_name:%d    gpio_func:%d     lone_press:0x%x      short_press : 0x%x \n",__FUNCTION__,single_key,gpio_id,gpio_name,gpio_func,long_press,short_press);

  48.     single_key->gpio_id = gpio_id;
  49.     single_key->gpio_name = gpio_name;
  50.     single_key->gpio_func = gpio_func;
  51.     single_key->long_press = long_press;
  52.     single_key->short_press = short_press;

  53.     return single_key;
  54. }

  55. /******************************************************************************
  56. * FunctionName : key_init
  57. * Description  : init keys
  58. * Parameters   : key_param *keys - keys parameter, which inited by key_init_single
  59. * Returns      : none
  60. *******************************************************************************/
  61. void ICACHE_FLASH_ATTR
  62. key_init(struct keys_param *keys)
  63. {
  64.     uint8 i;

  65.     ETS_GPIO_INTR_ATTACH(key_intr_handler, keys);

  66.     ETS_GPIO_INTR_DISABLE();

  67.         os_printf("+++ %s    key_num: %d \n",__FUNCTION__,keys->key_num);
  68.        
  69.     for (i = 0; i < keys->key_num; i++) {
  70.         keys->single_key[i]->key_level = 1;

  71.         PIN_FUNC_SELECT(keys->single_key[i]->gpio_name, keys->single_key[i]->gpio_func);

  72.         gpio_output_set(0, 0, 0, GPIO_ID_PIN(keys->single_key[i]->gpio_id));

  73.         gpio_register_set(GPIO_PIN_ADDR(keys->single_key[i]->gpio_id), GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE)
  74.                           | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE)
  75.                           | GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE));

  76.         //clear gpio14 status
  77.         GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(keys->single_key[i]->gpio_id));

  78.         //enable interrupt
  79.         gpio_pin_intr_state_set(GPIO_ID_PIN(keys->single_key[i]->gpio_id), GPIO_PIN_INTR_NEGEDGE);
  80.     }

  81.     ETS_GPIO_INTR_ENABLE();
  82. }

  83. /******************************************************************************
  84. * FunctionName : key_5s_cb
  85. * Description  : long press 5s timer callback
  86. * Parameters   : single_key_param *single_key - single key parameter
  87. * Returns      : none
  88. *******************************************************************************/
  89. LOCAL void ICACHE_FLASH_ATTR
  90. key_5s_cb(struct single_key_param *single_key)
  91. {
  92.         os_printf("\n\n+++++++++++++++++      %s\n\n\n",__FUNCTION__);
  93.     os_timer_disarm(&single_key->key_5s);

  94.        

  95.     // low, then restart
  96.     if (0 == GPIO_INPUT_GET(GPIO_ID_PIN(single_key->gpio_id))) {
  97.         if (single_key->long_press) {
  98.             single_key->long_press();

  99.                         os_printf("\n\n+++++++++++++++++     0 == GPIO_INPUT_GET(GPIO_ID_PIN(single_key->gpio_id))  %s\n\n\n",__FUNCTION__);
  100.         }
  101.     }
  102. }

  103. /******************************************************************************
  104. * FunctionName : key_50ms_cb
  105. * Description  : 50ms timer callback to check it's a real key push
  106. * Parameters   : single_key_param *single_key - single key parameter
  107. * Returns      : none
  108. *******************************************************************************/
  109. LOCAL void ICACHE_FLASH_ATTR
  110. key_50ms_cb(struct single_key_param *single_key)
  111. {
  112.         os_printf("\n\n+++++++++++++++++      %s\n\n\n",__FUNCTION__);
  113.     os_timer_disarm(&single_key->key_50ms);
  114.        
  115.     // high, then key is up
  116.     if (1 == GPIO_INPUT_GET(GPIO_ID_PIN(single_key->gpio_id))) {
  117.         os_timer_disarm(&single_key->key_5s);
  118.         single_key->key_level = 1;
  119.         gpio_pin_intr_state_set(GPIO_ID_PIN(single_key->gpio_id), GPIO_PIN_INTR_NEGEDGE);

  120.         if (single_key->short_press) {
  121.             single_key->short_press();
  122.         }
  123.     } else {
  124.         gpio_pin_intr_state_set(GPIO_ID_PIN(single_key->gpio_id), GPIO_PIN_INTR_POSEDGE);
  125.     }
  126. }

  127. /******************************************************************************
  128. * FunctionName : key_intr_handler
  129. * Description  : key interrupt handler
  130. * Parameters   : key_param *keys - keys parameter, which inited by key_init_single
  131. * Returns      : none
  132. *******************************************************************************/
  133. LOCAL void
  134. key_intr_handler(void *arg)
  135. {
  136.     uint8 i;
  137.     uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
  138.     struct keys_param *keys = (struct keys_param *)arg;

  139.         //os_printf("+++++++++++++++++      %s      gpio_status:%d     key_num: %d\n",__FUNCTION__,gpio_status,keys->key_num);

  140.     for (i = 0; i < keys->key_num; i++) {
  141.                 //os_printf("+++++++++++++++++    gpio_status:%d      keys->single_key[%d]->gpio_id:%d     BIT(keys->single_key[ %d ]->gpio_id) : %d      \n",gpio_status,i,keys->single_key[i]->gpio_id,i,BIT(keys->single_key[i]->gpio_id));
  142.         if (gpio_status & BIT(keys->single_key[i]->gpio_id)) {
  143.                         //os_printf("+++++++++++++++++      i: %d    \n",i);


  144.             //disable interrupt
  145.             gpio_pin_intr_state_set(GPIO_ID_PIN(keys->single_key[i]->gpio_id), GPIO_PIN_INTR_DISABLE);

  146.             //clear interrupt status
  147.             GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(keys->single_key[i]->gpio_id));

  148.             if (keys->single_key[i]->key_level == 1) {
  149.                 // 5s, restart & enter softap mode
  150.                 os_timer_disarm(&keys->single_key[i]->key_5s);
  151.                 os_timer_setfn(&keys->single_key[i]->key_5s, (os_timer_func_t *)key_5s_cb, keys->single_key[i]);
  152.                 os_timer_arm(&keys->single_key[i]->key_5s, 5000, 0);
  153.                 keys->single_key[i]->key_level = 0;
  154.                 gpio_pin_intr_state_set(GPIO_ID_PIN(keys->single_key[i]->gpio_id), GPIO_PIN_INTR_POSEDGE);
  155.             } else {
  156.                 // 50ms, check if this is a real key up
  157.                 os_timer_disarm(&keys->single_key[i]->key_50ms);
  158.                 os_timer_setfn(&keys->single_key[i]->key_50ms, (os_timer_func_t *)key_50ms_cb, keys->single_key[i]);
  159.                 os_timer_arm(&keys->single_key[i]->key_50ms, 50, 0);
  160.             }


  161.         }

  162.     }

  163. }

复制代码





timer中断函数:
  1. LOCAL os_timer_t timer;
  2. char zt = 1;

  3. void timer_callback(){
  4.         //if(GPIO_INPUT_GET(FUNC_GPIO2)){
  5.                
  6.         //} else {
  7.         //        os_printf("GPIO2 is 0");
  8.         //}

  9.         unsigned int status=GPIO_INPUT_GET(FUNC_GPIO2);
  10.         //os_printf("GPIO2 is : %d\n",status);
  11.         if(status){
  12.                 os_printf("------GPIO2 is : %d\n",status);
  13.         } else {
  14.                 os_printf("********%d    %d   \n",0x55,0x55);
  15.         }
  16.        
  17.         if(zt == 1){
  18.                 //GPIO_OUTPUT_SET(GPIO_ID_PIN(2), 0);
  19.                 zt = 0;
  20.         }else{
  21.                 //GPIO_OUTPUT_SET(GPIO_ID_PIN(2), 1);
  22.                 zt = 1;
  23.         }
  24. }
复制代码






回调函数:

  1. void key_down50ms_func(void)
  2. {
  3.         os_printf("\n\n+++++++++++++++++      %s\n\n\n",__FUNCTION__);
  4.         os_printf("key down 50ms!\n");
  5. }

  6. void key_down5s_func(void)
  7. {
  8.         os_printf("+++++++++++++++++      %s\n",__FUNCTION__);
  9.         os_printf("start smartconfig............!\n");
  10.        
  11.         smartconfig_set_type(SC_TYPE_ESPTOUCH); //SC_TYPE_ESPTOUCH,SC_TYPE_AIRKISS,SC_TYPE_ESPTOUCH_AIRKISS
  12.         wifi_set_opmode(STATION_MODE);
  13.         smartconfig_start(smartconfig_done);
  14.        
  15. }
复制代码



按键的初始化:
  1. struct keys_param key;
  2. struct single_key_param* single_key[1];


  3. void my_key_init(void)
  4. {
  5.         struct single_key_param *psingle_key;// = //&single_key[0];
  6.         psingle_key =
  7.                         key_init_single(GPIO_ID_PIN(2),PERIPHS_IO_MUX_GPIO2_U,FUNC_GPIO2,key_down5s_func,key_down50ms_func);
  8.         key.key_num = 1;
  9.         //key.single_key = key_init_single(2,2,(key_function)NULL,(key_function)NULL,(key_function)NULL);
  10.         single_key[0] = psingle_key;
  11.         key.single_key = single_key;//&psingle_key;

  12.         key_init(&key);
  13. }

复制代码


     

1

主题

3649

帖子

1万

积分

初级技术员

发表于 2017-9-13 14:56 | 显示全部楼层 |返回版面
看过好多键盘代码,各有优点。

我的键盘代码一般都很简单,仅仅是扫描按键,提供键码,仅此而已。
键码可以是按下、释放、重键、双击、长按,等等,根据需要取舍。键盘程序跟应用层无关,是以一个底层驱动程序存在的。
      

53

主题

1252

帖子

4335

积分

版主

发表于 2017-9-14 12:04 | 显示全部楼层 |返回版面
我看到的最好的代码是三条语句,长安 短按 双击 全部搞定
qq:641208111;技术交流群:377640799
欢迎去大赛专区交流:点我进入()
欢迎加个人QQ:641208111一起交流合作
您需要登录后才可以回帖 登录 | 注册 手机登录

本版积分规则

关闭

热门推荐上一条 /2 下一条

分享 快速回复 返回顶部 返回列表