grom 发表于 2010-6-6 22:14:14

帮忙解释按键防抖动51汇编程序语句

各位大侠,
我刚刚从事单片机这一行,需要写按键控制开关功能的汇率程序,但是用的是义隆单片机,在网上找了一个例程,是51单片机的,不能很好的理解,请熟悉51单片机的大侠能否写每一个语句的解释。我想按这个程序搬到义隆的单片机上。先谢过!
网上找的例程如下:
经典按键防抖动51汇编程序
;四独立按键控制四LED;
;四个独立按键对应四个独立的LED;
;当某一个按键按下时对应的LED亮,当第二次按下时灭。
;四个LED只有一个亮,初学者可以参考以下程式:
;当一直按下某一按键时对应的LED会闪动。
;————————————————————————
        K1        BIT        P1.4
        K2        BIT        P1.5
        K3        BIT        P1.6
        K4        BIT        P1.7

        FLAG0         BIT        20H.0        ;LED0标记
        FLAG1        BIT        20H.1        ;LED1标记
        FLAG2        BIT        20H.2        ;LED2标记
        FLAG3        BIT        20H.3        ;LED3标记

        K_OLD        EQU        30H
        K_NEW        EQU        31H
;______________________________________________________________
        ORG        0000H
        JMP        MAIN
        ORG        0030H
;_______________________________________________________________
MAIN:
        MOV         SP,#60H
        MOV         P1,#0FFH
        MOV         P0,#0FFH
        MOV        K_OLD,#00H
        MOV        20H,#0FFH
MAIN1:
        CALL        K_SCAN                ;键扫描
        MOV        A,K_NEW
        CJNE        A,K_OLD,        MAIN2
        JMP        MAIN1
MAIN2:
        CALL        DELAY                ;延时除去抖动
        CALL        K_SCAN                ;再判断键是否按下
        MOV        A,K_NEW
        CJNE        A,K_OLD,MAIN3
        JMP        MAIN1
MAIN3:
        JB         ACC.0,LOOP1                ;K1按下
        JB         ACC.1,LOOP2                ;K2按下
        JB         ACC.2,LOOP3                ;K3按下
        JB         ACC.3,LOOP4                ;K4按下
        JMP        MAIN1
LOOP1:
        JNB        FLAG0,LOOP1A
        MOV        P0,#0FEH
        MOV        20H,#0EH        ;FLAG0=0
        JMP        MAIN1
LOOP1A:
        MOV        P0,#0FFH
        MOV        20H,#0FH       
        JMP        MAIN1       
LOOP2:
        JNB         FLAG1,LOOP1A
        MOV         P0,#0FDH
        MOV        20H,#0DH        ;FLAG1=0
        JMP        MAIN1
LOOP2A:
        MOV        P0,#0FFH
        MOV        20H,#0FH
        JMP        MAIN1
LOOP3:
        JNB         FLAG2,LOOP3A
        MOV        P0,#0FBH
        MOV         20H,#0BH        ;FLAG2=0
        JMP        MAIN1
LOOP3A:
        MOV        P0,#0FFH
        MOV        20H,#0FH
        JMP        MAIN1
LOOP4:
        JNB         FLAG3,LOOP4A
        MOV        P0,#0F7H
        MOV         20H,#07H        ;FLAG3=0
        JMP        MAIN1
LOOP4A:
        MOV        P0,#0FFH
        MOV        20H,#0FH
        JMP        MAIN1
;_______________________________________________________________
;键扫描子程序
;———————————————————————————
K_SCAN:
        MOV        P1,#0FFH
        MOV        K_NEW,#00H
        MOV        A,#00H
        MOV        C,K4
        CPL        C
        RLC        A
        MOV        C,K3
        CPL        C
        RLC        A
        MOV        C,K2
        CPL        C
        RLC        A
        MOV        C,K1
        CPL        C
        RLC        A
        MOV        K_NEW,A
        RET
;__________________________________
;延时子程序
;——————————————————————————
DELAY:
        MOV        R6,#200
DEL:
        MOV        R7,#0FFH
        DJNZ        R7,$
        DJNZ        R6,DEL
        RET       
