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

標(biāo)題: 單片機(jī)定時(shí)器中斷按鍵掃描程序如何檢測長按狀態(tài)? [打印本頁]

作者: PDDDF    時(shí)間: 2019-12-24 16:50
標(biāo)題: 單片機(jī)定時(shí)器中斷按鍵掃描程序如何檢測長按狀態(tài)?

unsignedchar Trg;

unsignedchar Cont;

voidKeyRead( void )

{

   unsigned char ReadData = PINB^0xff;   // 1

   Trg = ReadData & (ReadData ^ Cont);      // 2

   Cont =ReadData;                               // 3

}

網(wǎng)上流傳很廣的3句語句實(shí)現(xiàn)按鍵掃描,自己用卻不會(huì)用,只能做到檢測單擊按鍵,長按和雙擊檢測不會(huì)做,求大佬指點(diǎn)



作者: PDDDF    時(shí)間: 2019-12-24 17:24
void key_scan()
{
        uchar S,b;
        S = P1^0xff;
  if(0<S && S == R)
        {
                b = T;
                T = S&(S^R);
                R = S;
                if(b != T)
                {
                        if(S == 0x20) {key = 1;        return;}
                  if(S == 0x10) {key = 2; return;}
            if(S == 0x08) {key = 3; return;}
                  if(S == 0x18) {key = 8; return;}
                }
                else
                {
                        if(S == 0x20) {key = 4; return;}
                  if(S == 0x10) {key = 5; return;}
                  if(S == 0x08) {key = 6; return;}
                  if(S == 0x18) {key = 9; return;}
                }
        }
        else
        {
                T = S&(S^R);
                R = S;
        }
}
1238為對應(yīng)按鍵的單擊標(biāo)識(shí),4569為對應(yīng)按鍵的長按標(biāo)識(shí),共4個(gè)按鍵, key_scan()放在中斷函數(shù)里面,20MS掃描一次
while(1)
{
        switch (key)
        {
            case......
        }
}循環(huán)執(zhí)行返回按鍵標(biāo)識(shí)的對應(yīng)程序
問題:無法辨別是單擊或是長按,按了幾下后卡死
作者: wulin    時(shí)間: 2019-12-24 23:17
不是簡單的3條代碼就搞定的,這只是讀鍵過程,還要有其配套服務(wù)程序解讀才能生效。
應(yīng)用示例:
  1. /*********************************************************
  2. 按時(shí)間片運(yùn)行讀鍵與觸發(fā)的單片機(jī)程序,定時(shí)器0工作在時(shí)間片
  3. 定時(shí)器1做蜂鳴器振蕩器,LED演示任務(wù)狀態(tài)。
  4. *********************************************************/
  5. #include "STC89xx.H"                         //單片機(jī)頭文件
  6. #include <intrins.h>                        //
  7. #define uint unsigned int                 //宏定義變量uint為無符號整型數(shù)據(jù)(0-65535)
  8. #define uchar unsigned char         //宏定義變量uchar為無符號字符型數(shù)據(jù)(0-255)
  9. #define KEY_MODE 0x80                        //按鍵宏定義
  10. #define KEY_PLUO 0x80                        //按鍵宏定義
  11. #define KEY_MODE1 0x40                        //按鍵宏定義
  12. #define KEY_PLUO1 0x40                        //按鍵宏定義
  13. #define LED P1                                        //LED宏定義
  14. sbit Buzzer=P2^3;                                //蜂鳴器端口定義
  15. uchar Trg;                                                //Trg(triger) 單擊鍵值全局變量
  16. uchar Cont;                                                //Cont(continue)長擊鍵值全局變量
  17. uchar Repeat;                                        //蜂鳴器重復(fù)次數(shù)變量
  18. uchar Intrcnt;                                        //定時(shí)器1中斷時(shí)標(biāo)
  19. bit Buzzer_sign=0;                                //蜂鳴器使能標(biāo)志位
  20. void KeyRead();                                        //按鍵掃描程序
  21. void KeyProc();                                        //按鍵服務(wù)程序
  22. void Timer_Init();                                //初始化定時(shí)器0/1
  23. void BuzzerSign();                                //蜂鳴器驅(qū)動(dòng)程序

  24. void main()                                                //主函數(shù)
  25. {                                                                //初始化數(shù)據(jù)       
  26.         LED=0xFE;                                        //LED初始化
  27.         Buzzer=1;                                        //蜂鳴器端口初始化
  28.         Timer_Init();                                //初始化定時(shí)器初始化

  29.         while(1)                                        //每20ms 執(zhí)行一次大循環(huán)
  30.         {
  31.                 KeyRead();              //將每個(gè)子程序都掃描一遍
  32.                 KeyProc();
  33.                 BuzzerSign();
  34. /**************************************************/
  35.                 while(1)
  36.                 {
  37.                         if(Intrcnt>100)                // 一直在等,直到20ms時(shí)間到
  38.                         {
  39.                                 Intrcnt=0;
  40.                                 break;               // 返回主循環(huán)
  41.                         }
  42.                 }
  43.         }
  44. }

  45. void KeyRead()                                        //讀鍵獲取鍵值
  46. {
  47.     uchar ReadData = P3^0xFF;   //ReadData 臨時(shí)變量,"^"按位異或運(yùn)算:如果a、b兩個(gè)值不相同!
  48.                                                                 //則異或結(jié)果為1。如果a、b兩個(gè)值相同,異或結(jié)果為0。
  49.     Trg = ReadData & (ReadData ^ Cont); //獲取短按鍵值
  50.     Cont = ReadData;                    //獲取長按鍵值
  51. }

  52. void KeyProc()                                                //判斷鍵值執(zhí)行相應(yīng)任務(wù)
  53. {
  54.         uchar cnt_plus,cnt_plus1;                //定義2個(gè)計(jì)時(shí)變量
  55.         if (Trg & KEY_MODE)                         // 如果按下的是KEY_MODE,而且你長按這按鍵也沒有用,
  56.         {
  57.                 Repeat = 1;                                        //賦值蜂鳴器重復(fù)次數(shù)變量
  58.                 LED=_cror_(LED,1);                        //LED循環(huán)右移1位// 可執(zhí)行任何代碼
  59.         }
  60.         if (Cont & KEY_PLUO)                         //如果KEY_PLUO按著不放
  61.         {
  62.                 cnt_plus++;                              // 計(jì)時(shí)
  63.                 if(cnt_plus > 50)                         // 20ms*100 = 2S 如果時(shí)間到執(zhí)行長按功能
  64.                 {
  65.                         cnt_plus = 50;                        //計(jì)數(shù)限制
  66.                         cnt_plus1++;
  67.                         if (cnt_plus1 >= 10)                //20ms*10 = 0.2S(長按功能啟動(dòng)后每0.2S執(zhí)行一次下層功能)
  68.                         {
  69.                                 cnt_plus1=0;
  70.                                 LED=_crol_(LED,1);        //LED循環(huán)左移1位
  71.                                 Repeat = 1;                        //賦值蜂鳴器重復(fù)次數(shù)變量
  72.                         }
  73.                 }         
  74.         }
  75.         else cnt_plus=cnt_plus1=0;                 //計(jì)時(shí)變量清0       
  76. }
  77. void BuzzerSign()                        //蜂鳴器驅(qū)動(dòng)程序
  78. {
  79.         if (Repeat & (Repeat ^ Buzzer_sign))//如果蜂鳴器重復(fù)次數(shù)變量Repeat>0、
  80.                 //蜂鳴器使能標(biāo)志Buzzer_sign=0
  81.                 TR1 = 1;                        //開啟定時(shí)器1
  82. }

  83. void Timer_Init()                        //200微秒@11.0592MHz
  84. {
  85. //        AUXR &= 0xBF;                        //定時(shí)器時(shí)鐘12T模式(1T要設(shè)置AUXR)
  86.         TMOD &= 0xFF;                        //設(shè)置定時(shí)器模式8位重載
  87.         TMOD |= 0x22;                        //設(shè)置定時(shí)器模式8位重載
  88.         TL1 = 0x48;                                //設(shè)置定時(shí)初值
  89.         TH1 = 0x48;                                //設(shè)置定時(shí)重載值
  90.         TL0 = 0x48;                                //設(shè)置定時(shí)初值
  91.         TH0 = 0x48;                                //設(shè)置定時(shí)重載值
  92.         TF1 = 0;                                        //清除TF1標(biāo)志
  93.         TR0 = 1;                                        //定時(shí)器0開始計(jì)時(shí)
  94. //        TR1 = 1;                                        //定時(shí)器1開始計(jì)時(shí)
  95.         EA=1;                                                //開總中斷
  96.         ET0=1;                                        //開定時(shí)器0中斷       
  97.         ET1=1;                                        //開定時(shí)器1中斷       
  98. }

  99. void timer0() interrupt        1        //中斷服務(wù)程序(定時(shí)器中斷函數(shù)timer0)
  100. {                                                                        //interrupt        0:外部中斷0,1:定時(shí)器中斷0,
  101.                                                                         //2:外部中斷1,3:定時(shí)器中斷1、串行口中斷
  102.                                                                         //中斷程序不需要聲明
  103.         Intrcnt++;                                        //定時(shí)器中斷變量200us自+1
  104. }
  105. void timer1() interrupt        3        //中斷服務(wù)程序(定時(shí)器1中斷函數(shù))
  106. {
  107.         uint Cnt200us;                        //定時(shí)器中斷計(jì)數(shù)變量
  108.         Cnt200us++;                                //中斷變量Cnt200us自+1

  109.         if(Cnt200us<=300)
  110.                 Buzzer=~Buzzer;                //蜂鳴器端口取反
  111.         if(Cnt200us>300)                //檢測中斷的次數(shù)>300                       
  112.                 Buzzer=1;                        //蜂鳴器端口清0
  113.                 Buzzer_sign=1;                //蜂鳴器使能標(biāo)志位置1
  114.         if(Cnt200us>=900)                //檢測中斷的次數(shù)>=600
  115.         {                                                        //兩次鳴響之間間隔時(shí)間
  116.                 Buzzer_sign=0;                //蜂鳴器使能標(biāo)志位清0
  117.                 Cnt200us=0;                        //計(jì)數(shù)清0
  118.                 TR1=0;                                //關(guān)閉定時(shí)器
  119.                 Repeat--;                        //蜂鳴器重復(fù)次數(shù)變量自-1                              
  120.                 if(Repeat<=0)                //判斷蜂鳴器重復(fù)次數(shù)
  121.                         Repeat=0;                //蜂鳴器重復(fù)次數(shù)變量清0
  122.         }
  123. }
