【单片机实验】矩阵键盘

实验五 矩阵键盘

一、实验目的

1、掌握矩阵键盘的硬件电路原理和软件编程方法;
2、掌握利用数码管显示矩阵键盘键值的编程方法。
二、实验说明

本实验提供了一个4X4小键盘,开始先将4行置一,4列置零,判断是否有键按下,如果有键按下,则逐列判断。键值判断方法:行*4+列,在有键按下后,要有一定的延时,防止键盘抖动。

三、实验内容及步骤
内容:
程序功能按下矩阵键盘单元键盘,静态显示单元数码管显示对应数字。
步骤:
1、根据硬件连接电路,编写程序并编译生成*.hex文件;
2、打开实验箱电源;
3、参照STC12C5A60S2下载说明中STC_ISP软件使用说明,向单片机中下载程序;
4、通过排线,将单片机最小系统单元的P2口的0-7与矩阵键盘单元的J0701的0-7一一对应相,通过信号线将单片机最小系统单元的P1.0、P1.1、P1.2分别与静态显示单元的SER、SRCLK、RCLK相连;
5、打开静态显示单元开关;
6、观察静态显示单元的LED1106数码管显示情况,若显示结果不正确,请修改该程序,重复以上操作。

  1 DAT BIT P1.0
  2   SRCLK BIT P1.1
  3   RCLK BIT P1.2
  4   ORG 00H
  5 LJMP MAIN
  6 ORG 0080H
  7 MAIN:
  8  MOV SP,#50H
  9  MOV 30H,#10H ;键值存放在30H单元中 
 10 SLOOP:
 11  ACALL JTXS     
 12  ACALL DELAY
 13  ACALL KEYSCAN
 14  SJMP SLOOP
 15 KEYSCAN:
 16   MOV R0,#00H
 17 LOOP:
 18   MOV P2,#0F0H ;将列清零 
 19   MOV A,P2
 20   CJNE A,#0F0H,KEY1     ;判断是否有键按下 
 21   LJMP  LOOP
 22 KEY1:
 23   ACALL DELAY      ;延时去抖动 
 24   MOV P2,#0F0H
 25   NOP
 26   NOP
 27   MOV A,P2
 28   CJNE A,#0F0H,KEY2       ;判断键值 
 29   LJMP  LOOP
 30 KEY2:
 31   MOV 31H,#0FEH    ;将第一列置一 
 32   MOV A,31H
 33 HANG:
 34   MOV P2,A
 35   MOV 31H,A
 36   MOV B,R0    ;代表第几行 
 37   ACALL LIE
 38   INC R0
 39   MOV A,31H
 40   RL A
 41   CJNE R0,#04H,HANG
 42   RET
 43 LIE:  ;判断列值 
 44   MOV A,P2
 45   ANL A,#0F0H
 46   CJNE A,#0E0H,K2
 47   MOV 32H,#00  ;第一列 
 48   SJMP JIE
 49 K2:
 50   CJNE A,#0D0H,K3
 51   MOV 32H,#01     ;第二列 
 52   SJMP JIE
 53 K3:
 54   CJNE A,#0B0H,K4
 55   MOV 32H,#02      ;第三列 
 56   SJMP JIE  
 57 K4:
 58   CJNE A,#70H,LEND
 59   MOV 32H,#03
 60   SJMP JIE            ;第四列 
 61 JIE:
 62   MOV A,#04H   ;行*4+列 
 63   MUL AB
 64   MOV B,32H
 65   ADD A,B
 66   MOV 30H,A
 67 LEND:
 68   RET
 69   ;静态显示 
 70 JTXS:
 71   MOV 31H,#10H
 72   MOV 32H,#10H 
 73   MOV 33H,#10H
 74   MOV 34H,#10H
 75   MOV 35H,#10H
 76 CHANGE:
 77   MOV R2,#06H
 78   MOV DPTR,#TABLE
 79   MOV R0,#30H
 80   MOV R1,#40H
 81 LOOP3:
 82   MOV A,@R0
 83   MOVC A,@A+DPTR
 84   MOV @R1,A
 85   INC R0
 86   INC R1
 87   DJNZ R2,LOOP3
 88 ZYXS:
 89   MOV R2,#06H
 90   MOV R1,#08H
 91   MOV R0,#40H
 92 LOOP2:
 93   MOV A,@R0
 94   MOV R1,#08H
 95 LOOP1:
 96   CLR SRCLK
 97   RLC A 
 98   MOV DAT,C
 99   NOP;
