📄 key_scan.lst
字号:
A51 MACRO ASSEMBLER KEY_SCAN 11/22/2007 09:15:49 PAGE 1
MACRO ASSEMBLER A51 V7.07
OBJECT MODULE PLACED IN key_scan.OBJ
ASSEMBLER INVOKED BY: C:\Program Files\Keil\C51\BIN\A51.EXE key_scan.asm SET(SMALL) DEBUG EP
LOC OBJ LINE SOURCE
1 ;********************************************************
2 ;*程序功能:在单片机教学实验仪的MCU#3上 *
3 ;*对矩阵按键进行扫描检测,将检测到的键号 *
4 ;*以移位的形式显示在8个数码管上 *
5 ;* *
6 ;********************************************************
7
0000 8 ORG 0000H
0000 802E 9 JMP MAIN
10
11 ;==================================
12 ;RAM区变量定义
13
0000 14 UP_DOWN BIT 00 ;键状态指示,0按下,1弹起
15
0030 16 DISBUF EQU 30H ;显示参数传递
0038 17 POSIT EQU 38H ;位选
0039 18 KEYBUF EQU 39H ;键码暂存
0040 19 KEYTEMP EQU 40H ;暂存待确定的扫描码
20
21 ;===================================
22 ;主函数
0030 23 ORG 0030H
0030 24 MAIN:
0030 D200 25 SETB UP_DOWN ;初始设置为弹起态
0032 753001 26 MOV DISBUF,#01H ;在第1个数码管上显示 1
0035 753102 27 MOV DISBUF+1,#02H ;在第2个数码管上显示 2
0038 753203 28 MOV DISBUF+2,#03H ;在第3个数码管上显示 3
003B 753304 29 MOV DISBUF+3,#04H ;在第4个数码管上显示 4
003E 753405 30 MOV DISBUF+4,#05H ;在第5个数码管上显示 5
0041 753506 31 MOV DISBUF+5,#06H ;在第6个数码管上显示 6
0044 753607 32 MOV DISBUF+6,#07H ;在第7个数码管上显示 7
0047 753708 33 MOV DISBUF+7,#08H ;在第8个数码管上显示 8
004A 34 LOOP:
004A 11A5 35 CALL KEY ;查键
004C 1150 36 CALL DISPLAY ;显示
004E 80FA 37 JMP LOOP
38
39 ;==================================
40 ;8路数码管驱动
0050 41 DISPLAY:
0050 753880 42 MOV POSIT,#80H ;用于指示数码管位选,初始化为第一个数码管亮
0053 7908 43 MOV R1,#08H ;用于指示程序循环,8个数码管每个送一次数后,本子程序结束
0055 900166 44 MOV DPTR,#DISCODE ;指向数码管的码表
0058 7830 45 MOV R0,#DISBUF ;指向显示数组
005A 46 DISLOOP: ;为方便起见,只将第一个数码管的执行过程讲明,其余依次类推
005A E6 47 MOV A,@R0 ;当R0=#DISBUF时,通过间接寻址将DISBUF中的内容放入A中
005B 93 48 MOVC A,@A+DPTR ;通过查表,A为地址偏移量,找出A中的数所对应的码值(即段码)
,还放在A中
005C F580 49 MOV P0,A ;将A中的数送至P0端口,单此时并未送至数码管
005E 118B 50 CALL SEGLOCK ;锁存数码管的段码
0060 853880 51 MOV P0,POSIT ;送位选至P0,以便指示哪一个数码管亮
0063 1191 52 CALL BITLOCK ;锁存数码管的位选信号
0065 1185 53 CALL DELAY ;使相应数码管亮一段时间
0067 758000 54 MOV P0,#00H ;送位选为00至P0口,即关闭所有的数码管,一产生消隐作用,避免
数码管上产生重影现象
006A 1191 55 CALL BITLOCK ;锁存消隐信号
006C E538 56 MOV A,POSIT ;当一个数码管完成显示后,对位选进行移位操作,以便为下一个数
A51 MACRO ASSEMBLER KEY_SCAN 11/22/2007 09:15:49 PAGE 2
码管
006E 03 57 RR A ;的显示作好准备,此时,位选指向下一个数码管
006F F538 58 MOV POSIT,A
0071 08 59 INC R0 ;使R0的数自加一,指向下一个要显示的数字,若上一次指向DISBUF
,则
0072 D9E6 60 DJNZ R1,DISLOOP ;本次指向DISBUF+1,并受R1控制,完成8个数在数码管上的显示
0074 22 61 RET ;所以,在使用此显示程序时,只需将欲显示的数字放入对应的DISB
UF即可
62
63 ;=============================
64 ;数码管移位
0075 65 POSI_CH:
0075 7830 66 MOV R0,#DISBUF
0077 7931 67 MOV R1,#DISBUF+1 ;将DISBUF中的数,从高位到低位
0079 68 UU: ;依次覆盖
0079 E7 69 MOV A,@R1 ;然后将得到的最新键植
007A F6 70 MOV @R0,A ;装入DISBUF+7
007B 08 71 INC R0
007C 09 72 INC R1
007D B838F9 73 CJNE R0,#POSIT,UU
0080 7937 74 MOV R1,#POSIT-1
0082 EF 75 MOV A,R7
0083 F7 76 MOV @R1,A
0084 22 77 RET
78
79 ;===================================
80 ;延时程序
0085 81 DELAY:
0085 7B0F 82 MOV R3,#0FH
0087 DBFE 83 LOOP1: DJNZ R3,LOOP1
0089 00 84 NOP
008A 22 85 RET
86
87 ;===================================
88 ;锁存数码管段码
008B 89 SEGLOCK:
008B D293 90 SETB P1.3
008D 00 91 NOP
008E C293 92 CLR P1.3
0090 22 93 RET
94
95 ;===================================
96 ;锁存数码管位选
0091 97 BITLOCK:
0091 D292 98 SETB P1.2
0093 00 99 NOP
0094 C292 100 CLR P1.2
0096 22 101 RET
102
103 ;===================================
104 ;按键检测
0097 105 KEY_SCAN:
0097 75A00F 106 MOV P2,#0FH ;列扫描
009A 85A039 107 MOV KEYBUF,P2
009D 75A0F0 108 MOV P2,#0F0H ;行扫描
00A0 E5A0 109 MOV A,P2
00A2 4539 110 ORL A,KEYBUF ;将最新的扫描码放在A中
00A4 22 111 RET
112
113 ;===================================
114 ;判断按键状态
00A5 115 KEY:
00A5 200002 116 JB UP_DOWN,KEY_DOWN_CHECH ;检测当前按键的状态,若为弹起状态,则检测键按下
00A8 801A 117 JMP KEY_UP_CHECH ;若为按下状态,则检测键弹起
00AA 118 KEY_DOWN_CHECH:
00AA 1197 119 CALL KEY_SCAN
A51 MACRO ASSEMBLER KEY_SCAN 11/22/2007 09:15:49 PAGE 3
00AC B4FF02 120 CJNE A,#0FFH,KEY_CHECH ;有键按下否?
00AF 801A 121 JMP KEY_END ;没有,返回主函数
00B1 122 KEY_CHECH:
00B1 1197 123 CALL KEY_SCAN
00B3 F540 124 MOV KEYTEMP,A ;存放最新的扫描码以被确认
00B5 11CC 125 CALL DELAY_KEY ;有,延时去抖
00B7 1197 126 CALL KEY_SCAN ;重新检测键状态
00B9 B5400F 127 CJNE A,KEYTEMP,KEY_END ;如和上次扫描的一样,说明确实有键按下
00BC 11D5 128 CALL KEY_SERCH
00BE 1175 129 CALL POSI_CH
00C0 C200 130 CLR UP_DOWN ;只对键号码表进行16次比对,找不到
00C2 8007 131 JMP KEY_END ;也要终止比较
00C4 132 KEY_UP_CHECH: ;按键弹起检测
00C4 1197 133 CALL KEY_SCAN
00C6 B4FF02 134 CJNE A,#0FFH,KEY_END
00C9 D200 135 SETB UP_DOWN ;给出当前按键状态
00CB 136 KEY_END:
00CB 22 137 RET
138
139 ;===================================
140 ;按键去抖延时
00CC 141 DELAY_KEY:
00CC 7B0F 142 MOV R3,#0FH
00CE 7FFF 143 L1: MOV R7,#0FFH
00D0 DFFE 144 L2: DJNZ R7,L2
00D2 DBFA 145 DJNZ R3,L1
00D4 22 146 RET
147
148 ;===================================
149 ;键号查询
00D5 150 KEY_SERCH:
00D5 B4DE02 151 CJNE A,#0DEH,KEY1 ;0键查询
00D8 804B 152 JMP KEY0_SR
00DA 153 KEY1:
00DA B4E702 154 CJNE A,#0E7H,KEY2 ;1键查询
00DD 804A 155 JMP KEY1_SR
00DF 156 KEY2:
00DF B4D702 157 CJNE A,#0D7H,KEY3 ;2键查询
00E2 8049 158 JMP KEY2_SR
00E4 159 KEY3:
00E4 B4B702 160 CJNE A,#0B7H,KEY4 ;3键查询
00E7 8048 161 JMP KEY3_SR
00E9 162 KEY4:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -