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

📄 1.asm

📁 万年历电路 里面有程序和图纸
💻 ASM
📖 第 1 页 / 共 3 页
字号:
 MOV B, #4
 DIV AB
 ADD A, R7
 MOV R7, A
 MOV A, #0
 ADDC A, R6
 MOV R6, A
 MOV A, R3   ;假设每月有28天,计算(月-1)个月的总天数
 DEC A
 MOV B, #28  ;设每月有28天
 MUL AB
 ADD A, R7
 MOV R7, A
 MOV A, B
 ADDC A, R6
 MOV R6, A
 MOV DPTR, #0F70H   ;平年月天数补偿表起始地址(大月31天、小月30天、闰年2月29天)
 MOV A, R2
 INC A
 MOV B, #4
 DIV AB
 MOV A, B
 JNZ SETDPTREND
 MOV DPTR, #0F80H   ;闰年月天数补偿表起始地址
 SETDPTREND:
 MOV A, R3          ;补加月补偿天数
 DEC A
 MOVC A, @A+DPTR
 ADD A, R7
 MOV R7, A
 MOV A, #0
 ADDC A, R6
 MOV R6, A
 MOV A, R4          ;日
 DEC A
 ADD A, R7
 MOV R7, A
 MOV A, #0
 ADDC A, R6
 MOV R6, A
 RET
 ;*****************************************************************************************
 ORG 0580H
 ;计算当前是星期几,使用第0组寄存器
 ;入口:R6、R7,为当天距离1925年1月1日的总天数
 ;出口:R5,计算结果0表示星期天,1~6分别为星期一至星期六
 SETWEEKDAYS:
 MOV A, R7      ;取出总天数,加4(1925年1月1日为星期四)
 ADD A, #4
 MOV R7, A
 MOV A, #0
 ADDC A, R6
 MOV R6, A      ;计算总天数除以7的余数
 MOV B, #7
 DIV AB
 MOV R6, B
 MOV A, R7
 MOV B, #7
 DIV AB
 MOV A, B
 RL A
 RL A
 RL A
 MOV R7, A
 MOV A, R6
 RL A
 RL A
 RL A
 MOV B, #7
 DIV AB
 MOV R6, B
 MOV R0, #3
 WEEKDAYSLOOP:
 MOV A, R6
 CLR CY
 RRC A
 MOV R6, A
 MOV A, R7
 RRC A
 MOV R7, A
 DEC R0
 CJNE R0, #0, WEEKDAYSLOOP
 ;MOV A, R7
 MOV B, #7
 DIV AB
 MOV R5, B
 RET
 ;*****************************************************************************************
 ORG 0700H
 ;计算农历日期(年月日),第0组、第1组(00H~0FH)寄存器存储计算中间值
 ;子程序段
 LUNARYEARDAYS:
 ;计算农历Y年的总天数
 ;入口,R2, Y年-1925
 ;出口,R4、R5,Y年的总天数
 MOV R5, #5CH ;设一年29x12=348(15CH)天
 MOV R4, #1
 MOV DPTR, #0E00H ;资料起始地址
 MOV A, R2 ;设置DPTR,原因:资料单位为字(双字节)
 ADD A, DPL
 MOV DPL, A
 MOV A, #0
 ADDC A, DPH ;在程序设计时确定该计算不会溢出
 MOV DPH, A
 MOV A, R2 ;取Y年月份资料高字节(1~8月份)
 MOVC A, @A+DPTR
 MOV R0, #0 ;累加农历Y年应补加的天数
 MOV R1, #8 ;移位计数器
 LOOPLUNARYEARDAYS1:
 RLC A
 JNC LUNARYEARDAY291
 INC R0
 LUNARYEARDAY291:
 DJNZ R1, LOOPLUNARYEARDAYS1
 MOV A, R2 ;取低字节资料的高四位
 INC A
 MOVC A, @A+DPTR
 MOV R1, #4
 LOOPLUNARYEARDAYS2:
 RLC A
 JNC LUNARYEARDAY292
 INC R0
 LUNARYEARDAY292:
 DJNZ R1, LOOPLUNARYEARDAYS2
 MOV A, R0
 ADD A, R5
 MOV R5, A
 MOV A, #0
 ADDC A, R4
 MOV R4, A
 LCALL LUNARLEAPDAYS ;补加Y年闰月的天数(R3)
 MOV A, R3
 ADD A, R5
 MOV R5, A
 MOV A, #0
 ADDC A, R4
 MOV R4, A
 RET
 LUNARLEAPDAYS:
 ;计算农历Y年的闰月的天数
 ;入口:R2 Y年-1925
 ;出口:R3,Y年闰月的天数
 LCALL LUNARLEAPMONTH ;Y年有无闰月,润几月。结果存在R3
 CJNE R3, #0, LUNARLEAPDAYS29
 MOV R3, #0
 LJMP LUNARLEAPDAYSRET
 LUNARLEAPDAYS29:
 MOV A, R2 ;取月份资料低字节低四位(闰月天数资料)
 INC A
 ADD A, #2 ;取(Y年-1924),低四位表示前一年闰月天数
 MOVC A, @A+DPTR
 ANL A, #0FH ;取低四位
 XRL A, #0FH ;如果低四位为F,则前一年闰月30天
 JZ LUNARLEAPDAYS30
 MOV R3, #29
 LJMP LUNARLEAPDAYSRET
 LUNARLEAPDAYS30:
 MOV R3, #30
 LUNARLEAPDAYSRET:
 RET
 LUNARLEAPMONTH:
 ;计算农历Y年的闰月的月份
 ;入口:R2 Y年-1925
 ;出口:R3,Y年闰月的月份, 0表示Y年无闰月
 MOV A, R2
 INC A
 MOVC A, @A+DPTR
 ANL A, #0FH ;取低四位
 MOV R3, A
 XRL A, #0FH ;如果是F,返回0,Y年无闰月
 JNZ LUNARLEAPMONTHRET
 MOV R3, #0
 LUNARLEAPMONTHRET:
 RET
 LUNARMONTHDAYS:
 ;计算农历Y年的M月的天数
 ;入口:R2 Y年-1925, R4 M月
 ;出口:RX,Y年M月的天数
 ;MOV A, R2
 ;MOV DPTR, #2000H ;资料起始地址
 ;MOV A, R2 ;设置DPTR,原因:资料单位为字(双字节)
 ;ADD A, DPL
 ;MOV DPL, A
 ;MOV A, #0
 ;ADDC A, DPH ;在程序设计时确定该计算不会溢出
 ;MOV DPH, A
 MOV A, R2 ;取Y年月份资料高字节(1~8月份)
 MOVC A, @A+DPTR
 MOV 25H, A
 MOV A, R4 ;循环计数器
 MOV R0, A
 MOV R1, #8
 MOV A, 25H
 LOOPMONTHDAYS1:
 RLC A
 MOV 01H, C
 DEC R0
 DEC R1
 MOV 25H, A ;保存A寄存器的内容
 MOV A, R0
 JZ EXITLOOPMONTHDAYS2
 MOV A, R1
 JZ EXITLOOPMONTHDAYS1
 MOV A, 25H ;恢复A寄存器的内容
 LJMP LOOPMONTHDAYS1
 EXITLOOPMONTHDAYS1:
 MOV A, R2 ;取低字节资料
 INC A
 MOVC A, @A+DPTR
 LOOPMONTHDAYS2:
 RLC A
 MOV 01H, C
 DJNZ R0, LOOPMONTHDAYS2
 EXITLOOPMONTHDAYS2:
 JB 01H, LUNARMONTHDAYS30
 MOV R3, #29
 LJMP LUNARMONTHDAYSRET
 LUNARMONTHDAYS30:
 MOV R3, #30
 LUNARMONTHDAYSRET:
 RET
 ;计算农历日期的主程序
 LUNARDATECALULATE:
 ;计算农历日期,使用第0组或第1组寄存器
 ;入口:R4、R5总天数
 ;出口:R2=年-1925;R4=月;R7=日
 ;分三段计算1925.1.24~1968.1.30、~2011.2.3、~2045.2.8、~2099.12.31
 MOV A, R5
 CLR C
 SUBB A, #033H
 MOV R7, A
 MOV A, R4
 SUBB A, #0B8H
 MOV R6, A
 MOV R2, #129
 JNC EXITFENDUAN
 MOV A, R5
 CLR C
 SUBB A, #0D4H
 MOV R7, A
 MOV A, R4
 SUBB A, #07AH
 MOV R6, A
 MOV R2, #86
 JNC EXITFENDUAN
 MOV A, R5
 CLR C
 SUBB A, #076H
 MOV R7, A
 MOV A, R4
 SUBB A, #03DH
 MOV R6, A
 MOV R2, #43
 JNC EXITFENDUAN
 MOV A, R5
 CLR C
 SUBB A, #017H
 MOV R7, A
 MOV A, R4
 SUBB A, #0
 MOV R6, A
 MOV R2, #0
 JNC EXITFENDUAN
 LJMP ERRCALCULATE   ;计算出错,超出日期范围
 EXITFENDUAN:        ;分段计算有效总天数R6、R7,年份R2,R4、R5失效后面的程序可以使用
 LOOPCALCULATEYEAR:
 LCALL LUNARYEARDAYS
 MOV A, R7
 CLR C
 SUBB A, R5
 MOV R7, A
 MOV A, R6
 SUBB A, R4
 MOV R6, A
 JC EXITLOOPCALCULATEYEAR
 INC R2
 MOV A, R2
 XRL A, #176 ;大于175(2100年)退出循环
 JNZ PASSERRCALCULATE2
 LJMP ERRCALCULATE
 PASSERRCALCULATE2:
 LJMP LOOPCALCULATEYEAR
 EXITLOOPCALCULATEYEAR:
 MOV A, R7    ;加上最后一年减掉的天数,当年已经过去的天数,用于计算月份和日期
 ADD A, R5
 MOV R7, A
 MOV A, R6
 ADDC A, R4
 MOV R6, A
 ;DEC R2 ;如果是零,为1926年
 LCALL LUNARLEAPMONTH  ;判断是否有闰月,月份存在R3
 MOV A, R3
 MOV R5, A
 CLR 00H ;是否闰月标识
 MOV R4, #1 ;计算月数
 LOOPCALCULATEMONTH:
 MOV A, R5
 JZ CALCULATEMONTH1 ;转无闰月处理
 MOV A, #1
 ADD A, R5
 XRL A, R4
 JNZ CALCULATEMONTH1 ;转非闰月处理
 JB 00H, CALCULATEMONTH1
 DEC R4
 SETB 00H ;设置闰年标识
 LCALL LUNARLEAPDAYS ;读取当年闰月的天数R3
 LJMP CALCULATEMONTH2 ;
 CALCULATEMONTH1:
 LCALL LUNARMONTHDAYS ;结果存放在R3中
 CALCULATEMONTH2:
 JNB 00H, CALCULATEMONTH3
 MOV A, #1
 ADD A, R5
 XRL A, R4
 JNZ CALCULATEMONTH3
 CLR 00H ;解除闰月标识
 CALCULATEMONTH3:
 MOV A, R7
 CLR C
 SUBB A, R3
 MOV R7, A
 MOV A, R6
 SUBB A, #0
 MOV R6, A
 JC EXITLOOPCALCULATEMONTH
 INC R4
 MOV A, R4 ;如果大于十二退出,提示错误
 XRL A, #13
 JZ ERRCALCULATE
 LJMP LOOPCALCULATEMONTH
 EXITLOOPCALCULATEMONTH:
 MOV A, R5 ;判断是否闰月
 JZ CALCULATEMONTH5
 MOV A, #1
 ADD A, R5
 XRL A, R4
 JNZ CALCULATEMONTH5
 JNB 00H, CALCULATEMONTH4
 CLR 00H
 LJMP CALCULATEMONTH5
 CALCULATEMONTH4:
 SETB 00H
 DEC R4
 CALCULATEMONTH5:
 MOV A, R7   ;加最后一次减的天数,当月已经过完的天数
 ADD A, R3
 MOV R7, A
 MOV A, #0
 ADDC A, R6
 MOV R6, A
 ;DEC R4
 INC R7 ;计算日期
 LJMP CALCULATERET
 ;计算结果:R2=年-1925;R4=月;R7=日
 ERRCALCULATE: ;错误显示
 ;错误处理程序
 NOP
 CALCULATERET:
 RET
 ;****************************************************************************************


