📄 computerclock.txt
字号:
ORG 0000h
AJMP MAIN ;跳向主程序
ORG 000BH ;T0中断入口
AJMP IT0P ;转到T0定时子程序
ORG 0050h
MAIN:MOV SP,#40H ;设堆栈指针
MOV 79h,#00H
MOV 7AH,#00H
MOV 7BH,#00H
MOV 7CH,#00H
MOV 7DH,#00H
MOV 7EH,#00H ;显示初始化,清零
L4: MOV R1,#7EH
L1: ACALL DIR ;调用显示程序
LOOP1:ACALL KS1 ;调用有无键闭合
JZ L1 ;无键按下就跳转L1
ACALL KEYI ;转到键盘扫描子程序
CJNE A,#0dh,L2 ;累加器与8位立即数比较不等则转移
AJMP DO1
L2: MOV @R1,A
DEC R1
CJNE R1,#78H,LOOP1 ;累加器与8位立即数比较不等则转移
AJMP L4
DO1: MOV TMOD,#01H ;T0工作在方式1,100ms定时程序
MOV TH0,#3CH
MOV TL0,#0B0H ;给T0装入初值
ACALL HB1
SETB ET0 ;允许T0开中断
SETB TR0 ;启动TR0
SETB EA ;CPU开中断
HERE:ACALL DIR
ACALL CF1
SJMP HERE ;等待中断
ORG 0300H
IT0P:PUSH PSW ;保护现场
PUSH ACC
PUSH DPH
PUSH DPL
MOV TH0,#3CH ;给T0装入初值
MOV TL0,#0B0H
DJNZ 63H,RETURN ;1S未到,返回
MOV 63H,#0AH ;重置中断次数
MOV A,#01H ;秒单元增1
ADD A,62H
DA A ;秒单元十进制调整
MOV 62H,A ;分的BCD码存回分单元
CJNE A,#60H,RETURN ;是否 到60秒,未到返回
MOV 62H,#00H ;计满60秒,秒单位清0
MOV A,#01H ; 分单元加1
ADD A,61H
DA A ;分单元十进制调整
MOV 61H,A ;分的BCD码存回分单元
CJNE A,#60H,RETURN ;是否到60分,未到返回
MOV 61H,#00H
MOV A,#01H
ADD A,60H
DA A
MOV 60H,A
CJNE A,#24H,RETURN;是否到24小时,未到返回
MOV 60H,#00H
RETURN:POP DPH
POP DPL
POP ACC
POP PSW
RETI ;中断返回
CF1: MOV R5,62H
MOV A,R5
ANL A,#0F0H
SWAP A
MOV 7AH,A
MOV A,R5
ANL A,#0FH
MOV 79H,A
MOV R5,61H
MOV A,R5
ANL A,#0F0H
SWAP A
MOV 7CH,A
MOV A,R5
ANL A,#0FH
MOV 7BH,A
MOV R5,60H
MOV A,R5
ANL A,#0F0H
SWAP A
MOV 7EH,A
MOV A,R5
ANL A,#0FH
MOV 7DH,A
RET
HB1: MOV 63H,#0AH
MOV A,7AH
SWAP A
ADD A,79H
MOV 62H,A
MOV A,7CH
SWAP A
ADD A,7BH
MOV 61H,A
MOV A,7EH
SWAP A
ADD A,7DH
MOV 60H,A
RET
ORG 0400H
KEYI:MOV R2,#0FEH ;扫描行列,确定键值
MOV R4,#00H ;列号计数器清零
LK4:MOV DPTR,#0FFDDH ;8155A口地址
MOV A,R2
MOVX @DPTR,A ;送0FEH至A口
INC DPTR
MOVX A,@DPTR ;从C口读入
JB ACC.0,LONE ;0行为1,0行无键按下,跳转LONE
MOV A,#00H ;第0行有键闭合,首键号0到A
AJMP LKP ;跳LKP,计算键号
LONE:JB ACC.1,LTW0 ;1行为1,1行无键按下,跳转LTWO
MOV A,#08H ;第1行有键闭合,首键号8到A
AJMP LKP ;跳LKP,计算键号
LTW0:JB ACC.2,LTHR ;2行为1,2行无键按下,跳转LTHR
MOV A,#10H ;第2行有键闭合,首键号10H到A
AJMP LKP ;跳LKP,计算键号
LTHR:JB ACC.3,NEXT ;3行为1,3行无键按下,跳转NEXT
MOV A,#18H ;第3行有键闭合,首键号18h到A
LKP:ADD A,R4 ; 计算键号,即:行首键号+列号=键号
PUSH ACC ;键号进栈保护
LK3:ACALL DIR ;调用显示子程序,延时6ms
ACALL KS1 ;调用判有无键闭合子程序,延时6ms
JNZ LK3 ;判键释放否,未释放,则循环
POP ACC ;键已释放,键号出栈到A
MOV DPTR,#TABEL1
MOVC A,@A+DPTR
RET
NEXT:INC R4 ;显示数据指针送入下一个数据单元
MOV A,R2 ;位选送入A ,判是否已扫描到最后一列(最右一列)
JNB ACC.7,KND ;判断整个键盘是否扫描结束,键扫描已扫描到最后一列 ,跳KND,重新进行整个键盘扫描
RL A ;左移,继续扫描下一列,键扫描未到最后一列,位选码左移一位
MOV R2,A ;位选码到R2
AJMP LK4
KND:RET
KS1:MOV DPTR,#0FFDDH ;判有无键闭合子程序
MOV A,#00H ;即列线全为低电平
MOVX @DPTR,A
INC DPTR ;DPTR=#0FFDE,键入口
MOVX A,@DPTR ;从74LS245端口读行线的状态
ANL A,#0F0H ;屏蔽无用的高4位
RET
TABEL1:DB 7,4,8,5,9,6,0AH,0BH,1,0,2,0FH,3,0EH,0CH,0DH
ORG 0500H ;显示程序入口地址,把显示缓冲区0x79 - 0x7E单元的数据取出来送LED1 - LED6显示
DIR: MOV R0,#79H ;置缓冲器指针初值
MOV R3,#01H ;位选码的初值送R3
MOV A,R3
LD0: MOV DPTR,#0FFDDH ;定义字位口/键扫口 ,位选码,8155H PA口最左边LED亮
MOVX @DPTR,A
MOV A,@R0 ;显示数据送A
MOV DPTR,#TAB
MOVC A,@A+DPTR ;根据显示数据来查表取段码,找出要显示的字符的LED字码
MOV DPTR,#0FFDCH ;定义字形口
DIR1:MOVX @DPTR,A ;段数据,8155B口
ACALL DL1ms ;延时1ms,即该位显示1ms
INC R0 ;显示数据缓冲区指针指向下一个数据单元
MOV A,R3 ;位选码送入A中
JB ACC.5,LD1 ;判断是否扫描到最右边的LED,如到最右边,则返回ACALL DIR下一条指令执行
RL A ;位选码循环向左移一位,准备让右边的下一位LED亮
MOV R3,A ;位选码送R3中保存
AJMP LD0
LD1: RET
TAB:DB 0C0h,0F9H,0A4H,0B0H,99H,92H ;共阳极LED段码表,表示要显示的字符为:0 - F
DB 82H,0F8H,80H,90H,88H,83H ;0X83='b'
DB 0C6H,0A1H,86H,8EH,8CH,0C1H ;0X8E='F',0x8C='P',0XC1='U'
DB 0CEH,91H,89H,0C7H,0FFH ;0XCE='厂',0x91='?',0X89='H',0XC7='L',0XFF='0'
DL1ms:MOV R7,#02H ;延时1ms子程序,相当于运行约255x2x2个时钟周期延时1ms
DL:MOV R6,#0FFH
DL6:DJNZ R6,DL6 ;R6=R6-1,R6=0时往下运行
DJNZ R7,DL ;R7=R7-1
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -