📄 wannianli.txt
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; AT89C2051日历程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
time_week data 52h ;星期存放单元
time_year data 5dh ;年份低两位存放单元(bcd码)
time_month data 5eh ;月份存放单元(bcd码)
time_data data 5fh ;日存放单元(bcd码)
yearh data 36h ;年份高两位
year data 35h ;年份低两位存放单元(bcd码)
month data 34h ;月份存放单元(bcd码)
day data 33h ;日存放单元(bcd码)
hour data 32h ;时存放单元(bcd码)
minute data 31h ;分存放单元(bcd码)
sec data 30h ;秒存放单元(bcd码)
aaa bit p3.0 ;显示位(74ls164 数据)
bbb bit p3.1 ;显示脉冲(74ls164时钟)
aa bit p3.3 ;时间调整按钮
bb bit p3.4 ;加1调整
cc bit p3.5 ;闹钟调整
bl bit p3.2 ;闹钟输出
bz1 bit 21h.0
times data 20h ;调时标志
com data p1 ;段码数据
; 定时器T0溢出周期为40MS,T0为秒计数用
;P1口 为字符输出口,采用共阳显示管。
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 中断入口程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ORG 0000H ;程序执行开始地址
LJMP START ;跳到标号START执行
ORG 0003H ;外中断0中断程序入口
RETI ;外中断0中断返回
ORG 000BH ;定时器T0中断程序
LJMP INTT0 ;跳至INTTO执行
ORG 0013H ;外中断1中断程序入口
RETI ;外中断1中断返回
ORG 001BH ;定时器T1中断程序入口
RETI
ORG 0023H ;串行中断程序入口地址
RETI ;串行中断程序返回
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
START: ;主 程 序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov r0,#30h ;清30H-38H共11个内存单元
mov r7,#9 ;9个字节
cleete:
mov @r0,#00h
inc r0
djnz r7,cleete
mov times,#00h ;清调时标志
mov tmod,#01h ;设T0为16位定时器
mov tl0,#0c8h ;40ms定时初值(T0计时用)
mov th0,#63h ;40ms定时初值
mov sec,#0
mov minute,#0h
mov hour,#0h
mov day,#01h
mov month,#01h
mov year,#01h
mov yearh,#20h
setb ea ;总中断开放
setb et0 ;允许T0中断
setb tr0 ;开启T0定时器
mov r4,#19 ;1秒定时用(40ms×25)
start1:
mov 2bh,#5
lcall disp ;调用显示子程序
jnb aa,setmm1 ;P3.3口为0时转时间调整程序
ljmp start1 ;P3.3口为1时跳回START1
SETMM1:
lcall setmm ;调时间调整程序SETMM
ljmp start1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SETMM: ;时间调整程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
lcall disp ;调用显示程序
lcall disp ;调用显示程序
jb aa,setmmo ;检测p3.3是否为1,是干扰跳过
setmm2:
jnb aa,setmm3 ;检测p3.3是否为0,是则跳转
clr et0
clr tr0 ;关t0中断
mov sec,#0 ;秒清零
mov times,#01h ;分开始调整
mov r0,#minute ;
setmm4:
nop
inc22:
lcall offl ;灭显示
lcall inc11 ;加调整
lcall disp
jb aa,inc22
lcall disp
jb aa,inc22
inc r0
mov a,times
rl a
mov times,a
djnz 2bh,setmm4 ;继续调整下一数据
setmm12:
jnb aa,setmm11
setmmo:
setb tr0
setb et0 ;调整完成开始计时
ret
setmm11:
lcall disp
ljmp setmm12
setmm3:
lcall disp
ljmp setmm2 ;避免调整时无显示
inc11:
mov r3,#40
inc111:
mov a,@r0
jb bb,inc17
add a,#1 ;加1
da a
lcall inc000 ;数据比较
inc13:
jnb bb,inc14
inc17:
mov @r0,a ;存入调整后的数据
lcall disp
djnz r3,inc111
ret
inc14:
lcall disp
ljmp inc13
offl: ;灭显示
mov 22h,@r0
mov r6,#4
off1:
mov r7,#4
off2:
mov @r0,#0aah ;放入熄灭码
lcall disp
djnz r7,off2
djnz r6,off1
mov @r0,22h
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
inc000: ;比较子程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
jb 20h.0,inc001 ;分比较
jb 20h.1,inc002 ;时比较
jb 20h.2,inc003 ;日比较
jb 20h.3,inc004 ;月比较
jb 20h.4,inc005 ;年比较
ljmp incout
inc005:
cjne a,#99h,incout
mov a,#00h ;超过99年为00年
ljmp incout
inc004:
cjne a,#13h,incout
mov a,#01h ;超过12月为1月
ljmp incout
inc003:
cjne a,#32h,incout
mov a,#01h ;超过31天为1日
ljmp incout
inc002:
cjne a,#24h,incout
mov a,#00h ;超过23时为0时
ljmp incout
inc001:
cjne a,#60h,incout
mov a,#00h
;超过59分为0分
incout:
ret ;返回
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
INTT0: ;1秒计时程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push acc ;累加器入栈保护
push psw ;状态字入栈保护
mov tl0,#0c8h ;低8位初值修正
mov th0,#63h ;高8位初值修正
djnz r4,clke111 ;25次中断未到
ljmp loop11
clke111:
ljmp clke
loop11:
mov r4,#19h ;25次中断到(1秒)重赋初值
mov a,sec ;调整秒
add a,#1
da a
mov sec,a
cjne a,#60h,clke99 ;整分否
mov sec,#0 ;清秒
mov a,minute ;调整分
add a,#1
da a
mov minute,a
clk0:
cjne a,#60h,clke ;整点否
mov minute,#0 ;清分
mov a,hour ;调整时
add a,#1
da a
mov hour,a
cjne a,#24h,clke ;零点否
mov hour,#0 ;清时
mov a,day ;调整日期
add a,#1
da a
mov day,a
mov a,month ;查阅本月最大日期
inc a
movc a,@a+pc
sjmp clk1
db 31h,28h,31h ;对应月份编码:01h,02h,03h
db 30h,31h,30h ;对应月份编码:04h,05h,06h
db 31h,31h,30h ;对应月份编码:07h,08h,09h
db 00h,00h,00h ;对应无效月份编码:0ah,0bh,0ch
db 00h,00h,00h ;对应无效月份编码:0dh,0eh,0fh
db 31h,30h,31h ;对应月份编码:10h,11h,12h
clk1:
clr c
subb a,day
jnc clke ;本月未满
mov a,month
cjne a,#2,clk3 ;是二月
mov a,year
anl a,#13h ;保留年份中非4的整数部分
jnb acc.4,clk2
add a,#2
clk2:
anl a,#3 ;能否被4整除
jnz clk3 ;非闰年
mov a,day
xrl a,#29h
jz clke ;闰年二月可以有29日
clk3:
mov day,#1 ;调整到下个月的1日
mov a,month
add a,#1
da a
mov month,a
cjne a,#13h,clke
mov month,#1 ;调整到下一年的一月份
mov a,year ;调整年份
add a,#1
da a
mov year,a
clke99:
lcall CONvert ;农历转换子程序
clke: ;时钟调整完毕,处理其它定时任务
pop psw
pop acc
reti ;完成
;;;;;;;;;;;;;;;;;;;;
disp: ;显示寄存器处理
;;;;;;;;;;;;;;;;;;;;
push psw
push acc
mov 23h,r0 ;保存r0
disp99:
mov r1,#40h ;显示寄存器首址
mov r0,#30h ;待处理寄存器首址
mov r2,#9 ;处理n次
disp1:
mov a,@r0 ;低寄存器1内容存入a
anl a,#0fh
mov @r1,a ;将a的值存入显示寄存器1
mov a,@r0 ;低寄存器1内容存入a
swap a
anl a,#0fh
inc r1 ;r1地址加1
mov @r1,a ;将A的值存入显示寄存器2
djnz r2,disp2 ;处理完n次,没有地址加1
lcall display
mov r0,23h
pop acc
pop psw
ret
disp2:
inc r1
inc r0
ljmp disp1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
display: ;显示程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 显示数据在40H-51H单元内,用19位LED共阳数码管显示,P1口输出段码数据,
;每个LED数码管亮1MS;时间再逐位循环。
mov r1,#40h ;指向显示数据首址
mov r5,#19 ;显示19个数据
setb aaa
play:
setb bbb
nop
clr bbb ;移一位
clr aaa ;清零
mov a,@r1 ;取显示数据到A
mov dptr,#tab ;取段码表地址
movc a,@a+dptr ;查显示数据对应段码
mov com,a ;段码放入P1口
lcall dl1ms ;显示1ms
mov com,#0ffh ;P1口复位
djnz r5,play1 ;
clr bbb
setb aaa
ret ;返回
play1:
inc r1 ;显示下一位
ljmp play
TAB:
DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,0a3h,8eh,0abh
;共阳段码表 "0""1""2" "3""4""5""6""7" "8""9""不亮""o""f""n";后面三个在调闹钟时用
dl1ms:
mov 25h,r7
mov 24h,r6 ;保存r6,r7
mov r7,#20
ds1:
mov r6,#10
djnz r6,$
djnz r7,ds1
mov r7,25h
mov r6,24h
ret
start_year equ 01
CONvert_yeAr DATA 5ch
CONvert_mONth DATA 38h ;BIT7 为1 表示闰月
CONvert_dAte DATA 37h
temp_Byte1 DATA 57h
temp_Byte2 DATA 58h
temp_Byte3 DATA 59h
temp_Byte4 DATA 5Ah
temp_Byte5 DATA 5Bh
;以下为公历转农历子程序
CONvert:
mov a,year
mov time_year,a
mov a,month
mov time_month,a
mov a,day
mov time_data,a
MOV A,time_year ;将年月日转化为HEX 格式
MOV B,#16
DIV AB
MOV CONvert_yeAr,B
MOV B,#10
MUL AB
ADD A,CONvert_yeAr
MOV CONvert_yeAr,A
MOV A,time_month
JNB ACC.4,CON_02
CLR ACC.4 ;ACC.4 为1 表示大于10 月
ADD A,#10
CON_02: MOV CONvert_mONth,A
MOV A,time_data
MOV B,#16
DIV AB
MOV CONvert_dAte,B
MOV B,#10
MUL AB
ADD A,CONvert_dAte
MOV CONvert_dAte,A
MOV dptr,#mONth_dAtA ;以下定位本年数据在表格中的位置
MOV A,CONvert_yeAr
CON_06: CLR C
SUBB A,#stArt_yeAr
MOV B,#3 ;表格每年3 字节
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -