一、实验目的
*
继续深入学习和掌握
MCS-51
的体系结构、指令系统和汇编语言开发
*
掌握
MCS-51
的中断系统和定时器
*
掌握多位
7
段数码管的显示方式
*
初步理解键盘矩阵的输入方式
二、实验设备
*
Proteus
仿真软件
三、实验原理
*
MCS-51
的体系结构、指令系统和汇编语言
*
多位
7
段数码管的显示原理
*
键盘矩阵的工作原理
*
MCS-51
中断系统的原理和编程
*
MCS-51
定时器工作原理和编程
四、实验内容
编写程序,检测键盘按键,将其对应的数字或符号逐次在数码管上显示,按ON/C
键显示清空,其他运算键自拟显示符号。
五、实验步骤
(一)绘制仿真电路
1、
在
Proteus
中新建工程,选项如下:
①建立
DEFAULT
原理图
②不创建
PCB Layout
③选择“
Create Firmware Project
”,
Family
选择8051
,
Controller
选择“
AT89C51
”,Compiler选择“
ASEM-51
”
这样建立的工程里面包括一个
CPU
,以及Source Code的基本框架
2、在原理图中添加一个集成化的4位7段数码
管组件( 7SEG-MPX4*
),一个集成化的计算器键盘矩阵( KEYPAD-SMALLCALC
)
3、CPU上选择适当的接口,与上述两个部件相
连接
参考电路
(二)编写程序
参考代码
;采用行扫描法键盘输入,将输入的数字存入显示缓冲区,
;如果遇到按键“C”,则清空显示缓冲区。
;显示缓存区的内容可通过定时器0中断程序显示在4位七段数码管上。
$NOMOD51
$INCLUDE (8051.MCU)
ORG 0000H
AJMP START;跳过中断入口地址
ORG 000BH
LJMP CTC0;长跳转指令:定时器中断程序
ORG 0100H
START:
MOV 60H,#10H;对应TABLE表的00H,在数码管上不显示
MOV 61H,#10H;
MOV 62H,#10H;
MOV 63H,#10H;
MOV R0,#60H;R0存显示缓冲区单元地址
MOV R7,#0EEH;用作四位数码管的位选信号
MOV TMOD, #01H
MOV TL0, #0F0H
MOV TH0, #0D8H ;电路图中设置晶振为12MHZ,则定时器的计数频率为 1MHz。
;定时10ms, T0初始值计算得55536即D8F0H (65536-55536)/(1M)=0.01
SETB TR0 ;先不启动定时器T0,等到按下“=”时再启动T0
SETB ET0 ;允许T0中断
SETB EA ;CPU开放中断
;====================================================================
;主程序:死循环
;====================================================================
MAIN:LJMP KEYJUDGE
SCAN:LCALL KEYSCAN
LJMP MAIN
;判断是否有按键按下
KEYJUDGE:
MOV P3,#0F0H
MOV A,P3
XRL A,#0F0H
JNZ DELAY
LJMP MAIN
;DELAY的作用是避免一次按键的多次检测
;由于测试过程中0FFH*0FFH次的DELAY还会有重复检测
;所以在第一段DELAY的后面又加了一段DELAY
DELAY:MOV R4,#0FFH
LOOP1:MOV R5,#0FFH
LOOP2:DJNZ R5,LOOP2
DJNZ R4,LOOP1
MOV R4,#0FFH
LOOP10:MOV R5,#0A0H
LOOP20:DJNZ R5,LOOP20
DJNZ R4,LOOP10
MOV P3,#0F0H
MOV A,P3
XRL A,#0F0H
JZ MAIN
JMP SCAN
;====================================================================
;行扫描法键盘输入子程序 将输入的数存入缓冲区60H,61H
;用到寄存器R0、R1、R2、R3
;R6存列号(0,1,2,3)
;R1存行号*4(0,4,8,C)
;R2用作列选
;R3控制循环次数(总共四次)
;====================================================================
KEYSCAN:
MOV R6,#00H
MOV R1,#00H
MOV R2,#0FEH
MOV R3,#04H
KEY:
MOV P3,R2
KEY0:JB P3.4,KEY1
MOV R1,#00H
LJMP NUM
KEY1:
JB P3.5,KEY2
MOV R1,#04H
LJMP NUM
KEY2:
JB P3.6,KEY3
MOV R1,#08H
LJMP NUM
KEY3:
JB P3.7,NEXT
MOV R1,#0CH
LJMP NUM
NEXT:
INC R6
MOV A,R2
RL A
MOV R2,A
DJNZ R3,KEY
LJMP NUM
NUM:
MOV A,R6
ADD A,R1
MOV DPTR,#KEYBOARD
MOVC A,@A+DPTR
CJNE A,#0CH,NEXT1
;到这按下了“C”,清空缓冲区
MOV 60H,#10H
MOV 61H,#10H
MOV 62H,#10H
MOV 63H,#10H
RET
NEXT1:
;到这输入数字到缓冲区
MOV 63H,62H
MOV 62H,61H
MOV 61H,60H;把20h单元中的内容送往61h
MOV 60H,A;把新输入的数送往60H
RET
;====================================================================
;定时器0中断子程序
;每次中断控制一位数码管显示相应内容,因为中断时间很短,所以看起来四个数码管是同时亮的
;====================================================================
CTC0:
MOV TL0, #0F0H
MOV TH0, #0D8H
MOV DPTR, #TABLE
MOV P1,R7
MOV A,@R0
MOVC A,@A+DPTR
MOV P0, A
MOV A,R7
RL A;位选信号左移一位
MOV R7,A
INC R0;显示缓冲区单元号移动一位
CJNE R0,#64H,EXIT
MOV R0,#60H
EXIT:
RETI
TABLE: DB 3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H, 7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H ,00H;最后一个00h表示不显示
KEYBOARD:DB 07H,08H,09H,0DH;7,8,9,/(Devide)
DB 04H,05H,06H,0FH;4,5,6,*(用F表示)
DB 01H,02H,03H,0BH;1,2,3,-(suB)
DB 0CH,00H,0EH,0AH;C,0,=(Equal),+(Add)
END