8051模拟器汇编入门(7)键盘扫描

这篇文章将向您展示如何扫描EdSim51的键盘,并且按下的键将在七段显示器上显示。

图片

位于外设区的七段显示器

让我们来看一下键盘的结构。这是EdSim51键盘接口的原理图。

图片

我想重点关注键盘的构造。通常,一个4×3的键盘是一个矩阵形式的按钮开关阵列,如这里所示。

图片

好的,让我们看看我们如何扫描按键。现在,我将根据这个图表对键盘上的按键进行编号,这是EDI SIM 51的键盘。

这是键盘的原理图,我们来检查一下这里,所以第0行连接到端口0位0或P0.0,所以那是第0行。第1行连接到P0.1,第2行连接到P0.2,第3行连接到P0.3,P0.4连接到第0列。第1列连接到P0.5,第2列连接到P0.6,注意到P0.7没有使用,并且默认所有引脚都设置为逻辑1。

图片

所以,我们将重点关注第3行,我们将讨论第2行、第1行和第0行。因此,我们需要扫描第3行,然后我们将扫描第0列、第1列和第2列,我们这样做是为了检查这三个键是否被按下。

现在,要扫描第3行,我们需要使用CLR,即清除P0.3,这将把P0.3设置为逻辑0。现在假设我们按下了编号为3的键,注意现在这里有一个完整的电路,并且它将连接到P0.4,这将把P0.4设置为0,我们可以使用JNB(跳转如果位为0)指令来测试P0.4是否为0,如果是0,那么它将调用这个子程序来显示按键3在7段显示器上。

图片

让我们看看另外两个键。这次假设按下了编号为2的键,我们在这里得到了连接到P0.5的连接,所以现在P0.5将被设置为0,我们可以再次使用JNB(跳转如果位为0)指令来测试这个位,如果它设置为0,那么它将转到这个子程序来显示数字2在7段显示器上。

图片

现在我们保持P0.3为0,这次我们按下编号为1的键,它将使连接成立,然后再次使用JNB P0.6这次来检查0,如果是0,那么调用这个子程序来显示数字1在7段显示器上。

图片

这是我们讨论的代码部分,这部分代码将只扫描第3行。

ORG     0000H

; Scan Row3
Begin:  CLR     P0.3            ; Clear Row3
        CALL    IDCode0         ; Call scan column subroutine
        JB      F0,Done         ; If F0 is set, end program
        JMP     Begin          ; Go back to scan Row3
Done:   JMP     $              ; Program execution ends and stay here

; Scan column subroutine
IDCode0:JNB     P0.4, KeyCode03 ; If Col0 Row3 is cleared - key found
        JNB     P0.5, KeyCode13 ; If Col1 Row3 is cleared - key found
        JNB     P0.6, KeyCode23 ; If Col2 Row3 is cleared - key found
        RET

KeyCode03:
        SETB    F0              ; Key found - set F0
        MOV     R7, #0B0h       ; Code for '3'
        MOV     P1, R7          ; Display key pressed
        RET

KeyCode13:
        SETB    F0              ; Key found - set F0
        MOV     R7, #0A4h       ; Code for '2'
        MOV     P1, R7          ; Display key pressed
        RET

KeyCode23:
        SETB    F0              ; Key found - set F0
        MOV     R7, #0F9h       ; Code for '1'
        MOV     P1, R7          ; Display key pressed
        RET

        END

对于第3行,我们使用了之前讨论的CLR P0.3,这将把第三行清0,然后我们调用子程序IDCode0,扫描第0-2列。让我们假设编号为3的键被按下,那么当我们扫描第0列时,P0.4将发送0,如果是这样,它将调用子程序KeyCode03,它将把F0通用标志设置为1,这将表示找到了按键,然后它将获取编号为3的代码,发送到R7,然后从R7推送到P1,这是7段显示器,所以你将在7段显示器上得到1的显示。如果其他按键被按下,例如2和1,那么相应的子程序将被调用,并且这将在7段显示器上显示A4用于数字2。

图片

按键1被按下时,显示器显示数字1

以下是扫描所有行的代码:

;   Defining the rows and columns

;   Col2 Col1 Col0
;  +----+----+----+
;  |  1 |  2 |  3 |  Row3
;  +----+----+----+
;  |  4 |  5 |  6 |  Row2
;  +----+----|----+
;  |  7 |  8 |  9 |  Row1
;  +----+----+----+
;  |  * |  0 |  # |  Row0
;  +----+----+----+

      ;Scan Row3
