找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6473|回復(fù): 23
打印 上一主題 下一主題
收起左側(cè)

單片機按鍵的長按和短按 長按一直按下時不斷的加 現(xiàn)在的問題是短按按快一點會沒反應(yīng)

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:586438 發(fā)表于 2019-12-2 13:49 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
    這是我在51hei論壇里學(xué)習(xí)出來的 自己修改了一些  論壇上的else好像沒有包含在按鍵確定按下的循環(huán)里  我那樣試沒有達(dá)到長按按下連加的功能,我這樣改了可以保證按下是連加  但是短按速度按快一些有時會沒有反應(yīng)。我是用定時器定5ms檢測一次,這按鍵按下的時間應(yīng)該不會低于5ms,按快了確實有時不反應(yīng),是否這就是這種按鍵處理方式的缺陷,希望有朋友能指點一下,
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏3 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:641629 發(fā)表于 2019-12-2 14:35 | 只看該作者
num  在哪里定義與賦值的啊
回復(fù)

使用道具 舉報

板凳
ID:470332 發(fā)表于 2019-12-2 14:37 | 只看該作者
還是好好屢屢邏輯吧,畫個流程圖
回復(fù)

使用道具 舉報

地板
ID:396245 發(fā)表于 2019-12-2 15:26 | 只看該作者

回復(fù)

使用道具 舉報

5#
ID:396245 發(fā)表于 2019-12-2 15:27 | 只看該作者
短按,一下就被你清零了。
回復(fù)

使用道具 舉報

