[文章]

Hi3861 ADC驱动 如何使用开发板上的3个按键

2020-10-23 23:36:58  456 GPIO 鸿蒙系统 HarmonyOS 鸿蒙OS
分享
4
本帖最后由 jf_39160458 于 2020-10-23 23:39 编辑

本节主要介绍Hi3861 的 ADC功能,顺便实现ADC按键检测。这里先看效果吧。
查看开发板,可以看到除了复位按键之外,还有3个按键。而查看原理,我们可以看到这个3个按键其实都是接的GPIO5 引脚,而GPIO5引脚又可复用为ADC2引脚。

故而,我们可以猜测出来我们可以使用ADC检测电压,判断出来是哪个引脚被按下了。
看下效果:
当我按下 按键1的时候,串口会打印:

当我按下按键2的时候串口会打印:

当我按下 USER按键的时候串口会打印


其中 vlt_min 表示读取到ADC值的最小值,
vlt_max 表示读取到ADC值的最大值。
由此我们可以看到,按键1被按下的时候,ADC值得范围在 0.563 ~ 0.577
按键2按下后,ADC值在 0.963 ~ 0.970
USER按键按下后 ADC值 在 0.197 ~ 0.204

如果没有按键按下,则ADC值在 3.227 ~ 3.241
vlt_min:3.227, vlt_max:3.241

代码实现其实很简单。
(1)引脚初始化
这里由于GPIO5默认被复用为串口引脚,这里我们重新修改为普通GPIO引脚。初始化代码如下:
   
  1. (hi_void)hi_gpio_init();
  2.    
  3.     hi_io_set_func(HI_IO_NAME_GPIO_5, HI_IO_FUNC_GPIO_5_GPIO); /* uart1 rx */

  4.     ret = hi_gpio_set_dir(HI_GPIO_IDX_5, HI_GPIO_DIR_IN);
  5.     if (ret != HI_ERR_SUCCESS) {
  6.         printf("===== ERROR ======gpio -> hi_gpio_set_dir1 ret:%d\r\n", ret);
  7.         return;
  8.     }
复制代码


(2)读取ADC值
读取ADC值的代码页相对简单,这里,我是重复读取64次,减少误判。
  1.     memset_s(g_adc_buf, sizeof(g_adc_buf), 0x0, sizeof(g_adc_buf));

  2.     for (i = 0; i < ADC_TEST_LENGTH; i++) {
  3.         ret = hi_adc_read((hi_adc_channel_index)HI_ADC_CHANNEL_2, &data, HI_ADC_EQU_MODEL_1, HI_ADC_CUR_BAIS_DEFAULT, 0);
  4.         if (ret != HI_ERR_SUCCESS) {
  5.             printf("ADC Read Fail\n");
  6.             return;
  7.         }
  8.         g_adc_buf[i] = data;
  9.     }
复制代码


(3)对读出来的ADC值进行判断处理
S1对应的是按键1 、 S2对应的是按键2 、 S3对应的是 USER按键
  1.     for (i = 0; i < data_len; i++) {
  2.         vlt = g_adc_buf[i];
  3.         float voltage = (float)vlt * 1.8 * 4 / 4096.0;  /* vlt * 1.8 * 4 / 4096.0: Convert code into voltage */
  4.         vlt_max = (voltage > vlt_max) ? voltage : vlt_max;
  5.         vlt_min = (voltage < vlt_min) ? voltage : vlt_min;
  6.     }
  7.     //printf("vlt_min:%.3f, vlt_max:%.3f \n", vlt_min, vlt_max);

  8.     vlt_val = (vlt_min + vlt_max)/2.0;

  9.     if((vlt_val > 0.4) && (vlt_val < 0.6))
  10.     {
  11.         if(key_flg == 0)
  12.         {
  13.             key_flg = 1;
  14.             key_status = KEY_EVENT_S1;
  15.         }
  16.     }
  17.     if((vlt_val > 0.8) && (vlt_val < 1.1))
  18.     {
  19.         if(key_flg == 0)
  20.         {
  21.             key_flg = 1;
  22.             key_status = KEY_EVENT_S2;
  23.         }
  24.     }

  25.     if((vlt_val > 0.01) && (vlt_val < 0.3))
  26.     {
  27.         if(key_flg == 0)
  28.         {
  29.             key_flg = 1;
  30.             key_status = KEY_EVENT_S3;
  31.         }
  32.     }

  33.     if(vlt_val > 3.0)
  34.     {
  35.         key_flg = 0;
  36.         key_status = KEY_EVENT_NONE;
  37.     }
复制代码


(4)使用
编写好上面代码后,就可以直接在while循环中判断按键值了:
   
  1.     while(1)
  2.     {
  3.         //读取ADC值
  4.         app_demo_adc_test();

  5.         switch(get_key_event())
  6.         {
  7.             case KEY_EVENT_NONE:
  8.             {
  9.                
  10.             }
  11.             break;

  12.             case KEY_EVENT_S1:
  13.             {
  14.                 printf("KEY_EVENT_S1 \r\n");
  15.             }
  16.             break;

  17.             case KEY_EVENT_S2:
  18.             {
  19.                 printf("KEY_EVENT_S2 \r\n");
  20.             }
  21.             break;

  22.             case KEY_EVENT_S3:
  23.             {
  24.                 printf("KEY_EVENT_S3 \r\n");
  25.             }
  26.             break;

  27.         }

  28.         usleep(30000);
  29.     }
  30.    
复制代码


key_demo.rar

1.23 KB, 下载次数: 8, 下载积分: 积分 -1 分

评论

您需要登录后才可以回帖 登录 | 注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
发文章