Begin:    CLR P0.3      ;Clear Row3
      CALL IDCode0    ;Call scan column subroutine
      SetB P0.3      ;Set Row 3
      JB F0,Done      ;If F0 is set, end program 
            
      ;Scan Row2
      CLR P0.2      ;Clear Row2
      CALL IDCode1    ;Call scan column subroutine
      SetB P0.2      ;Set Row 2
      JB F0,Done       ;If F0 is set, end program             

      ;Scan Row1
      CLR P0.1      ;Clear Row1
      CALL IDCode2    ;Call scan column subroutine
      SetB P0.1      ;Set Row 1
      JB F0,Done      ;If F0 is set, end program 

      ;Scan Row0      
      CLR P0.0      ;Clear Row0
      CALL IDCode3    ;Call scan column subroutine
      SetB P0.0      ;Set Row 0
      JB F0,Done      ;If F0 is set, end program 
                            
      JMP Begin      ;Go back to scan Row3
              
Done:    JMP $        ;Program execution ends and stay here

      ;Scan column subroutine
IDCode0:  JNB P0.4, KeyCode03  ;If Col0 Row3 is cleared - key found
      JNB P0.5, KeyCode13  ;If Col1 Row3 is cleared - key found
      JNB P0.6, KeyCode23  ;If Col2 Row3 is cleared - key found
      RET          

KeyCode03:  SETB F0      ;Key found - set F0
      Mov R7,#0B0h  ;Code for '3'
      Mov P1,R7    ;Display key pressed
      RET        

KeyCode13:  SETB F0      ;Key found - set F0
      Mov R7,#0A4h  ;Code for '2'
      Mov P1,R7    ;Display key pressed
      RET        

KeyCode23:  SETB F0      ;Key found - set F0
      Mov R7,#0F9h  ;Code for '1'
      Mov P1,R7    ;Display key pressed
      RET        

IDCode1:  JNB P0.4, KeyCode02  ;If Col0 Row2 is cleared - key found
      JNB P0.5, KeyCode12  ;If Col1 Row2 is cleared - key found
      JNB P0.6, KeyCode22  ;If Col2 Row2 is cleared - key found
      RET          

KeyCode02:  SETB F0      ;Key found - set F0
      Mov R7,#82h    ;Code for '6'
      Mov P1,R7    ;Display key pressed
      RET        

KeyCode12:  SETB F0      ;Key found - set F0
      Mov R7,#92h    ;Code for '5'
      Mov P1,R7    ;Display key pressed
      RET        

KeyCode22:  SETB F0      ;Key found - set F0
      Mov R7,#99h    ;Code for '4'
      Mov P1,R7    ;Display key pressed
      RET        

IDCode2:  JNB P0.4, KeyCode01  ;If Col0 Row1 is cleared - key found
      JNB P0.5, KeyCode11  ;If Col1 Row1 is cleared - key found
      JNB P0.6, KeyCode21  ;If Col2 Row1 is cleared - key found
      RET          

KeyCode01:  SETB F0      ;Key found - set F0
      Mov R7,#90h    ;Code for '9'
      Mov P1,R7    ;Display key pressed
      RET        

KeyCode11:  SETB F0      ;Key found - set F0
      Mov R7,#80h    ;Code for '8'
      Mov P1,R7    ;Display key pressed
      RET        

KeyCode21:  SETB F0      ;Key found - set F0
      Mov R7,#0F8h  ;Code for '7'
      Mov P1,R7    ;Display key pressed
      RET        

IDCode3:  JNB P0.4, KeyCode00  ;If Col0 Row0 is cleared - key found
      JNB P0.5, KeyCode10  ;If Col1 Row0 is cleared - key found
      JNB P0.6, KeyCode20  ;If Col2 Row0 is cleared - key found
      RET          

KeyCode00:  SETB F0      ;Key found - set F0
      Mov R7,#0BFh  ;Code for '-' replacing '#'. '#' cannot be display on 7-segment
      Mov P1,R7    ;Display key pressed
      RET        

KeyCode10:  SETB F0      ;Key found - set F0
      Mov R7,#0C0h  ;Code for '0'
      Mov P1,R7    ;Display key pressed
      RET        

KeyCode20:  SETB F0      ;Key found - set F0
      Mov R7,#0BFh  ;Code for '-' replacing '*'. '*' cannot be display on 7-segment
      Mov P1,R7    ;Display key pressed
      RET        
      
      End