前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计分享|基于51单片机的万年历(汇编)

设计分享|基于51单片机的万年历(汇编)

作者头像
电子工程师成长日记
发布2022-07-27 18:53:38
9451
发布2022-07-27 18:53:38
举报
文章被收录于专栏:电子工程师成长日记

具体功能:

实现年、月、日、时、分、秒、农历的显示,例如:如图显示的是2001年1月1日,农历12月7日,00点01分23秒。

设计介绍

单片机介绍

51单片是一种低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash 存储器。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得STC89C51为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。具有以下标准功能:8k字节Flash,512字节RAM,32 位I/O 口线,看门狗定时器,内置4KB EEPROM,MAX810复位电路,三个16 位 定时器/计数器,一个6向量2级中断结构,全双工串行口。另外 STC89X51 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU 停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。最高运作频率35Mhz,6T/12T可选。

设计思路

文献研究法:搜集整理相关单片机智能手环系统相关研究资料,认真阅读文献,为研究做准备;

调查研究法:通过调查、分析、具体试用等方法,发现单片机智能手环系统的现状、存在问题和解决办法;

比较分析法:比较不同单片机智能手环系统的具体原理,以及同一类传感器性能的区别,分析单片机智能手环系统的研究现状与发展前景;

软硬件设计法:通过软硬件设计实现具体硬件实物,最后测试各项功能是否满足要求。

设计内容

01

仿真图

本设计利用protues8.7软件实现仿真设计,具体如图。

Protues也是在单片机仿真设计中常用的设计软件之一,通过设计出硬件电路图,及写入驱动程序,就能在不实现硬件的情况进行电路调试。另外,protues还能实现PCB的设计,在仿真中也可以与KEIL实现联调,便于程序的调试,且支持多种平台,使用简单便捷。

02

程序

本设计由汇编语言编写,主代码具体如下:

