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

📄 wannianli.txt

📁 51写的19位数码管显示的万年历程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;           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 + -