欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3715|回復: 8
打印 上一主題 下一主題
收起左側

關于用單片機+紅外遙控長按短按設置定時器的問題

[復制鏈接]
回帖獎勵 10 黑幣 回復本帖可獲得 10 黑幣獎勵! 每人限 1 次
跳轉到指定樓層
樓主
ID:887218 發表于 2021-3-19 15:30 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 nyjm2021 于 2021-3-20 16:51 編輯

我用的是51單片機,想用NEC協議的紅外遙控來設置定時器,這個階段想要實現的功能是這樣的:1.數碼管前4位顯示ds1302芯片設置的時間(已實現)。

2.長按遙控的電源鍵5s(編碼為0x45),定時功能打開,這時數碼管前兩位顯示小時,后兩位顯示分鐘,初始值都為0.(已實現)
3.再按下遙控的電源鍵(小于5s),代表小時的前兩位閃爍。(有問題)
4.再次按下遙控的電源鍵(小于5s),代表分鐘的后兩位閃爍。(有問題)
我用計算紅外遙控的連發碼數量來算電源鍵長按下的時間,連發碼一個約108ms,5s需要達到46個連發碼。
最開始按下電源鍵,達到46個連發碼時可以打開定時器,小時和分鐘都不閃爍,數碼管上顯示00:00。再按電源鍵可以讓小時閃爍,再按可以讓分鐘閃爍。但如果打開定時器后,按下的時間比較長,一直沒有松開,按理說閃爍的部分是不應該有變化的,但是實際上在20個連發碼的時候,閃爍的小時或者分鐘會自動交換一次,等到35個連發碼時又會自動交換一次,等到46個連發碼時定時器沒有再次打開(小時或者分鐘還會閃爍),等到50個連發碼以上時定時器才會重新打開。
想問下有人知道這是什么原因導致的,怎樣才能改掉這個問題嗎?謝謝!感覺問題應該出在EX0_ISR()函數或者ir_process()函數:————————————————————————————————————————————————
解決方案:因為每次是在到20個連發碼的時候出現這個問題,所以我后來在ir_process()函數中把短按的最長時間從小于46個連發碼改到了小于15個連發碼,雖然沒有找到這個問題出現的原因,但也讓這個問題不再出現了。