代码语言:javascript
复制
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          ;段码数据
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,#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                 
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        
POP   ACC
POP   PSW
RET
DISP2:
INC   R1
INC   R0
JMP   DISP1  
DISPLAY:          
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  
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
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
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
ADD A,DPL
MOV DPL,A
MOV A,B
ADDC A,DPH
MOV DPH,A
MOV A,#2
MOVC A,@A+DPTR ;读本年表格最后一字节
CLR ACC.7 ;ACC.7 是闰年第13 个月大小,在此不用
MOV B,#32
DIV AB
MOV TEMP_BYTE1,A ;春节月份
MOV TEMP_BYTE2,B ;春节日
; 以下计算当前日期距元旦天数
MOV TEMP_BYTE3,#0 ;设距元旦天数高位为0
MOV A,CONVERT_MONTH
CJNE A,#10,CON_08
CON_08: JC CON_09 ;9 月以前日子数小于256 天,高字节为0(9 月份过去的整月为8 个月)
MOV TEMP_BYTE3,#1
CON_09: MOV A,CONVERT_YEAR
ANL A,#03H ;ACC 为除4 的余数
JNZ CON_10 ;转常年处理
; 年除4 余数为0 是闰年
MOV A,CONVERT_MONTH
LCALL GET_RUN_DAYS_LOW ;取得闰年过去月的天数的低字节
SJMP CON_12
CON_10: MOV A,CONVERT_MONTH
LCALL GET_DAYS_LOW ;取得常年过去月的天数的低字节
CON_12: MOV B,CONVERT_DATE
DEC B ;因为日期从1 日起,而不是0 日起
ADD A,B ;过去的整月天数加当月天数
MOV TEMP_BYTE4,A
JNC CON_14
INC TEMP_BYTE3 ;TEMP_BYTE3,TEMP_BYTE4 分别为公历年过去的天数的高低字节
; 以下求春节距元旦天数,因肯定小于256 天所以只用一字节表示
CON_14: MOV A,TEMP_BYTE1
LCALL GET_DAYS_LOW ;春节不会在3 月份,不用考虑闰年
DEC A ;因为日期从1 日起
ADD A,TEMP_BYTE2
MOV TEMP_BYTE5,A ;TEMP_BYTE5,为春节距元旦天数
MOV A,CONVERT_MONTH
CJNE A,TEMP_BYTE1,CON_20 ;转换月与春节月比较
MOV A,CONVERT_DATE
CJNE A,TEMP_BYTE2,CON_20 ;转换日与春节日比较
CON_20: JC CON_22
LJMP CON_60 ;当前日大于等于春节日期,公历年与农历年同年份
CON_22: MOV A,CONVERT_YEAR ;不到春节,农历年比公历年低一年
JNZ CON_24
MOV A,#100 ;年有效数0-99
CON_24: DEC A
MOV CONVERT_YEAR,A
MOV A,DPL
CLR C
SUBB A,#3
MOV DPL,A
JNC CON_26
DEC DPH ;表格指针指向上一年
CON_26: MOV A,TEMP_BYTE5
CLR C
SUBB A,TEMP_BYTE4
MOV TEMP_BYTE3,A ;TEMP_BYTE3 中为当前日离春节的天数
MOV CONVERT_MONTH,#12 ;农历月为12 月
CLR F0 ;1901-2099 年没有闰12 月,清闰月标志
CLR A
MOVC A,@A+DPTR
ANL A,#0F0H
SWAP A;
MOV TEMP_BYTE4,A ;TEMP_BYTE4 中为闰月
JZ CON_30 ;没有闰月转移
MOV A,#2 ;有闰月,取第13 个月天数
MOVC A,@A+DPTR
MOV C,ACC.7
MOV A,#1
MOVC A,@A+DPTR
RLC A ;ACC 中为最后6 个月的大小值
SJMP CON_34
CON_30: MOV A,#1
MOVC A,@A+DPTR ;ACC 中为最后6 个月的大小值
CON_34: MOV TEMP_BYTE5,A
CON_40: MOV A,TEMP_BYTE5
RRC A
MOV TEMP_BYTE5,A
JC CON_42
MOV B,#29 ;小月29 天
SJMP CON_44
CON_42: MOV B,#30 ;大月30 天
CON_44: MOV A,TEMP_BYTE3
CLR C
SUBB A,B
JZ CON_46 ;正好够减,就是农历日1 日
JNC CON_50
;不够减一月天数,结束农历月调整
CPL A ;求补取绝对值
INC A
CON_46: INC A ;加1 即为农历日
MOV B,#10 ;转换并保存农历日,月,年
DIV AB
SWAP A
ORL A,B
MOV CONVERT_DATE,A
MOV A,CONVERT_MONTH
MOV B,#10
DIV AB
SWAP A
ORL A,B
MOV CONVERT_MONTH,A
MOV A,CONVERT_YEAR
MOV B,#10
DIV AB
SWAP A
ORL A,B
MOV CONVERT_YEAR,A
CALL WEEK      ;星期转换子程序?
RET ;结束转换
CON_50: MOV TEMP_BYTE3,A ;TEMP_BYTE3 存减去一月后的天数
JB F0,CON_52 ;是闰月,前推一月,月份不减
DEC CONVERT_MONTH;
CON_52: MOV A,CONVERT_MONTH
CJNE A,TEMP_BYTE4,CON_54
CPL F0 ;当前月与闰月相同,更改闰月标志
CON_54: SJMP CON_40
CON_60: MOV A,TEMP_BYTE4 ;春节日小于当前日,农历年同公历年
CLR C
SUBB A,TEMP_BYTE5
MOV TEMP_BYTE4,A
JNC CON_62
DEC TEMP_BYTE3 ;TEMP_BYTE3 TEMP_BYTE4 中为公历日离春节的天数
CON_62: MOV CONVERT_MONTH,#1 ;农历月为1 月
CLR A
MOVC A,@A+DPTR
MOV TEMP_BYTE5,A
ANL A,#0F0H
SWAP A;
XCH A,TEMP_BYTE5 ;TEMP_BYTE5 中为闰月,ACC 为当年农历表第一字节
CLR F0 ;第一个月肯定不是闰月
ANL A,#0FH
MOV TEMP_BYTE1,A
MOV A,#1
MOVC A,@A+DPTR
MOV TEMP_BYTE2,A
ANL A,#0F0H
ORL A,TEMP_BYTE1
SWAP A
MOV TEMP_BYTE1,A
MOV A,#2
MOVC A,@A+DPTR
MOV C,ACC.7
MOV A,TEMP_BYTE2
ANL A,#0FH
SWAP A
MOV ACC.3,C;
MOV TEMP_BYTE2,A ;以上TEMP_BYTE1,TEMP_BYTE2 各BIT 存农历年大小
CON_70: MOV A,TEMP_BYTE2
RLC A
MOV TEMP_BYTE2,A
MOV A,TEMP_BYTE1
RLC A
MOV TEMP_BYTE1,A
JC CON_72
MOV B,#29 ;小月29 天处理
SJMP CON_74
CON_72: MOV B,#30 ;大月30 天
CON_74: MOV A,TEMP_BYTE4
CLR C
SUBB A,B
JNC CON_78 ;低字节够减跳转
MOV B,A ;低字节不够减, B 暂存减后结果,
MOV A,TEMP_BYTE3
JZ CON_76 ;高字节为0,不够减
DEC TEMP_BYTE3
MOV TEMP_BYTE4,B
SJMP CON_80
CON_76: MOV A,TEMP_BYTE4 ;不够减结束月调整
LJMP CON_46 ;转日期加1 后,处理并保存转换后农历年月日
CON_78: MOV TEMP_BYTE4,A ;TEMP_BYTE3 TEMP_BYTE4 天数为减去一月后天数
CON_80: MOV A,CONVERT_MONTH
CJNE A,TEMP_BYTE5,CON_82
CPL F0 ;当前月与闰月相同,更改闰月标志
JNB F0,CON_82 ;更改标志后是非闰月,月份加1
SJMP CON_70
CON_82: INC CONVERT_MONTH;
SJMP CON_70
GET_DAYS_LOW:
MOVC A,@A+PC ;取得常年过去月的天数的低字节
RET
DB 0,31,59,90,120,151,181,212,243,17,48,78
GET_RUN_DAYS_LOW:
MOVC A,@A+PC ;取得闰年过去月的天数的低字节
RET
DB 0,31,60,91,121,152,182,213,244,18,49,79
MONTH_DATA:
;公历年对应的农历数据,每年三字节,
;格式第一字节BIT7-4 位表示闰月月份,值为0 为无闰月,BIT3-0 对应农历第1-4 月的大小
;第二字节BIT7-0 对应农历第5-12 月大小,第三字节BIT7 表示农历第13 个月大小
;月份对应的位为1 表示本农历月大(30 天),为0 表示小(29 天).
;第三字节BIT6-5 表示春节的公历月份,BIT4-0 表示春节的公历日
DB 04DH,04AH,0B8H; 2001
DB 00DH,04AH,04CH; 2002
DB 00DH,0A5H,041H; 2003
DB 025H,0AAH,0B6H; 2004
DB 005H,06AH,049H; 2005
DB 07AH,0ADH,0BDH; 2006
DB 002H,05DH,052H; 2007
DB 009H,02DH,047H; 2008
DB 05CH,095H,0BAH; 2009
DB 00AH,095H,04EH; 2010
DB 00BH,04AH,043H; 2011
DB 04BH,055H,037H; 2012
DB 00AH,0D5H,04AH; 2013
DB 095H,05AH,0BFH; 2014
DB 004H,0BAH,053H; 2015
DB 00AH,05BH,048H; 2016
DB 065H,02BH,0BCH; 2017
DB 005H,02BH,050H; 2018
DB 00AH,093H,045H; 2019
DB 047H,04AH,0B9H; 2020
DB 006H,0AAH,04CH; 2021
DB 00AH,0D5H,041H; 2022
DB 024H,0DAH,0B6H; 2023
DB 004H,0B6H,04AH; 2024
DB 069H,057H,03DH; 2025
DB 00AH,04EH,051H; 2026
DB 00DH,026H,046H; 2027
DB 05EH,093H,03AH; 2028
DB 00DH,053H,04DH; 2029
DB 005H,0AAH,043H; 2030
DB 036H,0B5H,037H; 2031
DB 009H,06DH,04BH; 2032
DB 0B4H,0AEH,0BFH; 2033
DB 004H,0ADH,053H; 2034
DB 00AH,04DH,048H; 2035
DB 06DH,025H,0BCH; 2036
DB 00DH,025H,04FH; 2037
DB 00DH,052H,044H; 2038
DB 05DH,0AAH,038H; 2039
DB 00BH,05AH,04CH; 2040
DB 005H,06DH,041H; 2041
DB 024H,0ADH,0B6H; 2042
DB 004H,09BH,04AH; 2043
DB 07AH,04BH,0BEH; 2044
DB 00AH,04BH,051H; 2045
DB 00AH,0A5H,046H; 2046
DB 05BH,052H,0BAH; 2047
DB 006H,0D2H,04EH; 2048
DB 00AH,0DAH,042H; 2049
DB 035H,05BH,037H; 2050
DB 009H,037H,04BH; 2051
DB 084H,097H,0C1H; 2052
DB 004H,097H,053H; 2053
DB 006H,04BH,048H; 2054
DB 066H,0A5H,03CH; 2055
DB 00EH,0A5H,04FH; 2056
DB 006H,0B2H,044H; 2057
DB 04AH,0B6H,038H; 2058
DB 00AH,0AEH,04CH; 2059
DB 009H,02EH,042H; 2060
DB 03CH,097H,035H; 2061
DB 00CH,096H,049H; 2062
DB 07DH,04AH,0BDH; 2063
DB 00DH,04AH,051H; 2064
DB 00DH,0A5H,045H; 2065
DB 055H,0AAH,0BAH; 2066
DB 005H,06AH,04EH; 2067
DB 00AH,06DH,043H; 2068
DB 045H,02EH,0B7H; 2069
DB 005H,02DH,04BH; 2070
DB 08AH,095H,0BFH; 2071
DB 00AH,095H,053H; 2072
DB 00BH,04AH,047H; 2073
DB 06BH,055H,03BH; 2074
DB 00AH,0D5H,04FH; 2075
DB 005H,05AH,045H; 2076
DB 04AH,05DH,038H; 2077
DB 00AH,05BH,04CH; 2078
DB 005H,02BH,042H; 2079
DB 03AH,093H,0B6H; 2080
DB 006H,093H,049H; 2081
DB 077H,029H,0BDH; 2082
DB 006H,0AAH,051H; 2083
DB 00AH,0D5H,046H; 2084
DB 054H,0DAH,0BAH; 2085
DB 004H,0B6H,04EH; 2086
DB 00AH,057H,043H; 2087
DB 045H,027H,038H; 2088
DB 00DH,026H,04AH; 2089
DB 08EH,093H,03EH; 2090
DB 00DH,052H,052H; 2091
DB 00DH,0AAH,047H; 2092
DB 066H,0B5H,03BH; 2093
DB 005H,06DH,04FH; 2094
DB 004H,0AEH,045H; 2095
DB 04AH,04EH,0B9H; 2096
DB 00AH,04DH,04CH; 2097
DB 00DH,015H,041H; 2098
DB 02DH,092H,0B5H; 2099
DB 00DH,053H,049H; 2100
;以下子程序用于从当前公历日期,推算星期,
;入口:TIME_YEAR,TIME_MONTH ,TIME_DATA ,定义公历年月日,BCD 码,其中月的
;以下子程序用于从当前公历日期,推算星期,
;入口:TIME_YEAR,TIME_MONTH ,TIME_DATE ,定义公历年月日,BCD 码,其中月的
;年份存入R5,月份存入R6,日期存入R7(BCD码)
TIME_WEEK1 DATA 52H
WEEK:
MOV A,TIME_YEAR
MOV B,#16
DIV AB
MOV TEMP_BYTE1,B
MOV B,#10
MUL AB
ADD A,TEMP_BYTE1
MOV TEMP_BYTE1,A ;TEMP_BYTE1=年
MOV A,TIME_MONTH
JB ACC.7,GETW02
MOV A,#100
ADD A,TEMP_BYTE1
MOV TEMP_BYTE1,A ;20 世纪年+100
MOV A,TIME_MONTH
CLR ACC.7
GETW02: JNB ACC.4,GETW04
ADD A,#10
CLR ACC.4
GETW04: MOV TEMP_BYTE2,A ;TEMP_BYTE2=月
MOV A,TIME_DATA
MOV B,#16
DIV AB
MOV TEMP_BYTE3,B
MOV B,#10
MUL AB
ADD A,TEMP_BYTE3
MOV TEMP_BYTE3,A ;TEMP_BYTE3=日
MOV A,TEMP_BYTE1;
ANL A,#03H
JNZ GETW10 ;非闰年转移
MOV A,TEMP_BYTE2
CJNE A,#3,GETW06
GETW06: JNC GETW10 ;月大于2 转移
DEC TEMP_BYTE3 ;份小于等于2,又是闰年,日减1
GETW10: MOV A,TEMP_BYTE2;
LCALL GET_CORRECT ;取月校正表数据
ADD A,TEMP_BYTE1
MOV B,#7
DIV AB ;B 放年加校正日数之和后除7 的余数不先做这一步
;有可能数据溢出
MOV A,TEMP_BYTE1
ANL A,#0FCH
RR A
RR A ;以上年除4 即闰年数
ADD A,B
ADD A,TEMP_BYTE3
MOV B,#7
DIV AB
MOV A,B
CJNE A,#0,OUTOUT
MOV  B,#8
OUTOUT:               ;星期日显示8
MOV TIME_WEEK1,B
RET
GET_CORRECT:
MOVC A,@A+PC
RET
DB 0,3,3,6,1,4,6,2,5,0,3,5
END
GET_CORRECT:
MOVC A,@A+PC
RET
DB 0,3,3,6,1,4,6,2,5,0,3,5
END
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 电子工程师成长日记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档