;--  作者:hh_dream623
;--  时间:2006-02-28 20:08:46
;--
ORG 0900H
 THEKEYDOWNSERVER:
 ;27H单元的位地址高位到低位:37、36、35、34、33、32、31、30(H)
 ;有键按下的位为0,本程序为按键处理分派
 CLR TR1 ;关闭延时计数器
 CLR EX0 ;关闭INT0中断
 PUSH P0
 MOV P0, #0
 MOV 04H, #10 ;延时单元
 KEYDELAY:
 MOV 05H, #200
 DJNZ 05H, $
 DJNZ 04H, KEYDELAY
 PUSH PSW  ;保护现场
 PUSH A
 PUSH B
 MOV PSW, #00001000B
 MOV A, P1
 ORL A, #0FH
 MOV P1, A ;读键盘口,结果存储26H第四位
 MOV A, P1
 CPL A
 ANL A, #0FH
 JZ KEYALLOT5 ;如果无键按下,推出
 ANL 26H, #0F0H
 ORL 26H, A
 KEYALLOT1:
 MOV A, 27H
 JNZ KEYALLOT2
 ACALL KEYSTATE0
 AJMP KEYALLOT5
 KEYALLOT2:
 JNB 3CH, KEYALLOT3
 ACALL KEYSTATE1
 AJMP KEYALLOT5
 KEYALLOT3:
 JNB 3DH, KEYALLOT4
 ACALL KEYSTATE2
 AJMP KEYALLOT5
 KEYALLOT4:
 JNB 3EH, KEYALLOT8
 ACALL KEYSTATE3
 AJMP KEYALLOT5
 KEYALLOT8:
 JNB 3FH, KEYALLOT5
 ACALL KEYSTATE4
 ;AJMP KEYALLOT5
 KEYALLOT5:
 POP B ;恢复现场
 POP A
 POP PSW
 POP P0
 ;设置延时计数器,如果在5秒钟内没有按键动作自动转到时间显示状态
 MOV TH1, #0
 MOV TF0, #0
 MOV 03H, #255
 CLR IE0
 SETB EX0
 SETB TR1 ;计时开始
 RETI
 KEYSTATE0:
 ;状态0按键处理,时间显示状态
 STATE0KEY0:
 JNB 30H, STATE0KEY1
 MOV 27H, #10H
 ACALL PRESETALARMTIME
 AJMP KEYSTATE0RET
 STATE0KEY1:
 JNB 31H, STATE0KEY2
 AJMP STATE0KEY12
 STATE0KEY2:
 JNB 32H, STATE0KEY3
 STATE0KEY12:
 MOV 27H, #24H
 MOV R0, 18H
 MOV R1, 19H
 MOV R2, 1AH
 MOV R3, 1BH
 MOV R6, 36H
 MOV R7, 37H
 MOV A, 32H
 ANL A, #0F0H
 ANL 26H, #0FH
 ORL 26H, A
 AJMP KEYSTATE0RET
 STATE0KEY3:
 JNB 33H, KEYSTATE0RET
 MOV 27H, #48H
 ;AJMP KEYSTATE0RET
 KEYSTATE0RET:
 RET
 KEYSTATE1:
 ;状态1按键处理,闹钟设置状态
 STATE1KEY0:
 JNB 30H, STATE1KEY1
 ACALL SETALARMTIME ;SET
 MOV 27H, #21H ;初始化万年历状态
 MOV R0, 18H
 MOV R1, 19H
 MOV R2, 1AH
 MOV R3, 1BH
 MOV R6, 36H
 MOV R7, 37H
 MOV A, 32H
 ANL A, #0F0H
 ANL 26H, #0FH
 ORL 26H, A
 AJMP KEYSTATE1RET
 STATE1KEY1:
 JNB 31H, STATE1KEY2
 JB 3BH,  STATE1KEY1MIN ;UP
 INC R4
 CJNE R4, #25, STATE1KEY1HOUR
 MOV R4, #0
 STATE1KEY1HOUR:
 AJMP KEYSTATE1RET
 STATE1KEY1MIN:
 ACALL MINUTEADJUST
 AJMP KEYSTATE1RET
 STATE1KEY2:
 JNB 32H, STATE1KEY3
 JB 3BH,  STATE1KEY2MIN ;DOWN
 DEC R4
 CJNE R4, #0FFH, STATE1KEY2HOUR
 MOV R4, #24
 STATE1KEY2HOUR:
 AJMP KEYSTATE1RET
 STATE1KEY2MIN:
 ACALL MINUTEADJUST
 AJMP KEYSTATE1RET
 STATE1KEY3:
 JNB 33H, KEYSTATE1RET
 JNB 3BH, STATE1KEY3CHANGE ;RIGHT
 ACALL SETALARMTIME
 MOV A, 27H
 ANL A, #03H
 INC A
 MOV B, #4
 DIV AB
 MOV A, B
 ANL 27H, #0F0H
 ORL 27H, A
 ACALL PRESETALARMTIME
 AJMP KEYSTATE1RET
 STATE1KEY3CHANGE:
 SETB 3BH ;切换到分钟调整
 ;AJMP KEYSTATE1RET
 KEYSTATE1RET:
 RET
 KEYSTATE2:
 ;状态2按键处理,万年历查看状态
 STATE2KEYO:
 JNB 30H, STATE2KEY1
 MOV 27H, #41H ;按键0,SET
 AJMP KEYSTATE2RET
 STATE2KEY1:
 JNB 31H, STATE2KEY2
 JNB 38H, STATE2KEY1YEAR ;按键1, UP
 MOV B, #10
 ACALL YEARADJUST
 AJMP KEYSTATE2RET
 STATE2KEY1YEAR:
 JNB 39H, STATE2KEY1MONTH
 MOV B, #1
 ACALL YEARADJUST
 AJMP KEYSTATE2RET
 STATE2KEY1MONTH:
 JNB 3AH, STATE2KEY1DATE
 ACALL MONTHADJUST
 AJMP KEYSTATE2RET
 STATE2KEY1DATE:
 JNB 3BH, KEYSTATE2RET
 ACALL DATEADJUST
 AJMP KEYSTATE2RET
 STATE2KEY2:
 JNB 32H, STATE2KEY3
 JNB 38H, STATE2KEY2YEAR ;按键2, DOWN
 MOV B, #10
 ACALL YEARADJUST
 AJMP KEYSTATE2RET
 STATE2KEY2YEAR:
 JNB 39H, STATE2KEY2MONTH
 MOV B, #1
 ACALL YEARADJUST
 AJMP KEYSTATE2RET

⌨️ 快捷键说明

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