实验-矩阵按键(汇编语言与接口技术)
本次实验学习和总结了一下关键点:(1)外部中断触发的条件由于INT0连接P3.2、INT1连接P3.3,所以原理上来说,只有K3(连接P3.2)和K3(连接P3.3)才可以触发中断。并不是任意按下一个按键就可以触发中断。(由于课本里面的代码,都没有将按键与中断请求源所联系,就直接可以触发中断,所以产生的疑惑)(2)当寄存器不够用时,需要把数据存到哪里由于寄存器是有限的,所有当我们需要存储很多数据时
目录
一、 实验要求
- 利用单片机开发板的矩阵键盘实现个人学号后8位的输入和显示。
- 利用矩阵键盘S1~S10输入数字1~0。(1~9+0)
- 利用数码管LED8~LED1从左到右显示8位学号
(矩阵按键的电路图如下)

有上图可知:
行:P1.7(第一行)~P1.4(第四行)
列:P1.3(第一列)~P1.0(第四列)
二、 实验设计
1.整体思路
(1)START:初始化
(2)MAIN:如果有按键按下(R0值+1),则修改RAM中的值,RAM中的值存的是8个数码管段
选应该有的值。
调用数码管显示,数码管按照位选,分别点亮8个数码管。段选从RAM中取。
查询是否有按键按下,没有的话就继续点亮数码管。有的话进行抖动消除。
(3)抖动消除:调用数码管显示来代替延时程序。再次查询是否有按键按下,没有回到MAIN中
的数码管显示,有的话查询是哪一个按键按下。
(4)查询按键:查询按键的号码后,保存到A。回到MAIN中,修改RAM中的当前数码管所对应
的段选值。然后继续数码管的显示。
2.流程图

以上为主程序、R0_TIME(修改RAM中段码程序)、DESPLAY(数码管显示程序)、KS(按键查询程序)的流程图
3.主要模块设计思路及分析
(1)主程序模块
在主程序中,有START和MAIN还有MAIN_LOOP三个部分。START用来初始化按键计数器(R0)和P口还有DPTR。MAIN用来调用R0_TIME (RAM中段码修改)。MAIN_LOOP调用数码管显示和轮询按键是否按下模块。按下则进行抖动消除,再次轮询。还按下,则查询键号,没有按下就回到MAIN_LOOP。
(2)键号查询模块
当有按键按下时,需要查询键号。思路是:先初始化列好计数器(R4=0),点亮所有的行,和除了第一列的其他三列。逐行查询有无按键按下。如果没有就进行下一行检测,如果4行都没有,就换下一列(右移R2,R4+1),再次进行逐行检测。如果有按下,就将此行的首键号给A,并跳到KS进行键号计算(A+R4),计算后,检测按键是否松开,松开就将A出栈,并放回MAIN中调用R0_TIME(RAM中段码修改)。如果4列全部扫描完成,则回到MAIN_LOOP调用数码管显示和轮询按键是否按下模块。
(3)按键轮询模块
将行全部设为高电平,列全部设为低电平(P1=F0H),然后读取P1的状态(其实是读取行线状态),如果有按键按下,则行线中会被短路为低电平。可以通过读取P1的状态,与F0H进行异或操作,如果结果为1,则有按键按下,如果为0,则无按键按下。
(4)数码管显示模块(延时模块)
为了让数码管点亮与按键轮询同时实现,这里的延时模块可以进行数码管的显示。
在此模块中,位选通过直接赋值来依次选择数码管(8~1),段选通过从RAM(30H~37H)来选择数字,给到P0口,点亮数码管。每显示一个数码管就延时一下再通过设定比较短的延时,利用人眼的视觉暂留,来实现8个数码管“同时点亮”的效果。
(5)RAM中数据修改模块
如果R0为0,则还没有按键按下,则8个数码管需要全部显示0,所有RAM(30H~37H)中全部存9。如果R0等于1,则表示第一个按键按下,此时应该修改数码管8的段选所对应的RAM中的地址的值(30H),我们将求得的键号A存入30H中,后面的同理可得。
三、 实现效果

