找回密码
 立即注册
查看: 141|回复: 26

ADC分压按键代码,有大佬教教小白马

[复制链接]
  • TA的每日心情
    开心
    5 天前
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    2

    主题

    16

    回帖

    70

    积分

    注册会员

    积分
    70
    发表于 2024-5-8 16:49:09 | 显示全部楼层 |阅读模式
    同一个adc io口,通过adc值不同检测 s1,s2,s3,ADC分压按键 s1(开关),s2(增加温度),s3(减温度),长按s2连续增加,长按s3连续减少,s2和s3一起长按切换华氏度,或者摄氏度,目前只是做了按一次,但是长按会有问题 ,大佬们有比较优秀的代码让我学习学习吗
    截图202405081647089519.jpg
    新手小白,请大佬指教
    回复 送花

    使用道具 举报

  • TA的每日心情
    开心
    5 天前
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    2

    主题

    16

    回帖

    70

    积分

    注册会员

    积分
    70
     楼主| 发表于 2024-5-8 17:00:32 | 显示全部楼层

    基础大佬提供的扫描方法,优化的。请大佬指教一下,好像哪里还有问题,菜鸟自己看不出

    本帖最后由 wuzhixuan 于 2024-5-15 11:04 编辑


    void KeyScan(void){
        static unsigned char ADC_sap_cont, key_last, key_release;
        unsigned char key_th;
        adcData = GET_ADC_DATA(4);  // 通道4 AD值
        theVoltage = (unlong) adcData * 5 * 100 / 4096;    //电压放大100倍

        if (100 < theVoltage) {
            if (theVoltage >= 450) { key_th = 1; }          // S2 开关 按键
            else if ((theVoltage <= 340) && (theVoltage >= 290)) { key_th = 2; } // S3 - 按键
            else if ((theVoltage <= 250) && (theVoltage >= 220)) { key_th = 3; } // S4 + 按键
            else if ((theVoltage <= 390) && (theVoltage >= 350)) { key_th = 4; } // S3+S4 同时按下按键
            else { key_th = 0; }
            if (key_last == key_th) { ADC_sap_cont++; }          //键值稳定后开始累计
            else { key_last = key_th, ADC_sap_cont = 0; }          //不稳定键值将被替换抛弃

            if (ADC_sap_cont >= 200)                                                  //如果键值稳定且累计成功
            {
                key_release = 1;
                Key_value = key_last;
            }
        } else {
            if (key_release == 1) {
                key_release = 0;
                if (key_flag == 0)                                              //并且当前无未处理键值
                {
                    ADC_sap_cont = 0;                                           //则输出键值

                    key_flag = 1;
                } else { ADC_sap_cont = 200; }                                  //如果有未处理键值,则等待

            }
            ADC_sap_cont = 0;
        }
    }
    void keyAction() {
        if (key_flag) {  // 检查是否有未处理的键值
            switch (Key_value) {
                case 1:
                    toggle_power();  // 切换电源开关
                    break;
                case 2:
                    decrease_temperature();  // 减少温度
                    break;
                case 3:
                    increase_temperature();  // 增加温度
                    break;
                case 4:
                    switch_temperature_unit();  // 切换温度单位
                    break;
                default:
                    // 无操作
                    break;
            }
            key_flag = 0; // 处理完毕后重置key_flag
        }

        Key_value = 0; // 执行完任务后将Key_value清零
    }
    新手小白,请大佬指教
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    5 天前
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    2

    主题

    16

    回帖

    70

    积分

    注册会员

    积分
    70
     楼主| 发表于 2024-5-8 17:01:37 | 显示全部楼层

    代码是这样的,感觉有问题,而且实际测量的电压值和计算的电压值相差很大,大佬可以帮忙优化一下吗
    新手小白,请大佬指教
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    慵懒
    19 小时前
  • 签到天数: 103 天

    [LV.6]常住居民II

    14

    主题

    408

    回帖

    427

    积分

    荣誉版主

    热心市民

    积分
    427
    发表于 2024-5-8 18:37:34 | 显示全部楼层
    我常用的ADC按键代码,你可以参考一下,已经批量在产品上应用,比较稳定的。
    1. void ADC0_ISR (void) interrupt 5
    2. {
    3.     static unsigned char ADC_sap_cont,key_last,key_release;
    4.         unsigned char key_th;        
    5.         ADC_CONTR &= ~0x20;                //清ADC中断标记
    6.         key_adc = (unsigned int)ADC_RES<<8 | ADC_RESL;         //取AD值
    7.         if(key_adc<2100)
    8.         {
    9.                 if                (key_adc<200)                                                 {key_th = 1;}        //键值分段,实际测试得到区间
    10.                 else if ((key_adc<700) && (key_adc>=200))         {key_th = 2;}
    11.                 else if ((key_adc<1100) && (key_adc>=700))         {key_th = 3;}
    12.                 else if ((key_adc<2100) && (key_adc>=1100))        {key_th = 4;}
    13.                 else                                                                                {key_th = 0;}
    14.                 if (key_last == key_th)        {ADC_sap_cont++;}          //键值稳定后开始累计
    15.                 else  {key_last = key_th,ADC_sap_cont=0;}          //不稳定键值将被替换抛弃
    16.                 if(ADC_sap_cont>=200)                                                  //如果键值稳定且累计成功
    17.                 {
    18.                         key_release = 1;
    19.                         key_valu = key_last;
    20.                 }
    21.         }
    22.         else                                                                                         //如果无按键,则及时清零
    23.         {
    24.                 if(key_release == 1)
    25.                 {
    26.                         key_release = 0;
    27.                         if(key_flag == 0)                                                  //并且当前无未处理键值
    28.                         {
    29.                                 ADC_sap_cont = 0;                                          //则输出键值
    30.                                 
    31.                                 key_flag = 1;
    32.                         }
    33.                         else {ADC_sap_cont = 200;}                                  //如果有未处理键值,则等待
    34.         
    35.                 }
    36.                 ADC_sap_cont = 0;
    37.         }
    38.         ADC_CONTR = (ADC_CONTR & 0xF0) | 0x40 | 0x00;    //再次启动 AD 转换                           
    39. }
    复制代码




    睁开眼睛做场梦~~~
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    5 天前
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    2

    主题

    16

    回帖

    70

    积分

    注册会员

    积分
    70
     楼主| 发表于 2024-5-8 23:49:43 | 显示全部楼层
    晓飛飛 发表于 2024-5-8 18:37
    我常用的ADC按键代码,你可以参考一下,已经批量在产品上应用,比较稳定的。

    谢谢大佬
    新手小白,请大佬指教
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    5 天前
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    2

    主题

    16

    回帖

    70

    积分

    注册会员

    积分
    70
     楼主| 发表于 2024-5-9 00:09:23 | 显示全部楼层
    晓飛飛 发表于 2024-5-8 18:37
    我常用的ADC按键代码,你可以参考一下,已经批量在产品上应用,比较稳定的。

    大佬,你这个代码就很简洁很精妙
    新手小白,请大佬指教
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    5 天前
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    2

    主题

    16

    回帖

    70

    积分

    注册会员

    积分
    70
     楼主| 发表于 2024-5-9 00:16:41 | 显示全部楼层
    晓飛飛 发表于 2024-5-8 18:37
    我常用的ADC按键代码,你可以参考一下,已经批量在产品上应用,比较稳定的。

    if (key_flag == 0) //并且当前无未处理键值  这快代码不是很明白,可以帮忙讲解一下吗,还有就是 key_valu = key_last; 为啥是等于上一次的值,不等于key_th

    点评

    是一种消抖措施  详情 回复 发表于 2024-5-9 01:21
    新手小白,请大佬指教
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    慵懒
    19 小时前
  • 签到天数: 103 天

    [LV.6]常住居民II

    14

    主题

    408

    回帖

    427

    积分

    荣誉版主

    热心市民

    积分
    427
    发表于 2024-5-9 01:21:15 | 显示全部楼层
    wuzhixuan 发表于 2024-5-9 00:16
    if (key_flag == 0) //并且当前无未处理键值  这快代码不是很明白,可以帮忙讲解一下吗,还有就是 key_va ...

    是一种消抖措施
    睁开眼睛做场梦~~~
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    5 天前
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    2

    主题

    16

    回帖

    70

    积分

    注册会员

    积分
    70
     楼主| 发表于 2024-5-9 01:40:16 | 显示全部楼层

    大佬,这个好像不支持长按和两个按键同时按,长按s3,长按s4,已经s3,s4同时按

    点评

    长按、双击这些都可以在这个代码基础上进行扩展,需要额外增加代码实现的。  详情 回复 发表于 2024-5-9 08:43
    新手小白,请大佬指教
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    慵懒
    19 小时前
  • 签到天数: 103 天

    [LV.6]常住居民II

    14

    主题

    408

    回帖

    427

    积分

    荣誉版主

    热心市民

    积分
    427
    发表于 2024-5-9 08:43:47 | 显示全部楼层
    wuzhixuan 发表于 2024-5-9 01:40
    大佬,这个好像不支持长按和两个按键同时按,长按s3,长按s4,已经s3,s4同时按
    ...

    长按、双击这些都可以在这个代码基础上进行扩展,需要额外增加代码实现的。
    睁开眼睛做场梦~~~
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-5-20 20:01 , Processed in 0.079782 second(s), 73 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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