;_______________________________________________________
;可以将 K_SCAN 子程序更改为:
/*
K_SCAN:
        MOV        P1,#0FFH
        MOV         K_NEW,#00H
        MOV        A,P1
        CPL        A
        ANL        A,#0F0H
        SWAP        A
        MOV        K_NEW,A       
        RET
*/

taishandadi 发表于 2010-6-6 22:54:44

每一天指令都简单,重要的是你要理解程序的思路。不知道你对51的汇编指令熟悉不?

xxbwang 发表于 2010-6-6 23:17:13

我感觉用C比较方便吧   汇编的舞台不在51单片机上

grom 发表于 2010-6-7 09:51:16

回复【1楼】taishandadi
-----------------------------------------------------------------------
对51的只能是了解吧,要是都熟悉的话,就不用在此请教了。想总体的看一下这个程序 的功能和相关语句的作用。是其他单片机上要用

风雨无阻88 发表于 2016-4-1 21:33:22

这个要是用C写该如何写呢

jxchen 发表于 2016-4-3 21:46:31

本帖最后由 jxchen 于 2016-4-3 22:15 编辑


;===============================================================


;我剛剛從事單片機這一行,需要寫按鍵控制開關功能的匯率程式,但是用的是義隆單片機,在網上找了一個例程,是51單片機的,不能很好的理解,請熟悉51單片機的大俠能否寫每一個語句的解釋。我想按這個程式搬到義隆的單片機上。先謝過!
;網上找的例程如下:
;經典按鍵防抖動51彙編程式
;;四獨立按鍵控制四LED;
;;四個獨立按鍵對應四個獨立的LED;
;;當某一個按鍵按下時對應的LED亮,當第二次按下時滅。
;;四個LED只有一個亮,初學者可以參考以下程式:
;;當一直按下某一按鍵時對應的LED會閃動。
;;————————————————————————
      K1      BIT      P1.4
      K2      BIT      P1.5
      K3      BIT      P1.6
      K4      BIT      P1.7

      FLAG         DATA       20H
      FLAG0      BIT      20H.0      ;LED0標記
      FLAG1      BIT      20H.1      ;LED1標記
      FLAG2      BIT      20H.2      ;LED2標記
      FLAG3      BIT      20H.3      ;LED3標記

      ORG       00H
      JMP       MAIN
      ORG       030H
;_______________________________________________________________
MAIN:
      CLR       EA
      MOV       R0,#7FH             ;清除內部記憶體
CLRRAM: MOV       @R0,#0
      DJNZ      R0,CLRRAM

      MOV       SP,#5FH             ;設定堆疊
      MOV       P0,#0FFH
      MOV       P1,#0FFH      
      MOV       P2,#0FFH      
      MOV       P3,#0FFH      
      MOV       FLAG,#0H
MAIN1:
      JNB       K1,_KEY1
      JNB       K2,_KEY2
      JNB       K3,_KEY3
      JNB       K4,_KEY4
      JMP       MAIN1
;-------------------------------------------------------------
_KEY1:
      CALL      DELAY               ;延時除去抖動
      JB      K1,MAIN1            ;再判斷鍵是否按下
      JB      FLAG0,L0023A          ;檢查是否第一次按下
      SETB      FLAG0
      MOV       P0,#0FFH            ;LED ALL OFF
      MOV       P0,#0FEH            ;LED1 ON
      JMP       MAIN1
L0023A:
      CLR       FLAG0
      MOV       P0,#0FFH            ;LED1 OFF
      JMP       MAIN1
;;-------------------------------------------------------------
_KEY2:
      CALL      DELAY               ;延時除去抖動
      JB      K1,MAIN1            ;再判斷鍵是否按下
      JB      FLAG1,L0023B          ;檢查是否第一次按下
      SETB      FLAG1
      MOV       P0,#0FFH            ;LED ALL OFF
      MOV       P0,#0FDH            ;LED2 ON
      JMP       MAIN1
L0023B:
      CLR       FLAG1
      MOV       P0,#0FFH            ;LED2 OFF
      JMP       MAIN1