以上为矩阵键盘输入实现显示后8为学号的实现效果。
四、源代码
// 矩阵按键:
//行:P1.7 P1.6 P1.5 P1.4 1.7第0行
//列:P1.3 P1.2 P1.1 P1.0 1.3第0列
//数码管:
//位选:P2.2 P2.3 P2.4
//段选:P0
ORG 0000H
LJMP START
ORG 0100H
START:
MOV P1, #0FFH ;初始化
MOV P0, #0FFH
MOV P2, #0H
MOV DPTR, #TAB
MOV R0, #0 ;按下按键的次数, 用来控制数码管的点亮
MAIN: //初次检测
LCALL R0_TIME
MAIN_LOOP:
;如果r0没有修改,这无按下时,A=0,再次修改了30H中内存地址的值,所以数码管会一直显示1
LCALL DESPLAY
LCALL KS
JNZ K1 //有按键按下,A=1。跳到K1进行消除抖动
LJMP MAIN_LOOP
K1: //再次检测,消除抖动
LCALL DESPLAY
LCALL KS
JNZ K2 //有按键按下,跳到K2
LJMP MAIN_LOOP //有按键按下,检查是哪一个按键按下
K2:
INC R0 ;按下次数加一
MOV R2, #0F7H //列P1.3为0送入R2暂存
MOV R4, #00H //列计数器
K3:
MOV P1, R2
L0:
JB P1.7, L1 //P1.7(第0行)为1,无按键按下,跳到第一行检测
MOV A, #00H //第0行的首键号给ACC
LJMP LK //第0行按下,跳到键号计算程序
L1:
JB P1.6, L2
MOV A, #04H
LJMP LK
L2:
JB P1.5, L3
MOV A, #08H
LJMP LK
L3:
JB P1.4, NEXT //当前列的行都无按键按下,跳到下一列检测行
MOV A, #0CH
LK: //键号计算程序
ADD A, R4
PUSH ACC
LJMP K4
NEXT:
INC R4
MOV A, R2
JNB ACC.0, MAIN_LOOP //是否扫描完,扫描完,回到MAIN //如果ACC的第7位是0,则跳转到标签MAIN指示的代码位置”。
RR A //循环右移,换下一列扫描
MOV R2, A //将ACC值送入R2暂存
LJMP K3 //跳到K3继续
K4: //查看按键是否松开,松开则保存返回主程序
LCALL KS
JNZ K4
POP ACC
LJMP MAIN
KS:
MOV P1, #0F0H //列为0,行为1,如有按下,则行不全为1
MOV A, P1 //读行线状态,即高4位
XRL A, #0F0H //两次状态进行异或操作,无按键按下,则A=0
RET
DESPLAY: ;显示的同时,也是在延时
LED8:
MOV P2, #28
MOV A, 30H
MOVC A, @A+DPTR
MOV P0, A
LCALL D10ms
LED7:
MOV P2, #24
MOV A, 31H
MOVC A, @A+DPTR
MOV P0, A
LCALL D10ms
LED6:
MOV P2, #20
MOV A, 32H
MOVC A, @A+DPTR
MOV P0, A
LCALL D10ms
LED5:
MOV P2, #16
MOV A, 33H
MOVC A, @A+DPTR
MOV P0, A
LCALL D10ms
LED4:
MOV P2, #12
MOV A, 34H
MOVC A, @A+DPTR
MOV P0, A
LCALL D10ms
LED3:
MOV P2, #8
MOV A, 35H
MOVC A, @A+DPTR
MOV P0, A
LCALL D10ms
LED2:
MOV P2, #4
MOV A, 36H
MOVC A, @A+DPTR
MOV P0, A
LCALL D10ms
LED1:
MOV P2, #0
MOV A, 37H
MOVC A, @A+DPTR
MOV P0, A
LCALL D10ms
RET
R0_TIME:
CJNE R0, #0, M1
M0:
MOV 30H, #9
MOV 31H, #9
MOV 32H, #9
MOV 33H, #9
MOV 34H, #9
MOV 35H, #9
MOV 36H, #9
MOV 37H, #9
AJMP FINISH
M1: CJNE R0, #1, M2
MOV 30H, A
AJMP FINISH
M2: CJNE R0, #2, M3
MOV 31H, A
AJMP FINISH
M3: CJNE R0, #3, M4
MOV 32H, A
AJMP FINISH
M4: CJNE R0, #4, M5
MOV 33H, A
AJMP FINISH
M5: CJNE R0, #5, M6
MOV 34H, A
AJMP FINISH
M6: CJNE R0, #6, M7
MOV 35H, A
AJMP FINISH
M7: CJNE R0, #7, M8
MOV 36H, A
AJMP FINISH
M8:
MOV 37H, A
FINISH:
RET
D10ms:
MOV R7, #40 ; 延时10ms子程序,采用双循环
D1: MOV R6, #25
DJNZ R6, $
DJNZ R7, D1
RET
TAB:
DB 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H, 7FH, 6FH, 3FH ; 共阴极 (1~0)
END
五、总结与思考
本次实验学习和总结了一下关键点:
(1)外部中断触发的条件
由于INT0连接P3.2、INT1连接P3.3,所以原理上来说,只有K3(连接P3.2)和K3(连接P3.3)才可以触发中断。并不是任意按下一个按键就可以触发中断。(由于课本里面的代码,都没有将按键与中断请求源所联系,就直接可以触发中断,所以产生的疑惑)
(2)当寄存器不够用时,需要把数据存到哪里
由于寄存器是有限的,所有当我们需要存储很多数据时,只需要存到RAM中的内存即可。例如此实验中的8个数码管的段码。
(3)需要注意分支判断结果的跳回位置。
例如在此实验中,由于判断没有按键按下后,一直跳回MAIN,调用修改RAM中的值。因为A此时表示按键没有按下,所有为0,就修改了RAM中正确的段码。所有无按键按下时,需要跳回数码管显示,而不需要调用修改RAM中值的程序。
更多推荐



所有评论(0)