找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4986|回复: 23
打印 上一主题 下一主题
收起左侧

单片机按键的长按和短按 长按一直按下时不断的加 现在的问题是短按按快一点会没反应

  [复制链接]
跳转到指定楼层
楼主
    这是我在51hei论坛里学习出来的 自己修改了一些  论坛上的else好像没有包含在按键确定按下的循环里  我那样试没有达到长按按下连加的功能,我这样改了可以保证按下是连加  但是短按速度按快一些有时会没有反应。我是用定时器定5ms检测一次,这按键按下的时间应该不会低于5ms,按快了确实有时不反应,是否这就是这种按键处理方式的缺陷,希望有朋友能指点一下,
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:641629 发表于 2019-12-2 14:35 | 只看该作者
num  在哪里定义与赋值的啊
回复

使用道具 举报

板凳
ID:470332 发表于 2019-12-2 14:37 | 只看该作者
还是好好屡屡逻辑吧,画个流程图
回复

使用道具 举报

地板
ID:396245 发表于 2019-12-2 15:26 | 只看该作者

回复

使用道具 举报

5#
ID:396245 发表于 2019-12-2 15:27 | 只看该作者
短按,一下就被你清零了。
回复

使用道具 举报

6#
ID:213173 发表于 2019-12-2 15:52 | 只看该作者
按你的5ms扫描周期,给你写1个短按+/-,长按连+/-的示例程序
  1. void key_scan()
  2. {
  3.         static uint count1,count2;        //消抖计数变量                       

  4.         if(!K1)   
  5.         {  
  6.                 count1++;  
  7.                 if(count1>=150)                        //长按快调0.75s
  8.                 {
  9.                         if(num<255)
  10.                                 num++;
  11.                         count1=100;                        //连+间隔0.25s
  12.                 }
  13.         }  
  14.         else                                                //按键抬起
  15.         {  
  16.                 if(count1>4 && count1<150)//短按20ms~0.75s
  17.                 {
  18.                         if(num<255)
  19.                                 num++;
  20.                 }
  21.                 count1=0;                                //count1清0
  22.         }   
  23.         if(!K2)   
  24.         {  
  25.                 count2++;  
  26.                 if(count2>=150)                        //长按快调0.75s
  27.                 {
  28.                         if(num>0)
  29.                                 num--;
  30.                         count2=100;                        //连-间隔0.25s
  31.                 }
  32.         }  
  33.         else                                                //按键抬起
  34.         {  
  35.                 if(count2>4 && count2<150)        //短按20ms~0.75s
  36.                 {
  37.                         if(num>0)
  38.                                 num--;
  39.                 }
  40.                 count2=0;                                //count2清0
  41.         }   
  42. }
复制代码
回复

使用道具 举报

7#
ID:140489 发表于 2019-12-2 16:08 | 只看该作者
//试一下这样写
void keyscan()
{
        static  uint count1;
        if(key_add==0)
        {
               count1++;
               if(count1>=200)
               {
                    count1=100;//这里调节连加的速度
                   num++;
                  if(num>=255)
                  num=255;
                }
                else if(count1>=1 && count<200)
               {
                     count1=0;
                     num +=25;
                     if(num>=255)
                      num=255;
               }
         }
}
回复

使用道具 举报

8#
ID:89515 发表于 2019-12-2 17:05 来自手机 | 只看该作者
逻辑错误,无法实现长按键。
回复

使用道具 举报

9#
ID:89515 发表于 2019-12-2 17:08 来自手机 | 只看该作者
只是在不断实现短按键给你造成了错觉。
回复

使用道具 举报

10#
ID:650297 发表于 2019-12-2 20:49 | 只看该作者
count定义1个,num定义两个,程序重写后重复一遍就是num1
回复

使用道具 举报

11#
ID:650297 发表于 2019-12-2 20:52 | 只看该作者
count定义1个,num定义两个,程序重写一遍重复一下就是num1
回复

使用道具 举报

12#
ID:586438 发表于 2019-12-2 21:17 来自手机 | 只看该作者
SroneBridge 发表于 2019-12-2 15:27
短按,一下就被你清零了。

真是多谢分析了   不问不知道  一问吓一跳   真的非常感谢
回复

使用道具 举报

13#
ID:586438 发表于 2019-12-2 21:19 来自手机 | 只看该作者
wulin 发表于 2019-12-2 15:52
按你的5ms扫描周期,给你写1个短按+/-,长按连+/-的示例程序