;-------------------------------------------------------------
_KEY3:
      CALL      DELAY               ;延時除去抖動
      JB      K1,MAIN1            ;再判斷鍵是否按下
      JB      FLAG2,L0023C          ;檢查是否第一次按下
      SETB      FLAG2
      MOV       P0,#0FFH            ;LED ALL OFF
      MOV       P0,#0FCH            ;LED3 ON
      JMP       MAIN1
L0023C:
      CLR       FLAG2
      MOV       P0,#0FFH            ;LED3 OFF
      JMP       MAIN1
;-------------------------------------------------------------
_KEY4:
      CALL      DELAY               ;延時除去抖動
      JB      K1,MAIN1            ;再判斷鍵是否按下
      JB      FLAG3,L0023D          ;檢查是否第一次按下
      SETB      FLAG3
      MOV       P0,#0FFH            ;LED ALL OFF
      MOV       P0,#0FBH            ;LED4 ON
      JMP       MAIN1
L0023D:
      CLR       FLAG3
      MOV       P0,#0FFH            ;LED4 OFF
      JMP       MAIN1

DELAY:
      MOV       R5,#1
      MOV       R6,#40
LL:
      MOV       R7,#249
LABEL1:
      DJNZ      R7,LABEL1
      DJNZ      R6,LL
      DJNZ      R5,DELAY
      RET
      END

jxchen 发表于 2016-4-3 21:47:55

請參考上述程式碼

jxchen 发表于 2016-4-4 11:00:20

风雨无阻88 发表于 2016-4-1 21:33
这个要是用C写该如何写呢

#include <at89x51.h>

unsigned char bdata Flag;


sbit Flag0 = Flag ^ 0;      /* bit 0 of Flag0 */
sbit Flag1 = Flag ^ 0;      /* bit 1 of Flag1 */
sbit Flag2 = Flag ^ 0;      /* bit 2 of Flag2 */
sbit Flag3 = Flag ^ 0;      /* bit 3 of Flag3 */

sbitK1 =P1^4;
sbitK2 =P1^5;
sbitK3 =P1^6;
sbitK4 =P1^7;

void delay(unsigned int dly)
{
   while         (dly>0) dly--;
       
}               
       void main(void)
{

    EA=0;
          P0=0xFF;
          P1=0xFF;
    P2=0xFF;
          P3=0xFF;
          Flag=0;

while (1)
        {
          if (K1==0)
          {
       delay(2000);
                        if (K1==0)
                        {
                               if (Flag0==0)
                               {       
                                       Flag0=1;
                                       P0=0xFF;
                                       P0=0xFE;
                                        
         }
                               else
                               {
                                       Flag0=0;
                                       P0=0xFF;
                                                
                               }                                       
      }                                
                               
      
    }                       
          else if (K2==0)
                {
                                delay(2000);
                                if (K2==0)
                                {
                                        if (Flag1==0)
                                        {       
                                                Flag1=1;
                                                P0=0xFF;
                                                P0=0xFD;
                                        
                                        }
                                        else
                                        {
                                                Flag1=0;
                                                P0=0xFF;
                                                
                                        }                                       
                                }                                


    }                       
                else if (K3==0)
                {
                                delay(2000);
                                if (K3==0)
                                {
                                        if (Flag2==0)
                                        {       
                                                Flag2=1;
                                                P0=0xFF;
                                                P0=0xFC;
                                        
                                        }
                                        else
                                        {
                                                Flag2=0;
                                                P0=0xFF;
                                                
                                        }                                       
                                }                                


    }                               
                else if (K4==0)
                {
                                delay(2000);
                                if (K4==0)
                                {
                                        if (Flag3==0)
                                        {       
                                                Flag3=1;
                                                P0=0xFF;
                                                P0=0xFB;
                                        
                                        }
                                        else
                                        {
                                                Flag3=0;
                                                P0=0xFF;
                                                
                                        }                                       
                                }                                
    }                               
        }
       
页: [1]
查看完整版本: 帮忙解释按键防抖动51汇编程序语句