100   SETB SRCLK
101   DJNZ R1,LOOP1
102   INC R0
103   DJNZ R2,LOOP2
104   CLR RCLK
105   NOP;
106   NOP;
107   NOP;
108   SETB RCLK
109   RET
110 TABLE:
111   DB 3FH,06H,5BH,4FH,66H,6DH
112   DB 7DH,07H,7FH,6FH,77H,7CH
113   DB 39H,5EH,79H,71H,00H
114 DELAY:
115   MOV R1,#20H
116 DELAY1:
117   MOV R2,#00H
118 DELAY2:
119   DJNZ R2,DELAY2
120   DJNZ R1,DELAY1
121   RET
122   END
汇编写法

 

 1 #include <reg51.h>
 2 #include <intrins.h>
 3 unsigned char buf1[6] = { 16,16,16,16,16,16 };
 4 unsigned char buf2[6];
 5 unsigned char code table[] = { 0x3F,0x06,0x5B,0x4F,
 6                                0x66,0x6D,0x7D,0x07,
 7                                0x7F,0x6F,0x77,0x7C,
 8                                0x39,0x5E,0x79,0x71,
 9                                0x00 };
10 sbit ser = P1 ^ 0 ;
11 sbit srclk = P1 ^ 1 ;
12 sbit rclk = P1 ^ 2;
13 void main( void ){
14     unsigned char i,j,temp1, temp2;
15     unsigned char row,k,l,keyvalue = 0x10;
16     TMOD = 0x01 ; 
17     TH0 = 0xCA;
18     TL0 = 0x0B;
19     TR0 = 0 ;
20     TF0 = 0 ;
21     while ( 1 ) {
22          P2 = 0xF0;
23         if( P2 != 0xF0 ){
24              TMOD = 0x01 ;
25             TH0 = 0xCA;
26             TL0 = 0x0B;
27             TF0 = 0 ;
28             TR0 = 1 ;
29             while ( TF0 == 0 );
30             TF0 = 0 ;
31             TR0 = 0 ;    //延迟 15ms 左右,关闭定时器
32             if( P2!= 0xF0 )
33             {
34                 k = 0xFE;
35                 row = 0;
36                 for ( l = 0 ; l < 4 ; l++ )
37                 {
38                      P2 = k ; 
39                     if( ( P2 & 0xF0 ) == 0xE0 ) {
40                          keyvalue = row * 4 + 0 ; 
41                     }else if ( (P2&0xF0) == 0xD0 ) {
42                          keyvalue = row * 4 + 1 ;
43                     }else if ( (P2&0xF0) == 0xB0 ) {
44                          keyvalue = row * 4 + 2 ;
45                     }else if ( (P2&0xF0) == 0x70 ) {
46                          keyvalue = row * 4 + 3 ;
47                     }else {
48                          row ++ ;
49                         k = _crol_( k ,1  ) ;
50                         keyvalue = 16;
51                     }
52                     buf1[ 0 ] = keyvalue ;
53                     if( keyvalue != 16 ) 
54                     {
55                         P2 = 0xF0;
56                         while(P2!=0xf0);
57                          break;
58                     }
59                 }
60                     
61             }    
62         }
63         srclk = 0 ;
64         rclk = 0 ;
65         for ( i = 0 ; i < 6; i++ ) {
66              buf2[i] = table[buf1[i]];
67             temp1 = buf2[i];
68             for( j = 0 ; j < 8 ; j++ ){
69                  srclk = 0;
70                 temp2 = ( temp1 & 0x80 );
71                 if( temp2 ) {
72                      ser = 1 ;
73                 }else {
74                      ser = 0 ;
75                 }
76                 srclk = 1 ;
77                 _nop_();
78                 temp1 <<= 1 ;
79                 srclk = 0 ;
80 
81             }
82         }
83         rclk = 1 ;
84     }
85     return ;
86 }    
逐列排除法

 

 1 #include <reg51.h>
 2 #include <intrins.h>
 3 unsigned char buf1[6] = { 16,16,16,16,16,16 };
 4 unsigned char buf2[6];
 5 unsigned char code table[] = { 0x3F,0x06,0x5B,0x4F,
 6                                0x66,0x6D,0x7D,0x07,
 7                                0x7F,0x6F,0x77,0x7C,
 8                                0x39,0x5E,0x79,0x71,
 9                                0x00 };