非常感谢  这个就是仿照您给别人留言上学习 的  没想到弄成这样   非常感谢您的帮忙   我会认真理解的
回复

使用道具 举报

14#
ID:586438 发表于 2019-12-2 21:20 来自手机 | 只看该作者
lids 发表于 2019-12-2 16:08
//试一下这样写
void keyscan()
{

非常感谢您的帮忙 我会认真理解的多谢了
回复

使用道具 举报

15#
ID:123289 发表于 2019-12-2 21:54 | 只看该作者
要点:做一个计数器CJ来判定长按与短按,CJ的规则如下:
1、CJ计数只发生于定时器的中断服务程序中,每次中断+1,计满不再计,即不回0。
2、CJ计数只发生于键按下的时候,未按下不计。
3、做一个键状态判定触发标记:B_OK,如果键未按下,但CJ<>0,则置B_OK=1,表示是判断键状态的时候了。
4、当B_OK=1,判断键状态的界定法则是:CJ<某个值为短按,CJ>某个值为长按,某个值是多少由你决定。建议事先将长短两个界定值放置在某个寄存器中,这样可以随意变更界定值。
5、状态界定完成后将:B_OK清0、CJ清0以备下次再界定。
回复

使用道具 举报

16#
ID:586438 发表于 2019-12-3 10:58 | 只看该作者
wulin 发表于 2019-12-2 15:52
按你的5ms扫描周期,给你写1个短按+/-,长按连+/-的示例程序
  1. #include <STC12C5A60S2.H>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit key_add=P3^4; //增加的按键 的I/O口
  5. sbit key_dec=P3^3; //减少的按键 的I/O口
  6. bit flg1=0;
  7. bit flg2=0;      //按键计数标志位
  8. bit flag10ms=0;   //10ms时间标志位
  9. int num=0x00;
  10. unsigned char num1=0;
  11. //typedef enum KeyState{StateInit,StateAffirm,StateSingle,StateRepeat};        //键值状态值

  12. void init()
  13. {
  14.         TMOD=0X01;     //16位计数模式
  15.         TH0=(65535-1000)/256;
  16.         TL0=(65535-1000)%256;  //定时1ms
  17.         EA=1;                  //开总中断
  18.         ET0=1;            
  19.         TR0=1;       
  20.         CMOD=0x02;                //PCA计数脉冲选择为fos/2
  21.   CL=0x00;                                                                //清零
  22.   CH=0x00;
  23.   CCAP0H = CCAP0L = 0x00;          //PWM0的初始占空比为100%
  24.   CCAPM0=0x42;
  25.   CR=1;
  26. }

  27. void time0() interrupt 1
  28. {
  29.         TH0=(65535-1000)/256;
  30.         TL0=(65535-1000)%256;
  31.         num1++;
  32.         if(num1==10)
  33.         {
  34.                 flag10ms=1;
  35.         }
  36. }

  37. void keyscan()
  38. {
  39.         static uint count1,count2;        //消抖计数变量                        

  40.         if(!key_add)   
  41.         {  
  42.                 count1++;  
  43.                 if(count1>=150) //长按1.5s
  44.                 {
  45.                         if(num<255)
  46.                                         num++;
  47.                         count1=100; //连+间隔0.25s
  48.                 }
  49.         }  
  50.         else      //按键抬起
  51.         {  
  52.                 if(count1>1 && count1<150)       //短按20ms~0.75s
  53.                 {
  54.                         if(num<255)
  55.                                 num+=25;
  56.                 }
  57.                 count1=0;  //count1清0
  58.         }   
  59.         if(!key_dec)   
  60.         {  
  61.                 count2++;  
  62.                 if(count2>=150)//长按快调0.75s
  63.                 {
  64.                         if(num>0)
  65.                                         num--;
  66.                         count2=100;     //连-间隔0.25s
  67.                 }
  68.         }  
  69.         else   //按键抬起
  70.         {  
  71.                 if(count2>1 && count2<150)   //短按20ms~0.75s
  72.                 {
  73.                         if(num>0)
  74.                                 num-=25;
  75.                 }
  76.                 count2=0;  //count2清0
  77.         }   
  78. }
  79. void main()
  80. {
  81.         P3M0=0X80;
  82.         P3M1=0X00;//P3^7口推挽输出
  83.         init();
  84.         while(1)
  85.         {
  86.                 if(flag10ms==1)
  87.                 {
  88.                         CCAP0H=num;
  89.                         flag10ms=0;
  90.                         keyscan();
  91.                 }
  92.                 //display();//显示函数
  93.         }
  94. }
复制代码

这是我的全部代码  长按松开才加一次  为了区分是长按还是短按  我特地把长按和短按加的数值改了  发现长按只是实现了短按的功能  拜托能在指点一下吗  非常感谢
回复

使用道具 举报

17#
ID:586438 发表于 2019-12-3 10:59 | 只看该作者
yzwzfyz 发表于 2019-12-2 21:54
要点:做一个计数器CJ来判定长按与短按,CJ的规则如下:
1、CJ计数只发生于定时器的中断服务程序中,每次 ...

有没有范例可以仿照一下  非常感谢
回复

使用道具 举报

18#
ID:140489 发表于 2019-12-3 12:27 | 只看该作者
我写了个一键开关灯加调光的程序,你参考下
  1. //短按开关灯,开灯状态下,长按调光,开灯状态随时都可以调光         2019/10/22 调试完成
  2. #include<reg51.h>
  3. #define uint unsigned int
  4. #define uchar unsigned char


  5. //sfr AUXR = 0x8e;   //Auxiliary register


  6. sbit OUT=P1^1;//  P1.1输出pwm
  7. sbit OUT1=P1^2;//  P1.2输出pwm

  8. sbit KEY1 = P3^0;

  9. #define const_key_time1 10   //短按去抖动延时的时间
  10. #define const_key_time2 500  //长按延时的时间

  11. uint uiKeyTimeCnt1=0; //按键去抖动延时计数器
  12. uint uiKeyTimeCnt4=0; //按键去抖动延时计数器
  13. uint uiKeyTimeCnt2=0; //调光速度变量
  14. uint uiKeyTimeCnt3=0; //调光速度变量
  15. uchar ucKeyLock1=0;   //按键触发后自锁的变量标志
  16. uchar pwm_t;              //pwm周期
  17. bit flag;                      //调光加减标志
  18. uchar pwm_led_val = 50;//LED占空比值
  19. bit flag1;                                //开关灯标志
  20. bit flag2;                                //短按触发标志
  21. bit flag3;                                //长按调光启停标志
  22. bit flag4;                                //按键延时计数启动标志

  23. void keyscan()
  24. {
  25.         if(KEY1==1)        //按键没按下 要及时清零一些标志
  26.         {

  27.                 ucKeyLock1=0;   //按键自锁标志清零
  28.                 uiKeyTimeCnt4=0;//按键去抖动延时计数器清零

  29.                 uiKeyTimeCnt1=0;
  30.                 flag3=0;                //长按松手,停止调光
  31.                 flag4=0;                //松手,按键延时计数停止
  32.                 if(flag2 == 1)        //短按触发标志
  33.                 {
  34.                         flag2=0;
  35.                         flag1 = !flag1;//开关灯标志,松手后才开灯
  36.                 }
  37.        
  38.         }
  39.         else if(ucKeyLock1==0)//按键按下,且是第一次感应
  40.         {       
  41.                 flag4=1;
  42.                 //++uiKeyTimeCnt1;  //延时计数器
  43.                 if(uiKeyTimeCnt4>const_key_time1)//短按        10ms
  44.                 {       
  45.                         flag2 = 1;   //按键按下,启动计数标志
  46. //                        OUT= OUT1=0; //按下就把灯打开,        不要这句 就是松手后才开灯
  47.                 }               
  48.                 if(uiKeyTimeCnt4>const_key_time2)//长按 0.5s
  49.                 {
  50.                        
  51.                         flag2=0;                //清除短按标志
  52.                         ucKeyLock1=1; //自锁按键置位,避免一直触发
  53.        
  54.                         uiKeyTimeCnt4=0;
  55.        
  56.                         flag3=1;  //启动调光
  57.                        
  58.                 }
  59.         }
  60. }


  61. void main()
  62. {
  63.        
  64. //        AUXR &= 0x7F;                //定时器时钟12T模式
  65. //        TMOD &= 0xF0;                //设置定时器模式
  66.         TMOD |= 0x02;        //设置定时器模式 8为自动重装
  67.         TL0 = 0xF7;                //设置定时初值        10us   @11.0592M
  68.         TH0 = 0xF7;                //设置定时重载值
  69.     EA=1;//开总中断
  70.     ET0=1;//开定时器0中断
  71.     TR0=1;//启动定时器0
  72. //        LED3=0;
  73.     while(1)
  74.     {
  75.                 keyscan();
  76.     }                        
  77. }

  78. void tim0() interrupt 1
  79. {
  80.         if(flag1)

  81.         {
  82.                 pwm_t++;
  83.                 if(pwm_t==100)//周期1ms   频率1000Hz
  84.                 {pwm_t=0;}
  85.                 if( pwm_led_val < pwm_t )
  86.                 {OUT = 0; OUT1 = !OUT;}
  87.                 else {OUT=1; OUT1 = !OUT;}
  88.         }
  89.         else OUT=OUT1=1;

  90. //----------------------------------------------
  91.         if(flag4)
  92.         {
  93.                 ++uiKeyTimeCnt1;
  94.                 if(uiKeyTimeCnt1==100) //1ms到
  95.                 {
  96.                         uiKeyTimeCnt1=0;
  97.                         ++uiKeyTimeCnt4;
  98.                 }
  99.        
  100.         } //延时计数器

  101. //-------------------调光-------------------------
  102.         if(flag3)
  103.         {
  104.                 ++uiKeyTimeCnt2;  //延时计数器
  105.                 if(uiKeyTimeCnt2==100)
  106.                 {
  107.                         uiKeyTimeCnt2=0;
  108.                         ++uiKeyTimeCnt3;
  109.                         if(uiKeyTimeCnt3==5)//5ms调一步,此处调节调光速度,值越大,调光越慢
  110.                         {

  111.                                  uiKeyTimeCnt3=0;
  112.                      if(flag == 0)
  113.                       {
  114.        
  115.                          if(pwm_led_val < 100)
  116.        
  117.                           {
  118.                               pwm_led_val++;        //亮度变暗
  119.        
  120.                               if(pwm_led_val==99)//此处赋值100可以调灭
  121.                                   flag = 1;
  122.                           }
  123.                       }
  124.        
  125.                       if( flag ==1 )
  126.                       {
  127.                           if(pwm_led_val > 0)
  128.                           {
  129.                               pwm_led_val--;        //亮度变亮
  130.                               if(pwm_led_val==0)//
  131.                                   flag = 0;
  132.                           }
  133.                       }               
  134.                          }
  135.                 }
  136.         }

  137. }
复制代码
回复

使用道具 举报

19#
ID:140489 发表于 2019-12-3 14:06 | 只看该作者
这是1T单片机的程序,按键延时做了调整,按键延时要结合硬件来调整到最佳状态
  1. //短按开关灯,开灯状态下,长按调光,开灯状态随时都可以调光         2019/12/3 调试完成
  2. //#include<reg51.h>
  3. #include<STC12C5A60S2.h>
  4. #define uint unsigned int
  5. #define uchar unsigned char


  6. //sfr AUXR = 0x8e;   //Auxiliary register


  7. sbit OUT=P1^1;//  P1.1输出pwm
  8. sbit OUT1=P1^2;//  P1.2输出pwm

  9. sbit KEY1 = P3^0;

  10. #define const_key_time1 50   //短按去抖动延时的时间
  11. #define const_key_time2 3000  //长按延时的时间

  12. uint uiKeyTimeCnt1=0; //按键去抖动延时计数器
  13. uint uiKeyTimeCnt4=0; //按键去抖动延时计数器
  14. uint uiKeyTimeCnt2=0; //调光速度变量
  15. uint uiKeyTimeCnt3=0; //调光速度变量
  16. uchar ucKeyLock1=0;   //按键触发后自锁的变量标志
  17. uchar pwm_t;              //pwm周期
  18. bit flag;                      //调光加减标志
  19. uchar pwm_led_val = 50;//LED占空比值
  20. bit flag1;                                //开关灯标志
  21. bit flag2;                                //短按触发标志
  22. bit flag3;                                //长按调光启停标志
  23. bit flag4;                                //按键延时计数启动标志

  24. void keyscan()
  25. {
  26.         if(KEY1==1)        //按键没按下 要及时清零一些标志
  27.         {

  28.                 ucKeyLock1=0;   //按键自锁标志清零
  29.                 uiKeyTimeCnt4=0;//按键去抖动延时计数器清零
  30.                 flag3=0;                //长按松手,停止调光
  31.                 flag4=0;                //松手,按键延时计数停止
  32.                 if(flag2 == 1)        //短按触发标志
  33.                 {
  34.                         flag2=0;
  35.                         flag1 = !flag1;//开关灯标志,松手后才开灯
  36.                 }
  37.        
  38.         }
  39.         else if(ucKeyLock1==0)//按键按下,且是第一次感应
  40.         {       
  41.                 flag4=1;
  42.                 //++uiKeyTimeCnt1;  //延时计数器
  43.                 if(uiKeyTimeCnt4>const_key_time1)//短按        10ms
  44.                 {       
  45.                         flag2 = 1;   //按键按下,启动计数标志
  46. //                        OUT= OUT1=0; //按下就把灯打开,        不要这句 就是松手后才开灯
  47.                 }               
  48.                 if(uiKeyTimeCnt4>const_key_time2)//长按 1s
  49.                 {
  50.                        
  51.                         flag2=0;                //清除短按标志
  52.                         ucKeyLock1=1; //自锁按键置位,避免一直触发
  53.        
  54.                         uiKeyTimeCnt4=0;
  55.        
  56.                         flag3=1;  //启动调光
  57.                        
  58.                 }
  59.         }
  60. }


  61. void main()
  62. {
  63.        
  64. //        AUXR = 0x80;                //定时器时钟1T模式
  65.         AUXR &= 0x7F;                //定时器时钟12T模式
  66.         TMOD &= 0xF0;                //设置定时器模式
  67.         TMOD |= 0x02;        //设置定时器模式 8为自动重装
  68.         TL0 = 0xF7;                //设置定时初值        10us   @11.0592M
  69.         TH0 = 0xF7;                //设置定时重载值
  70.     EA=1;//开总中断
  71.     ET0=1;//开定时器0中断
  72.     TR0=1;//启动定时器0
  73. //        LED3=0;
  74.     while(1)
  75.     {
  76.                 keyscan();
  77.     }                        
  78. }

  79. void tim0() interrupt 1
  80. {
  81.         if(flag1)

  82.         {
  83.                 pwm_t++;
  84.                 if(pwm_t==100)//周期1ms   频率1000Hz
  85.                 {pwm_t=0;}
  86.                 if( pwm_led_val < pwm_t )
  87.                 {OUT = 0; OUT1 = !OUT;}
  88.                 else {OUT=1; OUT1 = !OUT;}
  89.         }
  90.         else OUT=OUT1=1;

  91. //----------------------------------------------
  92.         if(flag4)
  93.         {
  94.                 ++uiKeyTimeCnt1;
  95.                 if(uiKeyTimeCnt1==100) //1ms到
  96.                 {
  97.                         uiKeyTimeCnt1=0;
  98.                         ++uiKeyTimeCnt4;
  99.                 }
  100.        
  101.         } //延时计数器

  102. //-------------------调光-------------------------
  103.         if(flag3)
  104.         {
  105.                 ++uiKeyTimeCnt2;  //延时计数器
  106.                 if(uiKeyTimeCnt2==100)
  107.                 {
  108.                         uiKeyTimeCnt2=0;
  109.                         ++uiKeyTimeCnt3;
  110.                         if(uiKeyTimeCnt3==30)//30ms调一步,此处调节调光速度,值越大,调光越慢
  111.                         {

  112.                                  uiKeyTimeCnt3=0;
  113.                      if(flag == 0)
  114.                       {
  115.        
  116.                          if(pwm_led_val < 100)
  117.        
  118.                           {
  119.                               pwm_led_val++;        //亮度变暗
  120.        
  121.                               if(pwm_led_val==99)//此处赋值100可以调灭
  122.                                   flag = 1;
  123.                           }
  124.                       }
  125.        
  126.                       if( flag ==1 )
  127.                       {
  128.                           if(pwm_led_val > 0)
  129.                           {
  130.                               pwm_led_val--;        //亮度变亮
  131.                               if(pwm_led_val==0)//
  132.                                   flag = 0;
  133.                           }
  134.                       }               
  135.                          }
  136.                 }
  137.         }

  138. }
复制代码
回复

使用道具 举报

20#
ID:263029 发表于 2019-12-3 14:44 | 只看该作者
长按没有实现。
回复

使用道具 举报

21#
ID:140489 发表于 2019-12-3 15:59 | 只看该作者
给你改好了,实验板测试正常
  1. #include <STC12C5A60S2.H>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit key_add=P3^0; //增加的按键 的I/O口
  5. sbit key_dec=P3^1; //减少的按键 的I/O口
  6. //bit flg1=0;
  7. //bit flg2=0;      //按键计数标志位
  8. bit flag10ms=0;   //10ms时间标志位
  9. uint num=0x00;
  10. unsigned char num1=0;

  11. void init()
  12. {
  13.         TMOD=0X01;     //16位计数模式
  14.         TH0=(65535-1000)/256;
  15.         TL0=(65535-1000)%256;  //定时1ms
  16.         EA=1;                  //开总中断
  17.         ET0=1;            
  18.         TR0=1;
  19.                
  20.                 PCA_PWM0=0x00;        
  21.         CMOD=0x02;                //PCA计数脉冲选择为fos/2
  22.                 CL=0x00;                  //清零PCA计数器
  23.                 CH=0x00;
  24.                 CCAP0H = CCAP0L = 0x00;  //PWM0的初始占空比为100%
  25.                 CCAPM0=0x42;                         //设置模块0为8位PWM输出模式;PWM无需中断支持;模块0的脉冲在P1.3脚输出
  26.                 CR=1;                                         //启动PCA计数器
  27. }

  28. void time0() interrupt 1
  29. {
  30.         TH0=(65535-1000)/256;
  31.         TL0=(65535-1000)%256;
  32.         num1++;
  33.         if(num1==10)
  34.         {
  35.                 flag10ms=1;
  36.         }
  37. }

  38. void keyscan()
  39. {
  40.         static uint count1,count2;        //消抖计数变量                        

  41.         if(!key_add)   
  42.         {  
  43.                 count1++;  
  44.                 if(count1>=5000) //长按
  45.                 {
  46.                         if(num<255)
  47.                                                 {
  48.                                 num++;
  49.                                                          if(num==255)
  50.                                                         num=255;
  51.                                                 }
  52.                         count1=500; //连+
  53.                 }
  54.         }  
  55.         else      //按键抬起
  56.         {  
  57.                 if(count1>500 && count1<5000)       //短按
  58.                 {
  59.                         if(num<255)
  60.                                                 {
  61.                                  num+=5;
  62.                                                          if(num>=254)
  63.                                                         num=255;
  64.                                                 }
  65.                                                  count1=0;
  66.                 }
  67. //                count1=0;  //count1清0
  68.         }   


  69.         if(!key_dec)   
  70.         {  
  71.                 count2++;  
  72.                 if(count2>=5000)//长按
  73.                 {
  74.                         if(num>0)
  75.                                                 {
  76.                                 num--;
  77.                                                         if(num<=1)
  78.                                                         num=0;
  79.                                                 }
  80.                         count2=500;     //连-
  81.                 }
  82.         }  
  83.         else   //按键抬起
  84.         {  
  85.                 if(count2>500 && count2<5000)   //短按
  86.                 {
  87.                         if(num>0)
  88.                                                 {
  89.                                 num-=5;
  90.                                                         if(num<=0)
  91.                                                         num=0;

  92.                                                 }
  93.                                                 count2=0;
  94.                 }
  95. //                count2=0;  //count2清0
  96.         }   
  97. }
  98. void main()
  99. {
  100. //        P3M0=0X80;
  101. //        P3M1=0X00;//P3^7口推挽输出
  102.         init();
  103.         while(1)
  104.         {
  105. //                if(flag10ms==1)
  106.                 {
  107.                         CCAP0H=num;
  108. //                        flag10ms=0;
  109.                         keyscan();
  110.                 }
  111.         }
  112. }
复制代码
回复

使用道具 举报

22#
ID:213173 发表于 2019-12-3 17:33 | 只看该作者
如痴百感生 发表于 2019-12-3 10:58
这是我的全部代码  长按松开才加一次  为了区分是长按还是短按  我特地把长按和短按加的数值改了  发现 ...

不清楚你短按一次+/-1,长按连续+/-25 的意图,但要注意使用变量的数据类型,最好按数据类型的整除数+/-,否则会出现负数或溢出。给你改成递增/减5。
  1. #include <STC12C5A60S2.H>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit key_add=P3^4; //增加的按键 的I/O口
  5. sbit key_dec=P3^3; //减少的按键 的I/O口
  6. //bit flg1=0;
  7. //bit flg2=0;      //按键计数标志位
  8. //bit flag10ms=0;   //10ms时间标志位
  9. uchar  num=0x00;
  10. //unsigned char num1=0;
  11. //typedef enum KeyState{StateInit,StateAffirm,StateSingle,StateRepeat};        //键值状态值

  12. void Timer0Init()        //10毫秒@11.0592MHz
  13. {
  14.         AUXR &= 0x7F;        //定时器时钟12T模式
  15.         TMOD &= 0xF0;        //设置T0自动重装模式
  16.         TL0 = 0x00;                //设置定时初值
  17.         TH0 = 0xDC;                //设置定时初值
  18.         TF0 = 0;                //清除TF0标志
  19.         TR0 = 1;                //定时器0开始计时
  20. }
  21. void PWM_Init()
  22. {
  23.         CCON = 0;                                        //初始化PCA控制寄存器
  24.         CL = 0;                                //复位PCA寄存器
  25.         CH = 0;                         //复位PCA寄存器
  26.         CMOD=0x02;                        //PCA计数脉冲选择为fos/2/256=21.6KHz
  27.         PCA_PWM0 = 0x00;                        //PCA模块0工作于8位PWM
  28.         CCAP0H = CCAP0L = 0x00;                //PWM0的占空比为100%
  29.         CCAPM0 = 0x42;                                //允许CCP0脚用作脉宽调节输出
  30.         CR = 1;                                                //PCA定时器开始工作
  31. }
  32. /*
  33. void init()
  34. {
  35.         TMOD=0X01;     //16位计数模式
  36.         TH0=(65535-1000)/256;
  37.         TL0=(65535-1000)%256;  //定时1ms
  38. //        EA=1;                  //开总中断
  39. //        ET0=1;            
  40.         TR0=1;        

  41.         CCON = 0;                                        //初始化PCA控制寄存器
  42.         CL= 0;                  //清零
  43.         CH= 0;
  44.         CMOD=0x02;                //PCA计数脉冲选择为fos/2

  45.         CCAP0H = CCAP0L = 0x00;   //PWM0的初始占空比为100%
  46.         CCAPM0=0x42;
  47.         CR=1;
  48. }
  49. void time0() interrupt 1
  50. {
  51.         TH0=(65535-1000)/256;
  52.         TL0=(65535-1000)%256;
  53.         num1++;
  54.         if(num1==10)
  55.         {
  56.                 flag10ms=1;
  57.         }
  58. }
  59. */
  60. void keyscan()
  61. {
  62.         static uint count1,count2;        //消抖计数变量                        

  63.         if(!key_add)   
  64.         {  
  65.                 count1++;  
  66.                 if(count1>=150) //长按1.5s
  67.                 {
  68.                         if(num<255)
  69.                                 num+=5;;
  70.                         count1=100; //连+间隔0.25s
  71.                 }
  72.         }  
  73.         else      //按键抬起
  74.         {  
  75.                 if(count1>1 && count1<150)       //短按20ms~0.75s
  76.                 {
  77.                         if(num<255)
  78.                                 num+=5;
  79.                 }
  80.                 count1=0;  //count1清0
  81.         }   
  82.         if(!key_dec)   
  83.         {  
  84.                 count2++;  
  85.                 if(count2>=150)//长按快调0.75s
  86.                 {
  87.                         if(num>0)
  88.                                 num-=5;
  89.                         count2=100;     //连-间隔0.25s
  90.                 }
  91.         }  
  92.         else   //按键抬起
  93.         {  
  94.                 if(count2>1 && count2<150)   //短按20ms~0.75s
  95.                 {
  96.                         if(num>0)
  97.                                 num-=5;
  98.                 }
  99.                 count2=0;  //count2清0
  100.         }   
  101. }
  102. void main()
  103. {
  104.         P3M0 = 0x80;
  105.         P3M1 = 0x00;//P3^7口推挽输出
  106.         Timer0Init();
  107.         PWM_Init();
  108.         while(1)
  109.         {
  110.                 if(TF0==1)//查询中断请求标志
  111.                 {
  112.                         TF0=0;//中断请求标志清0
  113.                         keyscan();
  114.                         CCAP0H=num;
  115.                 }
  116.                 //display();//显示函数
  117.         }
  118. }
复制代码
回复

使用道具 举报

23#
ID:591676 发表于 2019-12-3 18:20 | 只看该作者
按键需要消抖否则又是时候会没反应
回复

使用道具 举报

24#
ID:586438 发表于 2019-12-4 08:06 | 只看该作者
弄好了   非常感谢各位的帮忙
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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