復(fù)制代碼

作者: PDDDF    時(shí)間: 2019-12-25 08:58
wulin 發(fā)表于 2019-12-24 23:17
不是簡單的3條代碼就搞定的,這只是讀鍵過程,還要有其配套服務(wù)程序解讀才能生效。
應(yīng)用示例:

我最搞不懂的就是這個(gè)按鍵掃描是怎樣做到消抖的,掃描我是放在中斷里面執(zhí)行的,一旦有觸發(fā)信號(假設(shè)0x01),read Trg Con的值都為0x01,下一個(gè)中斷到來時(shí)如果是真的按下(read繼續(xù)讀到0x01)那經(jīng)過這個(gè)按鍵掃描算法的處理就變?yōu)閞ead 0x01     Trg 0x00  Con 0x01 ,那判斷兩次讀取的值一樣才算消抖啊,但是這樣就判斷不了長按了,因?yàn)橐恢遍L按 R  T  C 的值都沒變的,還是read 0x01     Trg 0x00  Con 0x01 ,這樣我就搞不懂了
作者: wulin    時(shí)間: 2019-12-25 10:38
PDDDF 發(fā)表于 2019-12-25 08:58
我最搞不懂的就是這個(gè)按鍵掃描是怎樣做到消抖的,掃描我是放在中斷里面執(zhí)行的,一旦有觸發(fā)信號(假設(shè)0x01 ...

這是原作者的解釋,是在特定的程序構(gòu)架下才有效。
一款精巧的按鍵處理程序.doc (36.5 KB, 下載次數(shù): 51)


作者: PDDDF    時(shí)間: 2019-12-25 11:50
wulin 發(fā)表于 2019-12-25 10:38
這是原作者的解釋,是在特定的程序構(gòu)架下才有效。

謝謝大佬
作者: 還有誰?    時(shí)間: 2019-12-25 13:39
其實(shí)思路很簡單,在定時(shí)中斷中判斷一個(gè)按健按下來開始計(jì)數(shù),然后這樣:if((K1<40) && (K1>5) && (ON_flag==1))//消抖時(shí)間+去抖時(shí)間+開關(guān)標(biāo)記,后面處理好清0事宜就好了
作者: 1394077003    時(shí)間: 2019-12-25 18:37
太好了  又學(xué)到了新知識(shí)  好評

作者: ahshmj    時(shí)間: 2019-12-25 18:54
和處理鍵抖動(dòng)一回事,N次檢測仍未釋放就是長按......,N次加或減1,2N次加減2......,快速雙擊道理一樣,檢測的時(shí)間間隔不同。




歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1