下面是我的單片機main.c文件代碼:
  1. #include "reg52.h"        
  2. #include "ds1302.h"
  3. #include <intrins.h>                 //此文件中定義了單片機的一些特殊功能寄存器

  4. #define uint unsigned int          //對數據類型進行聲明定義
  5. #define uchar unsigned char
  6. #define ulong unsigned long

  7. bit timer_on_flag,hour_flash,min_flash;   //定時器開啟,時鐘閃爍,分鐘閃爍
  8.   
  9. uint hour,min;            

  10. sbit lsa = P2^4;          //數碼管位選
  11. sbit lsb = P2^3;
  12. sbit lsc = P2^2;


  13. sbit IRIN = P3^2;   //紅外遙控
  14. uint irtime;            //檢測紅外高電平持續時間
  15. bit irpro_ok,irok;
  16. uchar IRcord[4];         //儲存數據碼
  17. uchar irdata[33];         //1引導碼 8位客戶1 8位客戶2 8位操作碼 8位操作反碼
  18. bit shortpress;   //紅外遙控短按和長按
  19. uint long_press_time;   //紅外遙控連發碼數量

  20. uchar code duan[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

  21. uint flag1ms,flag5ms,flag100ms;

  22. uchar n4,n5,n6,n7;
  23. uchar n0,n1,n2,n3;
  24. bit dig_on;             //數碼管打開

  25. void Ircordpro();
  26. void ir_process();
  27. /*------------------------------------------------------------------------------
  28.                           數碼管位選、賦值、閃爍
  29. ------------------------------------------------------------------------------*/
  30. void flash_display(uchar seta,uchar setb,uchar setc,uchar num,bit check)                           //數碼管閃爍
  31. {
  32.          static uchar flash = 0;
  33.         lsa = seta; lsb = setb; lsc = setc;
  34.         if(check)
  35.         {
  36.                 if(++flash>10) flash = 0;
  37.                 else if(flash<=4) P0 = duan[num];
  38.                 else if(flash>4) P0 = 0x00;
  39.          }else{
  40.                  P0 = duan[num];
  41.          }
  42. }

  43. /*------------------------------------------------------------------------------
  44.                                 數碼管顯示
  45. ------------------------------------------------------------------------------*/
  46. void display(){
  47.     static uchar i = 0;                  

  48.         if(dig_on)
  49.         {        
  50.                 switch(i)
  51.                 {                        
  52.                         case 0:        flash_display(1,1,1,n7,hour_flash);break;
  53.                         case 1:        flash_display(1,1,0,n6,hour_flash);break;
  54.                         case 2:        flash_display(1,0,1,n5,min_flash);break;
  55.                         case 3: flash_display(1,0,0,n4,min_flash);break;
  56.                         case 4: lsa = 0;lsb = 1;lsc = 1;P0 = duan[n3];break;
  57.                         case 5: lsa = 0;lsb = 1;lsc = 0;P0 = duan[n2];break;
  58.                         case 6: lsa = 0;lsb = 0;lsc = 1;P0 = duan[n1];break;
  59.                         case 7: lsa = 0;lsb = 0;lsc = 0;P0 = duan[n0];break;                        
  60.                 }
  61.                 i++;
  62.                 if(i>7)        i=0;
  63.         }
  64.         else
  65.         {
  66.                 P0 = 0x00;
  67.         }               
  68. }

  69. /*------------------------------------------------------------------------------
  70.                                 定時器1初始化
  71. ------------------------------------------------------------------------------*/
  72. void Timer1Init()
  73. {
  74.         TMOD &= 0x0F;                         //清0 T1的控制位
  75.         TMOD |= 0x10;                     //定時器1的工作方式為1
  76.         TH1 = (65536-921)/256;         //晶振頻率為11.0592MHz,機器周期為12/11059200*1000000 = 1.08506944us,周期為1ms,N為1000/1.08506944 = 921.6
  77.         TL1 = (65536-921)%256;

  78.         EA = 1;                                     //打開總中斷
  79.         ET1 = 1;                             //打開定時器1中斷
  80.     TR1 = 1;                             //打開定時器1
  81. }

  82. /*------------------------------------------------------------------------------
  83.                              定時器1中斷服務函數
  84. ------------------------------------------------------------------------------*/
  85. void timer1() interrupt 3
  86. {

  87.          TH1 = (65536-921)/256;
  88.         TL1 = (65536-921)%256;
  89.         flag1ms = 1;                                                   //定時器周期為1ms

  90.         P0 = 0x00;                                  //消抖
  91. }
  92. /*------------------------------------------------------------------------------
  93.                          (紅外)定時器0初始化
  94. ------------------------------------------------------------------------------*/
  95. void Timer0Init()  //256*(1/11.0592MHz)*12 = 0.278ms
  96. {
  97.         TMOD &= 0xF0;  //清零T0的控制位
  98.         TMOD |= 0x02;  //定時器0工作方式2
  99.         TH0 = 0x00;           //高位初始化
  100.         TL0 = 0x00;           //低位初始化
  101.         ET0 = 1;           //定時器0中斷
  102.         TR0 = 1;           //啟動定時器
  103. }

  104. /*------------------------------------------------------------------------------
  105.                          (紅外)外部中斷0初始化
  106. ------------------------------------------------------------------------------*/
  107. void Int0Init()   //外部中斷0初始化
  108. {
  109.         IT0 = 1;          //設置外部中斷0為下降沿觸發
  110.         EX0 = 1;          //啟動外部中斷0
  111.         EA = 1;                  //總中斷允許
  112. }

  113. /*------------------------------------------------------------------------------
  114.                           (紅外)定時器0中斷服務函數
  115. ------------------------------------------------------------------------------*/

  116. void timer0() interrupt 1
  117. {
  118.         irtime++;         //檢測脈寬,一次位278us
  119. }

  120. /*------------------------------------------------------------------------------
  121.                           (紅外)外部中斷0服務函數
  122. ------------------------------------------------------------------------------*/
  123. void EX0_ISR() interrupt 0
  124. {
  125.         static uchar i;                 //把33次高電平持續時間存入irdata
  126.         static bit startflag;         //開始存儲脈寬標志位

  127.         if(startflag)                         //開始接收脈寬檢測
  128.         {   
  129.                 if(irtime<63 && irtime>=45)   //判斷是否引導碼,低電平9ms+高電平4.5ms         
  130.                 {
  131.                         i = 0;                         //如果是存入irdata的第一位
  132.                         shortpress = 1;
  133.                         long_press_time = 0;
  134.                 }
  135.                 else if(irtime>33 && irtime <45)         //判斷是否為連發碼,低電平9ms+高電平2.25ms
  136.                 {
  137.                         shortpress = 0;
  138.                         long_press_time++;                          //計算連發碼的數量
  139.                 }
  140.                 if(shortpress)
  141.                 {
  142.                         irdata[i] = irtime;
  143.                 }
  144.                 irtime = 0;                        //計數清零,下一個下降沿的時候再存入脈寬
  145.                 i++;                                //計算脈寬存入的次數
  146.                 if(i==33)                        //如果存入34次
  147.                 {
  148.                         irok = 1;                //脈寬檢測完畢
  149.                         i = 0;                        //脈寬計數清零準備下次存入
  150.                 }         
  151.         }
  152.         else
  153.         {
  154.                 irtime = 0;                        //計數清零
  155.                 startflag = 1;                //開始處理
  156.         }
  157. }
  158. /*------------------------------------------------------------------------------
  159.                           (紅外)碼值處理函數
  160. ------------------------------------------------------------------------------*/
  161. void Ircordpro()  //提取33次脈寬進行數據解碼
  162. {
  163.         uchar i, j, k,cord,value;            //k用于33次脈寬中的哪一位
  164.         k=1;                                            //從第一位開始,丟棄引導碼脈寬
  165.         for(i=0;i<4;i++)                //處理4個字節
  166.         {
  167.                 for(j=1;j<=8;j++)       //處理1個字節8位
  168.                 {
  169.                         cord=irdata[k];        //把脈寬存入cord
  170.                         if(cord>5)      //脈寬大于11.0592的T0溢出率位約278us*5=1390那么判斷為1
  171.                         {
  172.                                                         value=value|0x80;  //接收時先接收最低位
  173.                                                 }
  174.                         if(j<8)
  175.                         {
  176.                                 value>>=1;           //value位左移依次接收8位數據
  177.                         }
  178.                         k++;               //每執行一次脈寬數加一
  179.                 }
  180.                 IRcord[i]=value;           //每處理完一個字節把它放入ircord數組中
  181.                 value=0;                        //清零value方便下次存入數據
  182.         }
  183.         irpro_ok=1;  //接受完4個字節后irpro_ok置1表示紅外解碼完成
  184. }

  185. /*------------------------------------------------------------------------------
  186.                           (紅外)功能實現函數
  187. ------------------------------------------------------------------------------*/

  188. void ir_process()
  189. {
  190.         if(irok)                         //如果紅外信號接收完畢
  191.         {
  192.                 Ircordpro();        //對紅外信號進行解碼
  193.                 irok = 0;
  194.                 shortpress = 0;
  195.         }
  196.         if(irpro_ok)                   //如果對紅外信號解碼完畢
  197.         {
  198.                 if(IRcord[2]==0x45 )           //如果按鍵是45H
  199.                 {
  200.                         if(long_press_time >= 46)          //長按打開定時器
  201.                         {
  202.                                 timer_on_flag = 1;                 //打開定時器
  203.                                 hour = 0;
  204.                                 min = 0;
  205.                                 hour_flash = 0;                         //小時不閃爍
  206.                                 min_flash = 0;                         //分鐘不閃爍
  207.                         }
  208.                         else if( (1<=long_press_time && long_press_time <46))           //短按對時間進行選擇,設置超過20時會自動跳變
  209.                         {
  210.                                         if(timer_on_flag)                                   //如果定時器處于打開狀態
  211.                                         {
  212.                                                 if(!min_flash && !hour_flash)          //小時分鐘均不閃爍,讓小時閃爍
  213.                                                 {
  214.                                                         hour_flash = 1;
  215.                                                         irpro_ok = 0;
  216.                                                 }
  217.                                                 else if(hour_flash && !min_flash)                                   //小時已經在閃爍,短按一下讓分鐘閃爍
  218.                                                 {
  219.                                                         hour_flash = 0;
  220.                                                         min_flash = 1;
  221.                                                         irpro_ok = 0;
  222.                                                 }
  223.                                                 else if(min_flash && !hour_flash)
  224.                                                 {
  225.                                                         hour_flash = 1;                           //小時沒有閃爍,短按一下讓小時閃爍,分鐘不閃爍
  226.                                                         min_flash = 0;
  227.                                                         irpro_ok = 0;
  228.                                                 }
  229.                                        
  230.                                         }
  231.                         }
  232.                 }         
  233.         }  
  234.                
  235. }
  236. /*------------------------------------------------------------------------------
  237.                           數碼管顯示內容設置函數
  238. ------------------------------------------------------------------------------*/
  239. void calculate_num()
  240. {        
  241.         
  242.         n3 = long_press_time / 10;
  243.         n2 = long_press_time % 10;
  244.         n1 = IRcord[2]>>4;
  245.         n0 = IRcord[2]&0x0F;
  246.         
  247.         if(timer_on_flag)                    //定時器打開,數碼管顯示定時的倒計時
  248.         {
  249.                 n7 = hour / 10;
  250.                 n6 = hour % 10;
  251.                 n5 = min / 10;
  252.                 n4 = min % 10;
  253.         }else if(!timer_on_flag)          //定時器未開,數碼管顯示時鐘芯片實時時間
  254.         {
  255.                 Ds1302ReadTime();
  256.                 n7 = TIME[2]/16;                //時
  257.                 n6 = TIME[2]&0x0f;

  258.             n5 = TIME[1]/16;                //分
  259.                 n4 = TIME[1]&0x0f;
  260.         }
  261. }

  262. /*------------------------------------------------------------------------------
  263.                                 主函數
  264. ------------------------------------------------------------------------------*/
  265. void main( )
  266. {        
  267.         dig_on = 1;

  268.         Timer0Init();
  269.         Timer1Init();

  270.     Ds1302Init();
  271.         Int0Init();

  272.         while(1)
  273.         {
  274.                   if(flag1ms)
  275.                 {
  276.                         flag1ms = 0;               
  277.                         display();             //數碼管顯示
  278.                         if(++flag5ms>=5)          //1ms * 5 = 5ms
  279.                         {
  280.                                 flag5ms = 0;
  281.                                 ir_process();      //紅外控制
  282.                                 calculate_num();
  283.                         }
  284.                 }
  285.         }        
  286. }
復制代碼

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:140489 發表于 2021-3-19 16:19 | 只看該作者
用遙控器就多用幾個鍵來設置,,遙控器上那么多的按鍵不用作什么
回復

使用道具 舉報

板凳
ID:887218 發表于 2021-3-19 18:37 | 只看該作者
lids 發表于 2021-3-19 16:19
用遙控器就多用幾個鍵來設置,,遙控器上那么多的按鍵不用作什么

不好意思,我在做一個小項目,要求就是這樣的,用一個遙控按鍵實現長按5s開啟定時,短按切換小時和分鐘閃爍
回復

使用道具 舉報

地板
ID:283908 發表于 2021-3-19 21:22 | 只看該作者
是否可以換個思路,再定義幾個變量。

判斷在一定時間段里。出現的0x45。

如第一個0X45存在IRcord—one[2]==0x45

后 108ms的0X45存在IRcord—two[2]==0x45

IRcord—two[2] 再后的0X45存在IRcord_three[2]==0x45

然后再分別處理IRcord_three[2]   IRcord—two[2]  IRcord—one[2]

      
回復

使用道具 舉報

5#
ID:275826 發表于 2021-3-20 14:30 | 只看該作者
樓主的程序中long_press_time未復位0;程序應該沒有長按功能,只有短按功能
回復

使用道具 舉報

6#
ID:887218 發表于 2021-3-20 16:43 | 只看該作者
本帖最后由 nyjm2021 于 2021-3-20 16:54 編輯
tyrl800 發表于 2021-3-20 14:30
樓主的程序中long_press_time未復位0;程序應該沒有長按功能,只有短按功能

長按功能是可以實現的。我這里的長按和短按更準確地說是判斷讀取到的是11.25ms的連發碼還是13.5ms的引導碼,long_press_time是在短按,也就是接收到引導碼的時候復位0的。每一次有按鍵按下,最開始發送引導碼,執行短按部分的程序,long_press_time歸0,讀取到的數據碼存儲在irdata[]中,按鍵持續按下,沒有放開,讀取到連發碼,long_press_time自增,不存儲新的數據。每一次讀取到引導碼或者連發碼時,用Ircordpro()函數進行解碼,并用ir_process()函數完成相應的功能。遙控按鍵放開,下一次又有按鍵按下時,再對引導碼進行處理,long_press_time再次清零。
回復

使用道具 舉報

7#
ID:358564 發表于 2021-3-20 19:40 | 只看該作者
// =========================== key.c ======================
#include "reg51.h"

#define KEY_INPUT           P1.0    //  按鍵IO

#define KEY_STATE_0         0       //  按鍵狀態
#define KEY_STATE_1         1
#define KEY_STATE_2         2
#define KEY_STATE_3         3

#define SINGLE_KEY_TIME     3       //  SINGLE_KEY_TIME*10MS = 30MS     判定單擊的時間長度,軟件消抖
#define KEY_INTERVAL        30      //  KEY_INTERVAL*10MS    = 300MS 判定雙擊的時間間隔
#define LONG_KEY_TIME       300     //  LONG_KEY_TIME*10MS   = 3S   判定長按的時間長度


#define N_KEY               0       //  no click
#define S_KEY               1       //  single click        單擊
#define D_KEY               2       //  double click        雙擊
#define T_KEY               3       //  Triple click        三擊
#define Q_KEY               4       //  Quadruple click     四擊
#define L_KEY               10      //  long press          長按

// ----------------------------------- key_driver --------------------------
unsigned char key_driver(void)
{     
    static unsigned char key_state = 0;
    static unsigned int  key_time = 0;
    unsigned char key_press, key_return;

    key_return = N_KEY;                         //  清除 返回按鍵值

    key_press = key_input;                      //  讀取當前鍵值

    switch (key_state)     
    {      
        case KEY_STATE_0:                       //  按鍵狀態0:判斷有無按鍵按下
            if (!key_press)                     //  有按鍵按下
            {
                key_time = 0;                   //  清零時間間隔計數
                key_state = KEY_STATE_1;        //  然后進入 按鍵狀態1
            }        
            break;

        case KEY_STATE_1:                       //  按鍵狀態1:軟件消抖(確定按鍵是否有效,而不是誤觸)。按鍵有效的定義:按鍵持續按下超過設定的消抖時間。
            if (!key_press)                     
            {
                key_time++;                     //  一次10ms
                if(key_time>=SINGLE_KEY_TIME)   //  消抖時間為:SINGLE_KEY_TIME*10ms = 30ms;
                {
                    key_state = KEY_STATE_2;    //  如果按鍵時間超過 消抖時間,即判定為按下的按鍵有效。按鍵有效包括兩種:單擊或者長按,進入 按鍵狀態2, 繼續判定到底是那種有效按鍵
                }
            }         
            else key_state = KEY_STATE_0;       //  如果按鍵時間沒有超過,判定為誤觸,按鍵無效,返回 按鍵狀態0,繼續等待按鍵
            break;

        case KEY_STATE_2:                       //  按鍵狀態2:判定按鍵有效的種類:是單擊,還是長按
            if(key_press)                       //  如果按鍵在 設定的長按時間 內釋放,則判定為單擊
            {
                 key_return = S_key;            //  返回 有效按鍵值:單擊
                 key_state = KEY_STATE_0;       //  返回 按鍵狀態0,繼續等待按鍵
            }
            else
            {
                key_time++;                     

                if(key_time >= LONG_KEY_TIME)   //  如果按鍵時間超過 設定的長按時間(LONG_KEY_TIME*10ms=300*10ms=3000ms), 則判定為 長按
                {
                    key_return = L_KEY;         //  返回 有效鍵值值:長按
                    key_state = KEY_STATE_3;    //  去狀態3,等待按鍵釋放
                }
            }
            break;

      case KEY_STATE_3:                         //  等待按鍵釋放
          if (key_press)
          {
              key_state = KEY_STATE_0;          //  按鍵釋放后,進入 按鍵狀態0 ,進行下一次按鍵的判定
          }        
          break;

        default:                                //  特殊情況:key_state是其他值得情況,清零key_state。這種情況一般出現在 沒有初始化key_state,第一次執行這個函數的時候
            key_state = KEY_STATE_0;
            break;
    }

    return  key_return;                         //  返回 按鍵值
}

// ----------------------------------- key_read --------------------------------
void key_read(void)                             
{
    static unsigned char key_state1=0, key_time1=0;
    unsigned char key_return,key_temp;

    key_return = N_KEY;                         //  清零 返回按鍵值

    key_temp = key_driver();                    //  讀取鍵值

    switch(key_state1)
    {         
        case KEY_STATE_0:                       //  按鍵狀態0:等待有效按鍵(通過 key_driver 返回的有效按鍵值)
            if (key_temp == S_key )             //  如果是[單擊],不馬上返回單擊按鍵值,先進入 按鍵狀態1,判斷是否有[雙擊]的可能
            {
                 key_time1 = 0;                 //  清零計時
                 key_state1 = KEY_STATE_1;
            }            
            else                                //  如果不是[單擊],直接返回按鍵值。這里的按鍵值可能是:[長按],[無效按鍵]
            {
                 key_return = key_temp;         //  返回 按鍵值
            }
            break;

        case KEY_STATE_1:                       //  按鍵狀態1:判定是否有[雙擊]
            if (key_temp == S_key)              //  有[單擊]后,如果在 設定的時間間隔(KEY_INTERVAL*10ms=30*10ms=300ms) 內,再次有[單擊],則為[雙擊],但是不馬上返回 有效按鍵值為[雙擊],先進入 按鍵狀態2,判斷是否有[三擊]
            {
                key_time1 = 0;                  //  清零 時間間隔
                key_state1 = KEY_STATE_2;       //  改變 按鍵狀態值
            }
            else                                //  有[單擊]后,如果在 設定的時間間隔(KEY_INTERVAL*10ms=30*10ms=300ms)內,沒有[單擊]出現,則判定為 [單擊]
            {
                key_time1++;                    //  計數 時間間隔
                if(key_time1 >= KEY_INTERVAL)   //  超過 時間間隔
                 {
                    key_return = S_key;         //  返回 有效按鍵:[單擊]
                    key_state1 = KEY_STATE_0;   //  返回 按鍵狀態0,等待新的有效按鍵
                 }              
             }              
             break;

        case KEY_STATE_2:                       // 按鍵狀態2:判定是否有[三擊]
            if (key_temp == S_key)              // 有[雙擊]后,如果在 設定的時間間隔(KEY_INTERVAL*10ms=30*10ms=300ms) 內,再次有[單擊],則為[三擊],由于這里只擴展到[三擊],所以馬上返回 有效按鍵值為[三擊]
            {
                key_time1 = 0;                  // 清零 時間間隔
                key_state1 = KEY_STATE_3;       // 改變 按鍵狀態值
            }
            else                                // 有[雙擊]后,如果在 設定的時間間隔(KEY_INTERVAL*10ms=30*10ms=300ms)內,沒有[單擊],則判定為 [雙擊]
            {
                key_time1++;                    // 計數 時間間隔
                if(key_time1 >= KEY_INTERVAL)   // 超過 時間間隔
                 {
                      key_return = D_KEY;       // 返回 有效按鍵:[雙擊]
                      key_state1 = KEY_STATE_0; // 返回 按鍵狀態0,等待新的有效按鍵
                 }
             }
             break;

        case KEY_STATE_3:                       // 按鍵狀態3:等待按鍵釋放
            if (key_temp == S_key)              // 有[三擊]后,如果在 設定的時間間隔(KEY_INTERVAL*10ms=30*10ms=300ms) 內,再次有[單擊],則為[四擊],馬上返回有效按鍵值為[四擊],
            {
                 key_return = Q_key;            // 返回 有效按鍵:[四擊]
                 key_state1 = KEY_STATE_0;      // 返回 按鍵狀態0,等待新的有效按鍵
            }
            else                                
            {                                   // 有[三擊]后,如果在 設定的時間間隔(KEY_INTERVAL*10ms=30*10ms=300ms)內,沒有[單擊],則判定為 [三擊]                 
                key_time1++;                    // 計數 時間間隔
                if(key_time1 >= KEY_INTERVAL)   // 超過 時間間隔
                 {
                      key_return = T_KEY;       // 返回 有效按鍵:[三擊]
                      key_state1 = KEY_STATE_0; // 返回 按鍵狀態0,等待新的有效按鍵
                 }              
             }            
             break;

        default:                                //  特殊情況:key_state是其他值得情況,清零key_state。這種情況一般出現在 沒有初始化key_state,第一次執行這個函數的時候
            key_state1 = KEY_STATE_0;
            break;
    }

    return = key_return;                        // 返回 按鍵值
}     
回復

使用道具 舉報

8#
ID:275826 發表于 2021-3-20 20:36 | 只看該作者
nyjm2021 發表于 2021-3-20 16:43
長按功能是可以實現的。我這里的長按和短按更準確地說是判斷讀取到的是11.25ms的連發碼還是13.5ms的引導 ...

樓主程序每次都先執行短按,有長按再執行,沒有區分開吧
回復

使用道具 舉報

9#
ID:729845 發表于 2022-5-1 12:31 | 只看該作者
獲益匪淺
回復

使用道具 舉報

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

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表