⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 164_wnl.asm

📁 包含proteus仿真原理图
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;2051带农历显示的万年历最简电路
;带74L164三片
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;           AT89C2051日历程序         ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;转载请署名来自 www.01mcu.com 否则谢绝转载
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            ;www.01mcu.com
inc      r0
djnz    r7,cleete
mov    times,#00h       ;清调时标志
mov    tmod,#01h       ;设T0为16位定时器
mov    tl0,#0c0h         ;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:
call      disp              ;调用显示子程序
jnb      aa,setmm1    ;P3.3口为0时转时间调整程序
jmp     start1           ;P3.3口为1时跳回START1
SETMM1:    
call       setmm         ;调时间调整程序SETMM
jmp start1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SETMM:                    ;时间调整程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
call disp
call disp
jb aa,setmmo              ;是干扰跳过
setmm2:
jnb aa,setmm3
clr et0
clr tr0                         ;关t0中断
mov sec,#0                 ;秒清零
mov times,#01h           ;分开始调整
mov r0,#minute           ;
setmm4:
nop
inc22:
call offl                            ;灭显示
call inc11                        ;加调整
call disp
jb aa,inc22
call disp
jb aa,inc22
inc r0
mov a,times
rl a
mov times,a
jnb times.5,setmm4        ;继续调整下一数据
setmm12:
jnb aa,setmm11
setmmo:
setb tr0
setb et0                         ;调整完成开始计时
ret
setmm11:
call disp
jmp setmm12
setmm3:
call disp     
jmp setmm2                ;避免调整时无显示
inc11:
mov r3,#40
inc111:
mov a,@r0
jb bb,inc17
add a,#1                     ;加1
da a
call  inc000                 ;数据比较  
inc13:
jnb bb,inc14
inc17:
mov @r0,a                 ;存入调整后的数据
call disp
djnz r3,inc111
ret
inc14:
call disp
jmp inc13
offl:                             ;灭显示
mov 22h,@r0
mov r6,#10
off1:
mov r7,#10
off2:
mov @r0,#0aah         ;放入熄灭码
call disp
djnz r7,off2
djnz r6,off1
mov @r0,22h
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
inc000:                      ;比较子程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
jb times.0,inc001       ;分比较
jb times.1,inc002       ;时比较
jb times.2,inc003       ;日比较
jb times.3,inc004       ;月比较
jb times.4,inc005       ;年比较
jmp incout                 ;完成www.01mcu.com
inc005:
cjne a,#99h,incout
mov a,#00h               ;超过99年为00年
jmp incout
inc004:
cjne a,#13h,incout
mov a,#01h               ;超过12月为1月
jmp incout
inc003:
cjne a,#32h,incout
mov a,#01h               ;超过31天为1日
jmp incout
inc002:
cjne a,#24h,incout
mov a,#00h               ;超过23时为0时
jmp incout
inc001:
cjne a,#60h,incout
mov a,#00h               ;超过59分为0分
incout:
ret                      ;返回
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
INTT0:           ;1秒计时程序              ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push    acc               ;累加器入栈保护
push     psw             ;状态字入栈保护
orl      tl0,#0c0h       ;低8位初值修正
mov   th0,#63h        ;高8位初值修正
djnz   r4,clke111     ;25次中断未到
jmp   loop11
clke111:
jmp   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:
call  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
call  display
mov   r0,23h         ;www.01mcu.com
pop   acc
pop   psw
ret
disp2:
inc   r1
inc   r0
jmp   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口
call    dl1ms         ;显示1ms
mov   com,#0ffh  ;P1口复位
djnz   r5,play1  ;www.01mcu.com
clr    bbb
setb   aaa 
ret                      ;返回
play1:
inc    r1              ;显示下一位
jmp    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 格式
;www.01mcu.com
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 字节
MUL AB

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -