zxq_9781 发表于 2018-8-25 17:46:51

请教 多功能按键单击、双击能掉电 长按不能掉电的问题

本帖最后由 zxq_9781 于 2018-8-25 21:12 编辑

#include <STC15F2K60S2.H>
#include"intrins.h"
#define ucharunsigned char
#define uint   unsigned int
#defineNoClick       0
#define       ShortClick           1
#define       DoubleClick   2
#define       LongClick           3
#define LongClickTime      250
#define DoubleClickTimeDur      70
sbit key=P3^5;
sbit LED1=P3^2;
sbit LED2=P3^3;
sbit LED3=P3^4;
uchar BtnState= NoClick;

void Timer0Init(void)                //5毫秒@12.000MHz
{
        AUXR &= 0x7F;                //定时器时钟12T模式
        TMOD &= 0xF0;                //设置定时器模式
        TL0 = 0x78;                     //设置定时初值
        TH0 = 0xEC;                  //设置定时初值
        TF0 = 0;                   //清除TF0标志
        TR0 = 1;                      //定时器0开始计时
        ET0 = 1;
}
/******** T0中断函数 ********/
void timer()interrupt 1
{                            
      static unsigned int count = 0,ShortClickFlagCount = 0;         
      //count为按键按下计时变量;ShortClickFlagCount为单击按键后超时判断是否有双击计时变量
      static unsigned char ShortClickFlag = 0,LongClickFlag = 0;      
      //ShortClickFlag为单击按键标志,判断双击时用;LongClickFlag为长按按键标志,防止按键按下不释放

      if(key == 0)
      {
                if(count < LongClickTime)
                {
                         count++;
                }
                else
                {
                        BtnState = LongClick;
                        LongClickFlag = 1;
                }
      }
      else
      {
               if(count>=5 && count < LongClickTime)
                {
                         if(ShortClickFlag == 1)
                        {      
                              ShortClickFlag = 0;
                              BtnState = DoubleClick;
                        }
                        else
                        {
                                 ShortClickFlag = 1;
                        }
                }
                else if(count >= LongClickTime && LongClickFlag == 0)
                {
                         BtnState = LongClick;
                }
                LongClickFlag = 0;
                count = 0;
                if(ShortClickFlag == 1)
                {               
                        if(ShortClickFlagCount++ > DoubleClickTimeDur)
                        {
                                 BtnState = ShortClick;
                              ShortClickFlag = 0;
                              ShortClickFlagCount = 0;
                        }      
                }
                else
                {
                         ShortClickFlagCount = 0;
                }               
      }
}

/*************** INT3中断函数 ********************/
/*掉电唤醒*/
void INT3_int (void) interrupt 11
{       
INT_CLKO &= 0xDF;                         //关中断
}
main()
   {
          
    Timer0Init();
        EA = 1;
        while(1)
   {
                 switch(BtnState)
                {
                case   NoClick:
                  break;
                case   ShortClick:   LED1=0; //单击动作       
                  BtnState = NoClick;
                  break;
                case   DoubleClick:       LED2=0;//双击动作                                                
/*                             BtnState = NoClick;
                                LED1=1;LED2=1;       
                            INT_CLKO |= 0x20;              //INT3 Enable              
                               PCON = 0x02;             //MCU进入掉电模式
                               _nop_();
                               _nop_();
                               _nop_();
                               _nop_(); */          
                      break;
                case   LongClick: //        LED2=0;           //长按动作
                                BtnState = NoClick;
                                LED1=1;LED2=1;       
                                INT_CLKO |= 0x20;              //INT3 Enable              
                               PCON = 0x02;             //MCU进入掉电模式
                               _nop_();
                               _nop_();
                               _nop_();
                               _nop_();
                            break;
               default:      
                   break;
                }
                 
   }
}

