;单片机电子钟汇编程序
;-----------------------------------
HOU_S BIT P2.7;时十位
HOU_G BIT P2.6;时个位
MIN_S BIT P2.5;分十位
MIN_G BIT P2.4;分个位
SEC_S BIT P2.3;秒十位
SEC_G BIT P2.2;秒个位
H_KEY BIT P3.4;时调整键
M_KEY BIT P3.5;分调整键
LEDBUS EQU P0;显示数据总线
SECOND EQU 30H;秒寄存器
MINUTE EQU 31H;分寄存器
HOUR EQU 32H;时寄存器
TIM_1 EQU 33H;定时器0中断次数
TIM_2 EQU 34H;定时器1中断次数
;-----------------------------------
ORG 0000H
LJMP INIT
ORG 000BH
LJMP TIMER0
ORG 30H
;-----------------------------------
;单片机初始化
INIT:
MOV SECOND,#0;秒置0
MOV MINUTE,#0;分置0
MOV HOUR,#0;开机后显示0
MOV TIM_1,#10;中断10次为0.5秒
MOV TIM_2,#2;0.5*2=1秒
MOV SP,#5FH;堆栈指针指向5FH
MOV TMOD,#01H;定时器0为模式1
MOV TH0,#03CH
MOV TL0,#0B0H;50MS初值(晶振12M)
SETB ET0
SETB TR0
SETB EA
;------------------------------------
;主程序
MAIN:
JNB H_KEY,HT;时调整键按下转到HT
JNB M_KEY,MT;分调整键按下转到MT
ACALL DISP;调用子程序
AJMP MAIN;转到LOOP继续检测控制键的状态
;--------------------------------------
;时间调整
;---------------分调整------------------
MT:
ACALL DISP;调用显示子程序
JNB M_KEY,MT;判断按键是否松开
INC MINUTE;分加一
MOV A,MINUTE
CJNE A,#60,MAIN;判断是否加到60
MOV MINUTE,#0;分到60变为0
MOV SECOND,#0;秒置0
AJMP MAIN
;----------------时调整------------------
HT:
ACALL DISP;调用显示子程序
JNB H_KEY,HT;判断按键是否松开
INC HOUR;时加1
MOV A,HOUR
CJNE A,#24,MAIN
MOV HOUR,#0;判断时是否到24,到24后清0
AJMP MAIN
;-----------------------------------------
;显示子程序
DISP:
MOV DPTR,#LEDTAB;数码管显示首地址送DPTR
MOV A,SECOND ;秒放入ACC
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV LEDBUS,A
CLR SEC_S
ACALL D1MS
SETB SEC_S
MOV A,B
MOVC A,@A+DPTR
MOV LEDBUS,A
CPL SEC_G
ACALL D1MS
SETB SEC_G
MOV A,MINUTE;分放入ACC
MOV B,#10;B放入10
DIV AB;A/B,商在A里,余数在B里
MOVC A,@A+DPTR;查表取分十位段码
MOV LEDBUS,A;段码送LEDBUS显示
CLR MIN_S;打开分十位显示
ACALL D1MS;延迟1MS
SETB MIN_S;关闭分十位显示
MOV DPTR,#LEDTAB2
MOV A,B
MOVC A,@A+DPTR;查表取分个位段码
MOV LEDBUS,A
CLR MIN_G;打开分个位显示
ACALL D1MS;延迟1MS
SETB MIN_G;关闭分十位显示
MOV A,HOUR
MOV B,#10
DIV AB;拆分小时的十位和个位
JZ DISP0;十位为0,不显示十位
MOV DPTR,#LEDTAB
MOVC A,@A+DPTR
MOV LEDBUS,A
CLR HOU_S;打开时十位显示
ACALL D1MS
SETB HOU_S
DISP0:
MOV DPTR,#LEDTAB2
MOV A,B
MOVC A,@A+DPTR
MOV LEDBUS,A
CLR HOU_G;打开时个位显示
ACALL D1MS
SETB HOU_G;关闭时个位显示
RET
;--------------------------------------
;定时器0中断服务程序
TIMER0:
PUSH ACC;入栈保护ACC和PSW
PUSH PSW
MOV A,#0B0H;定时器0中断服务子程序
ADD A,TL0;同步修正
MOV TL0,A
MOV TH0,#03CH;重装定时器0初值
DJNZ TIM_1,RETI_1
MOV TIM_1,#10;中断10次为0.5秒
DJNZ TIM_2,RETI_1
MOV TIM_2,#2;1秒时间到
INC SECOND;秒加一
MOV A,SECOND
CJNE A,#60,RETI_1
MOV SECOND,#0;秒到60变0
INC MINUTE;分加1
MOV A,MINUTE
CJNE A,#60,RETI_1
MOV MINUTE,#0;分到60变0
INC HOUR;时加1
MOV A,HOUR
CJNE A,#24,RETI_1
MOV HOUR,#0;时到24变0
RETI_1:
POP PSW
POP ACC
RETI
;----------------------------------------
;延迟子程序
D1MS:
MOV R7,#2;延迟1MS子程序
D_1:
MOV R6,#250;延迟时间估算250*2*2=1000微秒
DJNZ R6,$
DJNZ R7,D_1
RET
;----------------------------------------
;数码管段码表
LEDTAB: ;不带点的数码管字码表
DB 0C0H,0F9H,0A4H,0B0H,99H;0,1,2,3,4
DB 92H,82H,0F8H,80H,90H;5,6,7,8,9
LEDTAB2: ;带点的数码管字码表
DB 40H,79H,24H,30H,19H;0,1,2,3,4
DB 12H,02H,78H,00H,10H;5,6,7,8,9
END