10 sbit ser = P1 ^ 0 ;
11 sbit srclk = P1 ^ 1 ;
12 sbit rclk = P1 ^ 2;
13 void main( void ){
14     unsigned char i,j,temp1, temp2, temp ;
15     unsigned char row,k,l,keyvalue = 0x10;
16     TMOD = 0x01 ; 
17     TH0 = 0xCA;
18     TL0 = 0x0B;
19     TR0 = 0 ;
20     TF0 = 0 ;
21     while ( 1 ) 
22     
23     {
24          P2 = 0xF0;
25         i=P2;
26         if( i != 0xF0 ){
27              TMOD = 0x01 ;
28             TH0 = 0xCA;
29             TL0 = 0x0B;
30             TF0 = 0 ;
31             TR0 = 1 ;
32             while ( TF0 == 0 );
33             TF0 = 0 ;
34             TR0 = 0 ;    //延迟 15ms 左右,关闭定时器
35             
36             if( P2!= 0xF0 )
37             {
38                 temp1 = P2 ;
39                 _nop_();
40                 _nop_();
41                 //_nop_();
42                 P2 = 0x0F;
43                 temp2 = P2 ;
44 
45                 temp = ( temp1 | temp2 );
46                 
47                 switch ( temp ) {
48                      case 0xEE : keyvalue = 0 ; break ; 
49                     case 0xDE : keyvalue = 1 ; break ;
50                     case 0xBE : keyvalue = 2 ; break ;
51                     case 0x7E : keyvalue = 3 ; break ;
52                     
53                     case 0xED : keyvalue = 4 ; break ; 
54                     case 0xDD : keyvalue = 5 ; break ; 
55                     case 0xBD : keyvalue = 6 ; break ; 
56                     case 0x7D : keyvalue = 7 ; break ;
57                 
58                     case 0xEB : keyvalue = 8 ; break ; 
59                     case 0xDB : keyvalue = 9 ; break ; 
60                     case 0xBB : keyvalue = 10; break ; 
61                     case 0x7B : keyvalue = 11; break ;
62                     
63                     case 0xE7 :    keyvalue = 12; break ;
64                     case 0xD7 :    keyvalue = 13; break ;
65                     case 0xB7 : keyvalue = 14; break ;
66                     case 0x77 : keyvalue = 15; break ;
67                     default : keyvalue = 16 ; 
68                 }
69                 buf1[0] = keyvalue;
70                 P2 = 0xF0; 
71                 while ( P2 != 0xF0 ) ;
72             }
73                 
74         }
75         srclk = 0 ;
76         rclk = 0 ;
77         for ( i = 0 ; i < 6; i++ ) {
78              buf2[i] = table[buf1[i]];
79             temp1 = buf2[i];
80             for( j = 0 ; j < 8 ; j++ ){
81                  srclk = 0;
82                 temp2 = ( temp1 & 0x80 );
83                 if( temp2 ) {
84                      ser = 1 ;
85                 }else {
86                      ser = 0 ;
87                 }
88                 srclk = 1 ;
89                 _nop_();
90                 temp1 <<= 1 ;
91                 srclk = 0 ;
92 
93             }
94         }
95         rclk = 1 ;
96     }
97     return ;
98 }    
行列置换法

 

posted @ 2019-06-18 21:42  Osea  阅读(1576)  评论(0编辑  收藏  举报