本坛上看到的多功能按键分 单击、双击、长按,在测试掉电模式时候 单击 或双击能进入掉电模式,长按不能进入掉电模式;长按不松开会进入掉电1uA工作电流。释放后后电流又大起来。
把描述的休眠改成掉电,免得引起误解

zxq_9781 发表于 2018-8-25 21:35:23

自己定一个大神们帮忙了,困扰了几天了

zxq_9781 发表于 2018-8-26 11:53:32

STC15 系列的 int3 不是只能下降沿中断吗,为什么长按不释放能进入掉电模式,松开后会引起中断唤醒呢

饭桶 发表于 2018-8-26 12:12:33

不要在中断函数里关中断

zxq_9781 发表于 2018-8-26 12:44:12

饭桶 发表于 2018-8-26 12:12
不要在中断函数里关中断

应该不是这个问题吧,能说一下改到哪里吗,如果把掉电模式的指令放到短按 或者双击掉电 执行里,能正常进入掉电和唤醒,放到长按执行里 会出现很难进入掉电,及时掉电了唤醒也要多按一次按键

XTXB 发表于 2018-8-29 10:07:21

本帖最后由 XTXB 于 2018-8-29 10:12 编辑

长按进入掉电模式,松开按键时按键抖动,又唤醒了。可以在唤醒后,延时确认是否开机,否,继续掉电模式。在中断中进入掉电模式有风险,会有很多意外发生。

zxq_9781 发表于 2018-8-29 12:36:30

XTXB 发表于 2018-8-29 10:07
长按进入掉电模式,松开按键时按键抖动,又唤醒了。可以在唤醒后,延时确认是否开机,否,继续掉电模式。在 ...

能帮忙改一下吗,我是自学的,目前不会搞,我有尝试把 长按改成释放执行动作可以掉电, 要是长按时间到就执行动作还是不搞; 另外按键扫描和中断唤醒这对键码的处理个逻辑怎么处理也没想明白的, 我现在是演示的 所以执行的动作比较单一,最终想要的效果是需要多次单击,双击 执行相应的动作,长按休眠.水平太菜了,搞不定啊

XTXB 发表于 2018-8-29 19:49:35

本帖最后由 XTXB 于 2018-8-29 19:52 编辑

这个多功能按键:单击,双击,长按,休眠,还真不简单,有难度,我水平有限,只能提下建议而已,可以参考一下这个https://www.amobbs.com/thread-5572213-1-1.html

zxq_9781 发表于 2018-8-29 19:54:59

XTXB 发表于 2018-8-29 19:49
这个多功能按键:单击,双击,长按,休眠,还真不简单,有难度,我水平有限,只能提下建议而已,可以参考一 ...

谢谢回复,自己不是搞软件的,有兴趣搞点小玩意,用电池的,不掉电休眠电池耗电比较快

1826772880 发表于 2018-8-30 11:16:00


1.我的IO上加了1uf电容,所以程序上没有做去抖(电容也不适用所有按键,比如抖动大的按键就不能用电容了,或者要调整电容大小)。
2.中断里边还是尽可能做个标志就行。
3.按键这种方式就不要在中断里关中断了。
4.如果不追求效率按键按下delay延时判断就行,也是最靠谱的通用所有按键。效率高就用定时器代替延时方式
5.STC的外部中断初始化顺序要排好,不然也会中断不相应(外部3 4要特别注意,踩过坑)。

zxq_9781 发表于 2018-8-30 12:22:48

1826772880 发表于 2018-8-30 11:16
1.我的IO上加了1uf电容,所以程序上没有做去抖(电容也不适用所有按键,比如抖动大的按键就不能用电容了, ...

谢谢,是抖动的问题引起的,我有在开关脚并个电容能休眠;不用延时的原因是我想要按键按下去就执行对应的动做,用延时的方法我还做不到及时性比较好的。我现在是按键 唤醒功能和键号怎么避免冲突不会搞
页: [1]
查看完整版本: 请教 多功能按键单击、双击能掉电 长按不能掉电的问题