6#
ID:213173 發(fā)表于 2019-12-2 15:52 | 只看該作者
按你的5ms掃描周期,給你寫1個短按+/-,長按連+/-的示例程序
  1. void key_scan()
  2. {
  3.         static uint count1,count2;        //消抖計數(shù)變量                       

  4.         if(!K1)   
  5.         {  
  6.                 count1++;  
  7.                 if(count1>=150)                        //長按快調(diào)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)                        //長按快調(diào)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. }
復(fù)制代碼
回復(fù)

使用道具 舉報

7#
ID:140489 發(fā)表于 2019-12-2 16:08 | 只看該作者
//試一下這樣寫
void keyscan()
{
        static  uint count1;
        if(key_add==0)
        {
               count1++;
               if(count1>=200)
               {
                    count1=100;//這里調(diào)節(jié)連加的速度
                   num++;
                  if(num>=255)
                  num=255;
                }
                else if(count1>=1 && count<200)
               {
                     count1=0;
                     num +=25;
                     if(num>=255)
                      num=255;
               }
         }
}
回復(fù)

使用道具 舉報

8#
ID:89515 發(fā)表于 2019-12-2 17:05 來自手機 | 只看該作者
邏輯錯誤,無法實現(xiàn)長按鍵。
回復(fù)

使用道具 舉報

9#
ID:89515 發(fā)表于 2019-12-2 17:08 來自手機 | 只看該作者
只是在不斷實現(xiàn)短按鍵給你造成了錯覺。
回復(fù)

使用道具 舉報

10#
ID:650297 發(fā)表于 2019-12-2 20:49 | 只看該作者
count定義1個,num定義兩個,程序重寫后重復(fù)一遍就是num1
回復(fù)

使用道具 舉報

11#
ID:650297 發(fā)表于 2019-12-2 20:52 | 只看該作者
count定義1個,num定義兩個,程序重寫一遍重復(fù)一下就是num1
回復(fù)

使用道具 舉報

12#
ID:586438 發(fā)表于 2019-12-2 21:17 來自手機 | 只看該作者
SroneBridge 發(fā)表于 2019-12-2 15:27
短按,一下就被你清零了。

真是多謝分析了   不問不知道  一問嚇一跳   真的非常感謝
回復(fù)

使用道具 舉報

13#
ID:586438 發(fā)表于 2019-12-2 21:19 來自手機 | 只看該作者
wulin 發(fā)表于 2019-12-2 15:52
按你的5ms掃描周期,給你寫1個短按+/-,長按連+/-的示例程序

非常感謝  這個就是仿照您給別人留言上學(xué)習(xí) 的  沒想到弄成這樣   非常感謝您的幫忙   我會認(rèn)真理解的
回復(fù)

使用道具 舉報

14#
ID:586438 發(fā)表于 2019-12-2 21:20 來自手機 | 只看該作者
lids 發(fā)表于 2019-12-2 16:08
//試一下這樣寫
void keyscan()
{

非常感謝您的幫忙 我會認(rèn)真理解的多謝了
回復(fù)

使用道具 舉報

15#
ID:123289 發(fā)表于 2019-12-2 21:54 | 只看該作者
要點:做一個計數(shù)器CJ來判定長按與短按,CJ的規(guī)則如下:
1、CJ計數(shù)只發(fā)生于定時器的中斷服務(wù)程序中,每次中斷+1,計滿不再計,即不回0。
2、CJ計數(shù)只發(fā)生于鍵按下的時候,未按下不計。
3、做一個鍵狀態(tài)判定觸發(fā)標(biāo)記:B_OK,如果鍵未按下,但CJ<>0,則置B_OK=1,表示是判斷鍵狀態(tài)的時候了。
4、當(dāng)B_OK=1,判斷鍵狀態(tài)的界定法則是:CJ<某個值為短按,CJ>某個值為長按,某個值是多少由你決定。建議事先將長短兩個界定值放置在某個寄存器中,這樣可以隨意變更界定值。
5、狀態(tài)界定完成后將:B_OK清0、CJ清0以備下次再界定。
回復(fù)

使用道具 舉報

16#
ID:586438 發(fā)表于 2019-12-3 10:58 | 只看該作者
wulin 發(fā)表于 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;      //按鍵計數(shù)標(biāo)志位
  8. bit flag10ms=0;   //10ms時間標(biāo)志位
  9. int num=0x00;
  10. unsigned char num1=0;
  11. //typedef enum KeyState{StateInit,StateAffirm,StateSingle,StateRepeat};        //鍵值狀態(tài)值

  12. void init()
  13. {
  14.         TMOD=0X01;     //16位計數(shù)模式
  15.         TH0=(65535-1000)/256;
  16.         TL0=(65535-1000)%256;  //定時1ms
  17.         EA=1;                  //開總中斷
  18.         ET0=1;            
  19.         TR0=1;       
  20.         CMOD=0x02;                //PCA計數(shù)脈沖選擇為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;        //消抖計數(shù)變量                        

  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)//長按快調(diào)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();//顯示函數(shù)
  93.         }
  94. }
復(fù)制代碼

這是我的全部代碼  長按松開才加一次  為了區(qū)分是長按還是短按  我特地把長按和短按加的數(shù)值改了  發(fā)現(xiàn)長按只是實現(xiàn)了短按的功能  拜托能在指點一下嗎  非常感謝
回復(fù)

使用道具 舉報

17#
ID:586438 發(fā)表于 2019-12-3 10:59 | 只看該作者
yzwzfyz 發(fā)表于 2019-12-2 21:54
要點:做一個計數(shù)器CJ來判定長按與短按,CJ的規(guī)則如下:
1、CJ計數(shù)只發(fā)生于定時器的中斷服務(wù)程序中,每次 ...

有沒有范例可以仿照一下  非常感謝
回復(fù)

使用道具 舉報

18#
ID:140489 發(fā)表于 2019-12-3 12:27 | 只看該作者
我寫了個一鍵開關(guān)燈加調(diào)光的程序,你參考下
  1. //短按開關(guān)燈,開燈狀態(tài)下,長按調(diào)光,開燈狀態(tài)隨時都可以調(diào)光         2019/10/22 調(diào)試完成
  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; //按鍵去抖動延時計數(shù)器
  12. uint uiKeyTimeCnt4=0; //按鍵去抖動延時計數(shù)器
  13. uint uiKeyTimeCnt2=0; //調(diào)光速度變量
  14. uint uiKeyTimeCnt3=0; //調(diào)光速度變量
  15. uchar ucKeyLock1=0;   //按鍵觸發(fā)后自鎖的變量標(biāo)志
  16. uchar pwm_t;              //pwm周期
  17. bit flag;                      //調(diào)光加減標(biāo)志
  18. uchar pwm_led_val = 50;//LED占空比值
  19. bit flag1;                                //開關(guān)燈標(biāo)志
  20. bit flag2;                                //短按觸發(fā)標(biāo)志
  21. bit flag3;                                //長按調(diào)光啟停標(biāo)志
  22. bit flag4;                                //按鍵延時計數(shù)啟動標(biāo)志

  23. void keyscan()
  24. {
  25.         if(KEY1==1)        //按鍵沒按下 要及時清零一些標(biāo)志
  26.         {

  27.                 ucKeyLock1=0;   //按鍵自鎖標(biāo)志清零
  28.                 uiKeyTimeCnt4=0;//按鍵去抖動延時計數(shù)器清零

  29.                 uiKeyTimeCnt1=0;
  30.                 flag3=0;                //長按松手,停止調(diào)光
  31.                 flag4=0;                //松手,按鍵延時計數(shù)停止
  32.                 if(flag2 == 1)        //短按觸發(fā)標(biāo)志
  33.                 {
  34.                         flag2=0;
  35.                         flag1 = !flag1;//開關(guān)燈標(biāo)志,松手后才開燈
  36.                 }
  37.        
  38.         }
  39.         else if(ucKeyLock1==0)//按鍵按下,且是第一次感應(yīng)
  40.         {       
  41.                 flag4=1;
  42.                 //++uiKeyTimeCnt1;  //延時計數(shù)器
  43.                 if(uiKeyTimeCnt4>const_key_time1)//短按        10ms
  44.                 {       
  45.                         flag2 = 1;   //按鍵按下,啟動計數(shù)標(biāo)志
  46. //                        OUT= OUT1=0; //按下就把燈打開,        不要這句 就是松手后才開燈
  47.                 }               
  48.                 if(uiKeyTimeCnt4>const_key_time2)//長按 0.5s
  49.                 {
  50.                        
  51.                         flag2=0;                //清除短按標(biāo)志
  52.                         ucKeyLock1=1; //自鎖按鍵置位,避免一直觸發(fā)
  53.        
  54.                         uiKeyTimeCnt4=0;
  55.        
  56.                         flag3=1;  //啟動調(diào)光
  57.                        
  58.                 }
  59.         }
  60. }


  61. void main()
  62. {
  63.        
  64. //        AUXR &= 0x7F;                //定時器時鐘12T模式
  65. //        TMOD &= 0xF0;                //設(shè)置定時器模式
  66.         TMOD |= 0x02;        //設(shè)置定時器模式 8為自動重裝
  67.         TL0 = 0xF7;                //設(shè)置定時初值        10us   @11.0592M
  68.         TH0 = 0xF7;                //設(shè)置定時重載值
  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.         } //延時計數(shù)器

  101. //-------------------調(diào)光-------------------------
  102.         if(flag3)
  103.         {
  104.                 ++uiKeyTimeCnt2;  //延時計數(shù)器
  105.                 if(uiKeyTimeCnt2==100)
  106.                 {
  107.                         uiKeyTimeCnt2=0;
  108.                         ++uiKeyTimeCnt3;
  109.                         if(uiKeyTimeCnt3==5)//5ms調(diào)一步,此處調(diào)節(jié)調(diào)光速度,值越大,調(diào)光越慢
  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可以調(diào)滅
  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. }
復(fù)制代碼
回復(fù)

使用道具 舉報

19#
ID:140489 發(fā)表于 2019-12-3 14:06 | 只看該作者
這是1T單片機的程序,按鍵延時做了調(diào)整,按鍵延時要結(jié)合硬件來調(diào)整到最佳狀態(tài)
  1. //短按開關(guān)燈,開燈狀態(tài)下,長按調(diào)光,開燈狀態(tài)隨時都可以調(diào)光         2019/12/3 調(diào)試完成
  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; //按鍵去抖動延時計數(shù)器
  13. uint uiKeyTimeCnt4=0; //按鍵去抖動延時計數(shù)器
  14. uint uiKeyTimeCnt2=0; //調(diào)光速度變量
  15. uint uiKeyTimeCnt3=0; //調(diào)光速度變量
  16. uchar ucKeyLock1=0;   //按鍵觸發(fā)后自鎖的變量標(biāo)志
  17. uchar pwm_t;              //pwm周期
  18. bit flag;                      //調(diào)光加減標(biāo)志
  19. uchar pwm_led_val = 50;//LED占空比值
  20. bit flag1;                                //開關(guān)燈標(biāo)志
  21. bit flag2;                                //短按觸發(fā)標(biāo)志
  22. bit flag3;                                //長按調(diào)光啟停標(biāo)志
  23. bit flag4;                                //按鍵延時計數(shù)啟動標(biāo)志

  24. void keyscan()
  25. {
  26.         if(KEY1==1)        //按鍵沒按下 要及時清零一些標(biāo)志
  27.         {

  28.                 ucKeyLock1=0;   //按鍵自鎖標(biāo)志清零
  29.                 uiKeyTimeCnt4=0;//按鍵去抖動延時計數(shù)器清零
  30.                 flag3=0;                //長按松手,停止調(diào)光
  31.                 flag4=0;                //松手,按鍵延時計數(shù)停止
  32.                 if(flag2 == 1)        //短按觸發(fā)標(biāo)志
  33.                 {
  34.                         flag2=0;
  35.                         flag1 = !flag1;//開關(guān)燈標(biāo)志,松手后才開燈
  36.                 }
  37.        
  38.         }
  39.         else if(ucKeyLock1==0)//按鍵按下,且是第一次感應(yīng)
  40.         {       
  41.                 flag4=1;
  42.                 //++uiKeyTimeCnt1;  //延時計數(shù)器
  43.                 if(uiKeyTimeCnt4>const_key_time1)//短按        10ms
  44.                 {       
  45.                         flag2 = 1;   //按鍵按下,啟動計數(shù)標(biāo)志
  46. //                        OUT= OUT1=0; //按下就把燈打開,        不要這句 就是松手后才開燈
  47.                 }               
  48.                 if(uiKeyTimeCnt4>const_key_time2)//長按 1s
  49.                 {
  50.                        
  51.                         flag2=0;                //清除短按標(biāo)志
  52.                         ucKeyLock1=1; //自鎖按鍵置位,避免一直觸發(fā)
  53.        
  54.                         uiKeyTimeCnt4=0;
  55.        
  56.                         flag3=1;  //啟動調(diào)光
  57.                        
  58.                 }
  59.         }
  60. }


  61. void main()
  62. {
  63.        
  64. //        AUXR = 0x80;                //定時器時鐘1T模式
  65.         AUXR &= 0x7F;                //定時器時鐘12T模式
  66.         TMOD &= 0xF0;                //設(shè)置定時器模式
  67.         TMOD |= 0x02;        //設(shè)置定時器模式 8為自動重裝
  68.         TL0 = 0xF7;                //設(shè)置定時初值        10us   @11.0592M
  69.         TH0 = 0xF7;                //設(shè)置定時重載值
  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.         } //延時計數(shù)器

  102. //-------------------調(diào)光-------------------------
  103.         if(flag3)
  104.         {
  105.                 ++uiKeyTimeCnt2;  //延時計數(shù)器
  106.                 if(uiKeyTimeCnt2==100)
  107.                 {
  108.                         uiKeyTimeCnt2=0;
  109.                         ++uiKeyTimeCnt3;
  110.                         if(uiKeyTimeCnt3==30)//30ms調(diào)一步,此處調(diào)節(jié)調(diào)光速度,值越大,調(diào)光越慢
  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可以調(diào)滅
  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. }
復(fù)制代碼
回復(fù)

使用道具 舉報

20#
ID:263029 發(fā)表于 2019-12-3 14:44 | 只看該作者
長按沒有實現(xiàn)。
回復(fù)

使用道具 舉報

21#
ID:140489 發(fā)表于 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;      //按鍵計數(shù)標(biāo)志位
  8. bit flag10ms=0;   //10ms時間標(biāo)志位
  9. uint num=0x00;
  10. unsigned char num1=0;

  11. void init()
  12. {
  13.         TMOD=0X01;     //16位計數(shù)模式
  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計數(shù)脈沖選擇為fos/2
  22.                 CL=0x00;                  //清零PCA計數(shù)器
  23.                 CH=0x00;
  24.                 CCAP0H = CCAP0L = 0x00;  //PWM0的初始占空比為100%
  25.                 CCAPM0=0x42;                         //設(shè)置模塊0為8位PWM輸出模式;PWM無需中斷支持;模塊0的脈沖在P1.3腳輸出
  26.                 CR=1;                                         //啟動PCA計數(shù)器
  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;        //消抖計數(shù)變量                        

  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. }
復(fù)制代碼
回復(fù)

使用道具 舉報

22#
ID:213173 發(fā)表于 2019-12-3 17:33 | 只看該作者
如癡百感生 發(fā)表于 2019-12-3 10:58
這是我的全部代碼  長按松開才加一次  為了區(qū)分是長按還是短按  我特地把長按和短按加的數(shù)值改了  發(fā)現(xiàn) ...

不清楚你短按一次+/-1,長按連續(xù)+/-25 的意圖,但要注意使用變量的數(shù)據(jù)類型,最好按數(shù)據(jù)類型的整除數(shù)+/-,否則會出現(xiàn)負(fù)數(shù)或溢出。給你改成遞增/減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;      //按鍵計數(shù)標(biāo)志位
  8. //bit flag10ms=0;   //10ms時間標(biāo)志位
  9. uchar  num=0x00;
  10. //unsigned char num1=0;
  11. //typedef enum KeyState{StateInit,StateAffirm,StateSingle,StateRepeat};        //鍵值狀態(tài)值

  12. void Timer0Init()        //10毫秒@11.0592MHz
  13. {
  14.         AUXR &= 0x7F;        //定時器時鐘12T模式
  15.         TMOD &= 0xF0;        //設(shè)置T0自動重裝模式
  16.         TL0 = 0x00;                //設(shè)置定時初值
  17.         TH0 = 0xDC;                //設(shè)置定時初值
  18.         TF0 = 0;                //清除TF0標(biāo)志
  19.         TR0 = 1;                //定時器0開始計時
  20. }
  21. void PWM_Init()
  22. {
  23.         CCON = 0;                                        //初始化PCA控制寄存器
  24.         CL = 0;                                //復(fù)位PCA寄存器
  25.         CH = 0;                         //復(fù)位PCA寄存器
  26.         CMOD=0x02;                        //PCA計數(shù)脈沖選擇為fos/2/256=21.6KHz
  27.         PCA_PWM0 = 0x00;                        //PCA模塊0工作于8位PWM
  28.         CCAP0H = CCAP0L = 0x00;                //PWM0的占空比為100%
  29.         CCAPM0 = 0x42;                                //允許CCP0腳用作脈寬調(diào)節(jié)輸出
  30.         CR = 1;                                                //PCA定時器開始工作
  31. }
  32. /*
  33. void init()
  34. {
  35.         TMOD=0X01;     //16位計數(shù)模式
  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計數(shù)脈沖選擇為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;        //消抖計數(shù)變量                        

  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)//長按快調(diào)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)//查詢中斷請求標(biāo)志
  111.                 {
  112.                         TF0=0;//中斷請求標(biāo)志清0
  113.                         keyscan();
  114.                         CCAP0H=num;
  115.                 }
  116.                 //display();//顯示函數(shù)
  117.         }
  118. }
復(fù)制代碼
回復(fù)

使用道具 舉報

23#
ID:591676 發(fā)表于 2019-12-3 18:20 | 只看該作者
按鍵需要消抖否則又是時候會沒反應(yīng)
回復(fù)

使用道具 舉報

24#
ID:586438 發(fā)表于 2019-12-4 08:06 | 只看該作者
弄好了   非常感謝各位的幫忙
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表