;*******************************************************************************
;* USER WORKING MEMORY (VARIABLE DEFINITION) *
;*******************************************************************************
DATA RAM
DEBOUNCE2 BYTE
INPUT_MASK2 BYTE
LAST_KEY_STATE2 BYTE
KEY_FS2 BYTE
KEY_RS2 BYTE
UCADDR BYTE ;写入DS1302的地址
UCDATA BYTE ;写入DS1302的内容
SECOND BYTE
MINUTE BYTE
HOUR BYTE
DAY BYTE
MONTH BYTE
WEEK BYTE
YEAR BYTE
PCLOCK EQU SECOND
MiniValue BYTE ;设定秒,分。。。的最小值
MaxValue BYTE ;设定秒,分。。。的最大值
TimeSetupFlag BYTE ;设置时间的标志
SETUPSECOND_FLAG EQU 00000001B ;设定秒标志
SETUPMINUTE_FLAG EQU 00000010B ;设定分标志
SETUPHOUR_FLAG EQU 00000100B ;设定时标志
SETUPDAY_FLAG EQU 00001000B ;设定日标志
SETUPMONTH_FLAG EQU 00010000B ;设定月标志
SETUPWEEK_FLAG EQU 00100000B ;设定星期标志
SETUPYEAR_FLAG EQU 01000000B ;设定年标志
FlashCount WORD ;闪烁计时,半秒改变一次,以T1 1000HZ计算,FlashCount=500时改变一次显示状态,
; 由亮变为灭,或由灭变为亮
FlashFlag BYTE ; 闪烁状态,第0位,1表示亮,0表示灭
CODE
;************************************************************
;FUNCTION 初始化变量
;************************************************************
InitialDS1302Value FUNCTION
MOVE [INPUT_MASK2], 00111000B
MOVE [TimeSetupFlag], 00H
MOVE [FlashFlag], 00H
MOVEW [FlashCount], 0000H
RET
InitialDS1302Value ENDF
;************************************************************
;FUNCTION 开始写, 控制命令,WP=0,写操作
;************************************************************
InitialDS1302 FUNCTION
CALL InitialDS1302Value
MOVE [UCADDR],90H
MOVE [UCDATA],A0H
CALL WRITE1302 ; FUNCTION 写操作
;CALL InitialTime
;*************************************************************
;FUNCTION 控制命令,WP=1,写保护功能
;*************************************************************
MOVE [UCADDR],8EH
MOVE [UCDATA],80H
CALL WRITE1302 ;FUNCTION 写保护
RET
InitialDS1302 ENDF
;=================================================================
;FUNCTION InitialTime() 设置初始时间
;=================================================================
InitialTime FUNCTION
MOVE X,00H
MOVE PTR,TAB1
@L1 MOVE A,[PTR]
MOVE [PCLOCK+X], A
INC PTR
INC X
CMP X, 07H
JNZ @L1
CALL SET1302
RET
InitialTime ENDF
;**************************************************************
;FUNCTION 调整功能 1个按键是功能选择,另外一个是数值加,
; 另外一个是数值减
;**************************************************************
;**************************************************************
;FUNCTION 调整功能
;**************************************************************
DS1302_SCAN_KEY FUNCTION
CMP [DEBOUNCE2], 20
JNC @F
RET
@ MOVE [DEBOUNCE2], 0
MOVE A, [PORT1_DATA]
MOVE X, A
XOR A, [LAST_KEY_STATE2] ; GET CHANGE KEY STATE
AND A, [INPUT_MASK2]
PUSH A
AND A, [LAST_KEY_STATE2] ; GET FALLING EDGE KEY
MOVE [KEY_FS2], A
POP A
AND A, X ; GET RISING EDGE KEY
MOVE [KEY_RS2], A
MOVE [LAST_KEY_STATE2], X
OR A, [KEY_FS2]
JNZ @HAS_KEY_EVENT2
RET
@HAS_KEY_EVENT2
;有按键,打开LCD背光
CALL SetBacklight
;=============================================================================================================
; 向上键处理
@KEYF_P13 JBZ [KEY_FS2], 00001000B, @KEYF_P14 ;第P1.3脚, 上键
CALL Key_Increase
JUMP @QUIT_SCAN2
;=============================================================================================================
; 中键,主要是功能切换处理, 秒结束后,就停止设置会到正常时钟显示
; 设置顺序:年4位,前面都加20,如2008
; 月+日 四位,中间点不显示
; 时+分 四位,中间点显示
; 秒 二位,单独设置
@KEYF_P14 JBZ [KEY_FS2], 00010000B, @KEYF_P15 ;第P1.4脚, 功能键
MOVE A, [TimeSetupFlag]
JNZ A, @f
OR A, 10000000B
@
CLC ; 清楚PSR 零标志位
RCR A
; 星期自动计算,所以跳过设定
JBZ A, SETUPWEEK_FLAG, @F
CLC
RCR A
@
MOVE [TimeSetupFlag], A
; 判断是否已经一个设定循环结束,即TimeSetupFlag == 0, 如果等于0则保存以前设定的值
JNZ [TimeSetupFlag], @SETUP
CALL SaveSetup
JUMP @QUIT_SCAN2
@SETUP
MOVEW [FlashCount], 500
OR [FlashFlag], 00000001B
JUMP @QUIT_SCAN2
;=============================================================================================================
; 向下键处理
@KEYF_P15 JBZ [KEY_FS2], 00100000B, @QUIT_SCAN2 ;第P1.5脚, 下键
CALL Key_Decrease
JUMP @QUIT_SCAN2
@QUIT_SCAN2 MOVE [KEY_FS2], 00H ; CLEAR FALLING KEY STATUS
MOVE [KEY_RS2], 00H ; CLEAR RISING KEY STATUS
RET
DS1302_SCAN_KEY ENDF
;***************************************************************
;FUNCTION DS1302_ShowTime()
; 根据TimeSetupFlag决定是要正常显示,还是闪烁设置的状态, 设置时的
; 闪烁参见@KEYF_P14
;***************************************************************
DS1302_ShowTime FUNCTION
; 首先比对FlashCount 是否为 500 = 1f4H, 不是表示还没有到要刷新的时间,则加1后返回,需要刷新则进入下面判断
CMP [FlashCount], F4H
JNZ @NOTEQUAL
CMP [FlashCount+1],01H
JZ @F
@NOTEQUAL
ADDW [FlashCount], 1
RET
@
MOVEW [FlashCount], 0000H ;FlashCount == 500, 开始切换闪烁状态,并且重置FlashCount=0
MOVE A, [TimeSetupFlag] ;TimeSetupFlag == 0 表示不是设置状态,则正常显示时间
JNZ A, @@F ;SetupTime
;ShowNormalTime
;====================================================
;正常显示时间
CALL GET1302
MOVE A, [HOUR]
MOVE X, [MINUTE]
; 将时间显示出来
MOVE [ShowFlag], 00001111B ;ShowFlag 在LCD 中定义的,此处表示四位数字全部显示
CALL ShowTime ;Show
; 显示闪烁的两点
JBZ [FlashFlag], 00000001B, @F ;FlashFlag.0 == 1 表示显示, == 0 表示不显示
; 此处FlashFlag.0 == 1, 显示内容
MOVE [ShowFlag], 00010000B ;显示两点
CALL ShowDots
AND [FlashFlag], 11111110B
JUMP @RETURN
@
MOVE [ShowFlag], 00010000B ;隐藏两点
CALL ClearDots
OR [FlashFlag], 00000001B
@RETURN
RET
@@ ;=====================================================
; 有设置标志,则进行闪烁
;=====================================================
; 正在设置年
JBZ [TimeSetupFlag], SETUPYEAR_FLAG, @@F
CALL ClearDots
MOVE A, 0
MOVE X, [YEAR]
ADD AX, 2000
MOVE [NumberShow], AX
JBZ [FlashFlag], 00000001B, @F ;FlashFlag.0 == 1 表示显示, == 0 表示不显示
; 此处FlashFlag.0 == 1, 显示内容
MOVE [ShowFlag], 00001111B ;ShowFlag 在LCD 中定义的,此处表示四位数字全部显示
AND [FlashFlag], 11111110B
CALL ShowNumbers ;Show
RET
@
; 此处FlashFlag.0 == 0, 不显示内容
MOVE [ShowFlag], 00000000B ;ShowFlag 在LCD 中定义的,此处表示四位数字全部不显示
OR [FlashFlag], 00000001B
CALL ShowNumbers ;Show
RET
@@ ;=====================================================
; 正在设置月
JBZ [TimeSetupFlag], SETUPMONTH_FLAG, @@F
CALL ClearDots
MOVE A, [MONTH]
MOVE X, [DAY]
JBZ [FlashFlag], 00000001B, @F ;FlashFlag.0 == 1 表示显示, == 0 表示不显示
; 此处FlashFlag.0 == 1, 显示内容
MOVE [ShowFlag], 00001111B ;ShowFlag 在LCD 中定义的,此处表示四位数字全部显示
AND [FlashFlag], 11111110B
CALL ShowTime ;Show
RET
@
; 此处FlashFlag.0 == 0, 不显示内容
MOVE [ShowFlag], 00000011B ;ShowFlag 在LCD 中定义的,此处表示四位数字全部不显示
OR [FlashFlag], 00000001B
CALL ShowTime ;Show
RET
@@ ;=====================================================
; 正在设置日
JBZ [TimeSetupFlag], SETUPDAY_FLAG, @@F
CALL ClearDots
MOVE A, [MONTH]
MOVE X, [DAY]
JBZ [FlashFlag], 00000001B, @F ;FlashFlag.0 == 1 表示显示, == 0 表示不显示
; 此处FlashFlag.0 == 1, 显示内容
MOVE [ShowFlag], 00001111B ;ShowFlag 在LCD 中定义的,此处表示四位数字全部显示
AND [FlashFlag], 11111110B
CALL ShowTime ;Show
RET
@ ;=====================================================
; 此处FlashFlag.0 == 0, 不显示内容
MOVE [ShowFlag], 00001100B ;ShowFlag 在LCD 中定义的,此处表示四位数字全部不显示
OR [FlashFlag], 00000001B
CALL ShowTime ;Show
RET
@@ ;=====================================================
; 正在设置时
JBZ [TimeSetupFlag], SETUPHOUR_FLAG, @@F
CALL ShowDots
MOVE A, [HOUR]
MOVE X, [MINUTE]
JBZ [FlashFlag], 00000001B, @F ;FlashFlag.0 == 1 表示显示, == 0 表示不显示
; 此处FlashFlag.0 == 1, 显示内容
MOVE [ShowFlag], 00001111B ;ShowFlag 在LCD 中定义的,此处表示四位数字全部显示
AND [FlashFlag], 11111110B
CALL ShowTime ;Show
RET
@ ;=====================================================
; 此处FlashFlag.0 == 0, 不显示内容
MOVE [ShowFlag], 00000011B ;ShowFlag 在LCD 中定义的,此处表示四位数字全部不显示
OR [FlashFlag], 00000001B
CALL ShowTime ;Show
RET
@@ ;=====================================================
; 正在设置分
JBZ [TimeSetupFlag], SETUPMINUTE_FLAG, @@F
CALL ShowDots
MOVE A, [HOUR]
MOVE X, [MINUTE]
JBZ [FlashFlag], 00000001B, @F ;FlashFlag.0 == 1 表示显示, == 0 表示不显示
; 此处FlashFlag.0 == 1, 显示内容
MOVE [ShowFlag], 00001111B ;ShowFlag 在LCD 中定义的,此处表示四位数字全部显示
AND [FlashFlag], 11111110B
CALL ShowTime ;Show
RET
@ ;=====================================================
; 此处FlashFlag.0 == 0, 不显示内容
MOVE [ShowFlag], 00001100B ;ShowFlag 在LCD 中定义的,此处表示四位数字全部不显示
OR [FlashFlag], 00000001B
CALL ShowTime ;Show
RET
@@ ;=====================================================
; 正在设置秒
JBZ [TimeSetupFlag], SETUPSECOND_FLAG, @@F
CALL ClearDots
MOVE A, FFH
MOVE X, [SECOND]
JBZ [FlashFlag], 00000001B, @F ;FlashFlag.0 == 1 表示显示, == 0 表示不显示
; 此处FlashFlag.0 == 1, 显示内容
MOVE [ShowFlag], 00000011B ;ShowFlag 在LCD 中定义的,此处表示四位数字全部显示
AND [FlashFlag], 11111110B
CALL ShowTime ;Show
RET
@ ;=====================================================
; 此处FlashFlag.0 == 0, 不显示内容
MOVE [ShowFlag], 00000000B ;ShowFlag 在LCD 中定义的,此处表示四位数字全部不显示
OR [FlashFlag], 00000001B
CALL ShowTime ;Show
@@ RET
DS1302_ShowTime ENDF
;**************************************************************
;FUNCTION 数值增函数
;**************************************************************
Key_Increase FUNCTION
PUSH A
PUSH X
MOVE X,00H
MOVE A, [TimeSetupFlag]
JZ A, @NOT_SETUP_MODE
@ RCR A
JC @SETUP_TIME ; 有设定时间
INC X
CMP X, 07H
JNZ @B
@SETUP_TIME
PUSH X
MOVE PTR, TAB2
ROL X ;X = X*2
ADD PTR, X ;取设定时的最小值
MOVE A, [PTR]
MOVE [MiniValue], A
INC PTR ;取设定时的最大值
MOVE A, [PTR]
MOVE [MaxValue], A
POP X
MOVE A, [PCLOCK+X]
CMP A, [MaxValue]
JZ @F
INC A
JUMP @@F
@
MOVE A, [MiniValue]
@@
;此时A内的值为新的设定值,将新的设定值写入DS1302
MOVE [PCLOCK+X], A
JUMP @EXIT_KEY_INCREASE
@NOT_SETUP_MODE
; TimeSetupFlag == 0, 表示不在设定时间状态
@EXIT_KEY_INCREASE
POP X
POP A
RET
Key_Increase ENDF
;***************************************************************
;FUNCTION 数值减函数
;***************************************************************
Key_Decrease FUNCTION
PUSH A
PUSH X
MOVE X,00H
MOVE A, [TimeSetupFlag]
JZ A, @NOT_SETUP_MODE
@ RCR A
JC @SETUP_TIME ; 有设定时间
INC X
CMP X, 07H
JNZ @B
@SETUP_TIME
PUSH X
MOVE PTR, TAB2
ROL X ;X = X*2
ADD PTR, X ;取设定时的最小值
MOVE A, [PTR]
MOVE [MiniValue], A
INC PTR ;取设定时的最大值
MOVE A, [PTR]
MOVE [MaxValue], A
POP X
MOVE A, [PCLOCK+X]
CMP A, [MiniValue]
JZ @F
DEC A
JUMP @@F
@
MOVE A, [MaxValue]
@@
;此时A内的值为新的设定值,将新的设定值写入DS1302
MOVE [PCLOCK+X], A
JUMP @EXIT_KEY_DECREASE
@NOT_SETUP_MODE
; TimeSetupFlag == 0, 表示不在设定时间状态
@EXIT_KEY_DECREASE
POP X
POP A
RET
Key_Decrease ENDF
;***************************************************************
;FUNCTION SaveSetup()
; 保存时钟设置的结果
; 有两种状况会调用到此函数,一按【功能切换】键切到SetupTimeFlag == 0时调用
; 或者在设定时,较长时间没有按键,自动切会到时钟显示时,会调用
SaveSetup FUNCTION
; 先计算出 星期值
CALL CalculateWeek
CALL SET1302
RET
SaveSetup ENDF
;***************************************************************
;FUNCTION Write1302()
; 功 能:往DS1302写入数据
; 说 明:先写地址,后写命令/数据 (内部函数)
; 调 用:RTInputByte() , RTOutputByte()
; 入口参数:ucAddr: DS1302地址, ucData: 要写的数据
; 返 回 值:无
;***************************************************************
WRITE1302 FUNCTION
PUSH X
CALL ClearDS1302ChipSelect
CALL ClearDS1302Clock
CALL SetDS1302ChipSelect
MOVE A, [UCADDR]
CALL RTINPUTBYTE ;A 为参数
MOVE A, [UCDATA]
CALL RTINPUTBYTE
CALL SetDS1302Clock
CALL ClearDS1302ChipSelect
POP X
RET
WRITE1302 ENDF
;*******************************************************************
;函 数 名:Read1302()
; 功 能:读取DS1302某地址的数据
; 说 明:先写地址,后读命令/数据 (内部函数)
; 调 用:RTInputByte() , RTOutputByte()
; 入口参数:ucAddr: DS1302地址
; 返 回 值:ucData :读取的数据
;*******************************************************************
Read1302 FUNCTION
PUSH X
CALL ClearDS1302ChipSelect
CALL ClearDS1302Clock
CALL SetDS1302ChipSelect
MOVE A,[UCADDR]
CALL RTINPUTBYTE
CALL RTOUTPUTBYTE
MOVE [UCDATA],A
CALL SetDS1302Clock
CALL ClearDS1302ChipSelect
POP X
RET
Read1302 ENDF
;********************************************************************
;FUNCTION 设置初始时间,先写地址,后读命令/数据(寄存器多字节方式)
;- 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年
;-7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B
;********************************************************************
SET1302 FUNCTION
MOVE [UCADDR],8EH
MOVE [UCDATA],00H
CALL WRITE1302 ;FUNCTION 将控制寄存器的值设置为零,最高位WP=0允许写
MOVE [UCADDR], 80H
MOVE X,00H
@L
PUSH X
MOVE A, [PCLOCK+X]
; 将 要写入的值,转为BCD码, 如08年,需要转成08H, 12月需要转成12H 而非0CH
MOVEW [Dividend],0000H
MOVE [Dividend], A
MOVEW [Divisor], 0AH
CALL DIV16
MOVE A, 10H
IMUL [Quotient], A ; 商*16
ADD [Quotient], X ; 此时 X 内为除后的余数,加Quotient后,[Quotient]为写入值的BCD码
MOVE A, [Quotient]
MOVE [UCDATA], A
CALL WRITE1302 ;FUNCTION 将7个时间初值写入对应的控制寄存器
ADD [UCADDR], 2 ;UCADDR += 2
POP X ; 由于除法中X值会被改变,所以需要先PUSH, 在需要使用指出POP出来
INC X
CMP X, 07H ;IF X == 7 结束循环
JNZ @L
MOVE [UCADDR],8EH
MOVE [UCDATA],80H
CALL WRITE1302 ;FUNCTION 写保护
RET
SET1302 ENDF
;*********************************************************
;FUNCTION 读取当前时间值
;*********************************************************
GET1302 FUNCTION
PUSH A
MOVE [UCADDR],81H
MOVE X,00H
@
PUSH X
CALL Read1302 ;Read1302将读出的值放在A中
MOVEW [Dividend],0000H
MOVE [Dividend], A ;读出数据为BCD码,即56秒的值为56H,所以需要通过除以16*10+余数方法,得到正式16进制数
;如56秒,读出值为56H,通过56/16+56%16 = 38H
MOVEW [Divisor], 10H
CALL DIV16
MOVE A, 0AH
IMUL [Quotient], A ; 商*10
ADD [Quotient], X ; 此时 X 内为除后的余数,加Quotient后,[Quotient]为BCD码转出来的值,如原来32H,变为十进制的32
MOVE A, [Quotient]
POP X ; 由于除法中X值会被改变,所以需要先PUSH, 在需要使用指出POP出来
MOVE [PCLOCK+X], A
ADD [UCADDR], 2
INC X
CMP X, 07H
JNZ @B
POP A
RET
GET1302 ENDF
;*************************************************************
;FUNCTION RtOutputByte
; 函 数 名:RTOutputByte()
; 功 能:实时时钟读取一字节
; 说 明:从DS1302读取1Byte数据 (内部函数)
; 入口参数:无
; 返 回 值:A
;unsigned char RTOutputByte(void)
;{
; unsigned char i;
; for(i=8; i>0; i--)
; {
; ACC = ACC >>1; //相当于汇编中的 RRC
; ACC7 = T_IO;
; T_CLK = 1;
; T_CLK = 0;
; }
; return(ACC);
;}
;*************************************************************
RTOutputByte FUNCTION
MOVE A, 00H
AND PSR,11111110B
OR [PORT1_IO_MODE], 00000010B ;设定P1.1为输入状态
MOVE X, 08H
@@
RCR A
JBZ [PORT1_DATA], 00000010B, @F
OR A, 10000000B
@ CALL SetDS1302Clock
CALL ClearDS1302Clock
LOOP X, @@B
RET
RTOutputByte ENDF
;*************************************************************
;FUNCTION RTInputByte
; 函 数 名:RTInputByte()
; 功 能:实时时钟写入一字节
; 说 明:往DS1302写入1Byte数据 (内部函数)
; 入口参数:A 写入的数据
; 返 回 值:无
;void RTInputByte(unsigned char d)
;{
; unsigned char i;
; ACC = d;
; for(i=8; i>0; i--)
; {
; T_IO = ACC0; //相当于汇编中的 RRC
; T_CLK = 1;
; T_CLK = 0;
; ACC = ACC >> 1;
; }
;}
;*************************************************************
RTInputByte FUNCTION
AND [PORT1_IO_MODE], 11111101B ;设定P1.1为输出状态
MOVE X, 08H
@@
RCR A
CALL ClearDS1302Data
JNC @F
CALL SetDS1302Data
@
CALL SetDS1302Clock
CALL ClearDS1302Clock
LOOP X, @@B
RET
RTInputByte ENDF
;********************************
;FUNCTION SetDS1302Clock()
;Clock 接 P12
;********************************
SetDS1302Clock FUNCTION
OR [PORT1_DATA],00000100b
RET
SetDS1302Clock ENDF
;********************************
;FUNCTION ClearDS1302Clock()
;********************************
ClearDS1302Clock FUNCTION
AND [PORT1_DATA],11111011b
RET
ClearDS1302Clock ENDF
;********************************
;FUNCTION SetDS1302Data()
;Data 接 P11
;********************************
SetDS1302Data FUNCTION
OR [PORT1_DATA],00000010b
RET
SetDS1302Data ENDF
;*********************************
;FUNCTION ClearDS1302Data()
;*********************************
ClearDS1302Data FUNCTION
AND [PORT1_DATA],11111101b
RET
ClearDS1302Data ENDF
;********************************
;FUNCTION SetDS1302ChipSelect()
;ChipSelect 接 P10
;********************************
SetDS1302ChipSelect FUNCTION
OR [PORT1_DATA],00000001b
RET
SetDS1302ChipSelect ENDF
;*********************************
;FUNCTION ClearDS1302ChipSelect()
;*********************************
ClearDS1302ChipSelect FUNCTION
AND [PORT1_DATA],11111110b
RET
ClearDS1302ChipSelect ENDF
; 计算星期几
; 已知D=第"N"年"m"月"d"日
; WD≡d+[ (13n-1)/5 ] + y +[y/4] +[c/4] -2c (mod 7),
; 这里 n = m-2若果 m="2"、3、....、12;
; 否则n=12若m=2, 及n=11若m=1。
; 注:其实这里想将月份倒推二个月。
; 此外c、y由以下公式确定:N=100 c + y,而y是0至99(包括0和99)的整数,即最后的两个位数字。c代表删去最后两个位所得到的数字,所谓c世纪。
; 在以上的方括号代表括号内数字的整数部份。
; 如[1.2]=1、[13.9]=13、[99/4]=[24.75]=24。
; 在此 mod 7 代表 将计算的答案用7除后,只取余数。这亦即常用的所谓"同余"。
; 最后的数值应该在0至6之间。
; "0"代表星期日;
; "1"代表星期一;
; "2"代表星期二;
; 如此类推
; 举个例子:
; 今天是 1999年 3月 20日,它应是星期六。
; 由此得N=1999,所以c=19、y=99、m=3、n=1、d=20。
; d+[ (13*n-1)/5 ] + y +[y/4] +[c/4] -2*c
; =20 +[ (13x1 -1)/5] +99+[99/4]+[19/4] -2x19
; ≡20+[12/5]+99+[99/4] +[19/4] -38
; ≡6+2 +1+24+4 - 3
; ≡6 (即星期六) 。
CalculateWeek FUNCTION
PUSH A
PUSH X
MOVEW [Dividend], 13 ;将Dividend 当临时变量用于乘除
;由于我们日期都是从2000-2099, 所以C为固定值20,C/4 固定为5, 2*C 固定为40,40%7 = 5,与C/4正好抵消
;先根据月计算出n 来,值放在A 里
MOVE A, [MONTH]
CMP A, 1
JZ @F
SUB A, 2
JUMP @@F
@ MOVE A, 11
@@ IMUL [Dividend], A ;此时Dividend = 13*N
DEC [Dividend] ;13N-1
MOVE A, 5
IDIV [Dividend], A ;Dividend = [13*N-1]/5
;忽略IDIV 除后的余数
MOVE A, [Dividend] ;将结果先保存到WEEK
MOVE [WEEK], A
;再计算y/4,
MOVE A, [YEAR]
MOVEW [Dividend], 0
MOVE [Dividend], A ;Dividend = YEAR
MOVE A, 4
IDIV [Dividend], A ;此时Dividend = Y/4
MOVE A,[Dividend] ;A = Y/4 X = y%4
ADD A, [DAY] ;A = D + Y/4
ADD A, [WEEK] ;A = D+ Y/4 + 此时WEEK值为[13*N-1]/5
ADD A, [YEAR] ;A = D + Y/4 + [13*N-1]/5 + Y
; ADD A, 5 ;A = D + Y/4 + [13*N-1]/5 + Y + C/4
; SUB A, 5 ;A = D + Y/4 + [13*N-1]/5 + Y + C/4 - 2C
MOVEW [Dividend], 0
MOVE [Dividend], A ;A当被除数
MOVEW [Divisor], 7 ;7为除数
CALL DIV16 ;此时X为余数,
;0代表星期天,这里把它修正为7,表示星期天
JNZ X, @F
MOVE X, 7
@
MOVE [WEEK], X
POP X
POP A
RET
CalculateWeek ENDF
; 秒 分 时 日 月 星期 年
TAB1 DB 00H,59H,23H,28H,04H,01H, 08H
; Min Max
; 秒 分 时 日 月 星期 年
; ====== ====== ====== ====== ====== ====== ======
TAB2 DB 0, 59, 0, 59, 00, 23, 1, 31, 01, 12, 1, 7, 00, 99
文章评论(0条评论)
登录后参与讨论