.c 代码:
002 // File Name : keyboard.c
003 // Author : Coolbor Xie
004 // Created : 2009-11-13
005 // Modified : CWM
006 // Revision : V0.1
007 // Modified Time :2011-06-15
008 //***************************************************************
009 #ifndef _keyboard_c_
010 #define _keyboard_c_
011
012 #include <reg52.h>
013 #include <intrins.h>
014 #include "keyboard.h"
015
016 //***************************************************************
017 //端口定义
018 //PIN DESCRIPTION
019 //P17 P16 P15 P14
020 // | | | |
021 // /---/---/---/---P10 1 2 3 F1
022 // /---/---/---/---P11 4 5 6 F2
023 // /---/---/---/---P12 7 8 9 F3
024 // /---/---/---/---P13 * 0 # F4
025 //***************************************************************
026 #define KeyPort P1
027
028 #define key_state_0 0 //定义按键状态(基于状态机)
029 #define key_state_1 1
030 #define key_state_2 2
031 #define key_state_3 3
032
033 #define NO_key 0
034 //***************************************************************
035 // Function : KeyBoardScan
036 // Input : none
037 // Output : Key Number
038 // 0~9、*、#:ASCII code
039 // F1、F2、F3、F4: (A、B、C、D) ASCII code
040 // Description : 4*4 matrix keyboard scanning Function
041 //
042 //***************************************************************
043 uchar KeyBoardScan( void)
044 {
045 uchar key_temp;
046 uchar key_num = NO_key;
047 static uchar key_status = key_state_0; //按键状态
048
049 //线反转法扫描键盘
050 KeyPort = 0x0f; //置按键口
051 key_temp = KeyPort; //按键口
052 KeyPort = 0xf0;
053 key_temp |= KeyPort;
054 KeyPort = 0xff;
055 switch( key_status)
056 {
057 case key_state_0 :
058 if( key_temp != 0xff)
059 key_status = key_state_1;
060 break;
061 case key_state_1 :
062 if( key_temp == 0xff)
063 key_status = key_state_0;
064 else
065 {
066 key_status = key_state_2;
067 switch( key_temp)
068 {
069 case 0x7e : //0111 1110
070 key_num = '1';
071 break;
072 case 0xbe : //1011 1110
073 key_num = '2';
074 break;
075 case 0xde : //1101 1110
076 key_num = '3';
077 break;
078 case 0x7d : //0111 1101
079 key_num = '4';
080 break;
081 case 0xbd : //1011 1101
082 key_num = '5';
083 break;
084 case 0xdd : //1101 1101
085 key_num = '6';
086 break;
087 case 0x7b : //0111 1011
088 key_num = '7';
089 break;
090 case 0xbb : //1011 1011
091 key_num = '8';
092 break;
093 case 0xdb : //1101 1011
094 key_num = '9';
095 break;
096 case 0xb7 : //1011 0111
097 key_num = '0';
098 break;
099 case 0x77 : //0111 0111
100 key_num = '*'; //*
101 break;
102 case 0xd7 : //1101 0111
103 key_num = '#'; //#
104 break;
105 case 0xee : //1110 1110
106 key_num = 'A'; //F1
107 break;
108 case 0xed : //1110 1101
109 key_num = 'B'; //F2
110 break;
111 case 0xeb : //1110 1011
112 key_num = 'C'; //F3
113 break;
114 case 0xe7 : //1110 0111
115 key_num = 'D'; //F4
116 break;
117 }
118 }
119 break;
120 case key_state_2 :
121 if( key_temp == 0xff)
122 key_status = key_state_3;
123 break;
124 case key_state_3 :
125 if( key_temp == 0xff)
126 key_status = key_state_0;
127 else
128 key_status = key_state_2;
129 break;
130 }
131 return key_num;
132 }
133
134
135 #endif
136 //===============================END OF FILE==================================//
.H文件
02 // Author : Coolbor Xie
03 // Created : 2009-11-13
04 // Modified : CWM
05 // Revision : V0.1
06 // Modified Time :2011-06-15
07 //***************************************************************
08 #ifndef _keyboard_h_
09 #define _keyboard_h_
10 #include <reg52.h>
11 #define uchar unsigned char
12 //***************************************************************
13 //端口定义
14 //PIN DESCRIPTION
15 //P17 P16 P15 P14
16 // | | | |
17 // /---/---/---/---P10 1 2 3 F1
18 // /---/---/---/---P11 4 5 6 F2
19 // /---/---/---/---P12 7 8 9 F3
20 // /---/---/---/---P13 * 0 # F4
21 //***************************************************************
22
23
24 //global functions declaration
25 extern uchar KeyBoardScan( void);
26
27 #endif
28 //===============================END OF FILE==================================//
调用示例:
01 #include <keyboard.h>
02 #include <reg52.h>
03
04 void system_Ini()
05 {
06 TMOD|= 0x00;
07 TH1=0x1c;//12.000M
08 TL1=0x18;//定时器1工作在方式0下 定时1ms
09 IE = 0x8A;
10 TR1 = 1;
11 }
12
13 void main()
14 {
15 system_Init();
16 if(key_stime_ok==1)
17 {
18 switch(KeyBoardScan())//每10ms调用一次键盘扫描消抖
19 {
20 case '1':
21 case '2':
22 .
23 .
24 .
25 }
26 }
27
28 }
29
30 void Timer1(void) interrupt 3
31 {
32 TH1 = 0x1c;//12.000
33 TL1 = 0x18;
34 if(++key_stime_counter>=10)//到达10ms
35 {
36 key_stime_counter=0;
37 key_stime_ok=1;
38 }
39 }
体会:
对于矩阵键盘 关键问题是掌握其扫描方法,比较好的是如上所述的线反转法,其程序设计 流程如下图:
详细内容可参见:http://wenku.baidu.com/view/055962669b6648d7c1c7468e.html