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

📄 1.asm

📁 万年历电路 里面有程序和图纸
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;寄存器配置:(时间和日期)
 ;    第3组(18~1FH)(RS1、RS0=11)R0~R3,公历年月日;
 ;                         R4~R7,时间的时、分、秒、百分之一秒(0.01秒)
 ;    第2组(10~17H)(RS1、RS0=10)计算农历日期存储中间临时数据
 ;    第1组(08~0FH)(RS1、RS0=01)键盘处理程序存储
 ;           闹钟设置状态:R4、R5设置时间时、分,R6、R7计算分钟数
 ;           万年历状态:R0~R3查看的公历年月日,R6、R7农历月日,R4、R5总天数
 ;           时间设置时:直接在第3组寄存器操作
 ;    第0组(00~07H)(RS1、RS0=00)计算中间值临时存储器
 ;
 ;总天数、星期、当天分钟计数器、农历日期寄存器
 ;    30H、31H--距1925.1.1日总天数
 ;    32H--高四位星期几,低四位与33H当天的分钟数
 ;    34~37H--农历年月日
 ;寄存器配置:(闹钟),两个字节为一个单位
 ;           低地址最高位表示是否设置闹钟,低四位与27H为闹钟时间(当天的分钟数)
 ;    闹钟1:28H、29H,星期一到五闹钟
 ;    闹钟2:2AH、2BH,配置与闹钟1相同
 ;    闹钟3:2CH、2DH,为每日闹钟
 ;    闹钟4:2EH、2FH,为一次性闹钟
 ;运行状态寄存器:27H单元,00H,正常的时间显示模式
 ;    1xH,闹铃设置模式,0~1位第几个闹钟(0~3号),第3位设置时(0)和分(1)
 ;    2xH,万年历查看模式,0~3分别加减10年、1年、1月、1日,1有效
 ;    4xH,时间日期设置,低四位都是0设置年,第0~3位分别为1时设置月、日、时、分(加减1)
 ;方波信号:位地址的07H、06H分别为1秒和0.5秒等脉宽信号,用于控制设置时闪烁显示
 ;显示缓冲区:6F~7F单元,分别为星期、年月日、时分、农历月日,星期1个单元、年4个单元、其余2个单元
 ;在计算过程中所示用的位寄存器:
 ;    在计算农历时用00H位(位地址)表示是否闰月
 ;    y年m月的天数用25H单元存储临时数据,01H位(位地址)表示当月是29天或30天
 ;    05H计时满一天后或者调整日期后请求进行农历日期计算标志为
 ;    04H调整小时或分钟后重新计算当天分钟数请求标识
 ;    06H、07H周期1秒和0.5秒的方波信号,前者用于秒闪烁,后者调整项闪烁
 ;****************************************************************************************
 ORG 0000H
 ;开机及复位后从第一行起运行
 LJMP 0080H  ;INITTHECLOCK
 ORG 0003H
 ;INT0中断服务程序,若有键按下则产转入键处理
 LJMP THEKEYDOWNSERVER ;900H
 ORG 000BH
 ;定时/计数器0中断服务程序,预计每10毫秒产生一次中断
 LJMP SETTIMEvalue ;0300H
 ORG 001BH
 ;定时/计数器1中断服务程序,用于延时5秒后将状态寄存器复位为00H
 PUSH A
 DEC 03H
 MOV A, 03H
 JNZ TIMER1RET
 ;按键后16秒中如果没有其他按键操作,自动转换为时间显示状态
 MOV A, 27H
 JZ TIMER1SERVERRET ;如果是状态0,直接返回
 TIMER1STATE1:
 JNB 3CH, TIMER1STATE2
 PUSH PSW ;如果是在闹钟设置状态下调用闹钟设置程序
 MOV PSW, #00001000B
 LCALL SETALARMTIME
 POP PSW
 AJMP TIMER1SERVERRET
 TIMER1STATE2:
 JNB 3DH, TIMER1STATE3
 AJMP TIMER1SERVERRET ;如果在万年历查看方式下直接换到时间显示状态
 TIMER1STATE3:
 JNB 3EH, TIMER1SERVERRET
 ;如果在时间设置状态下,更改当前分钟数
 SETB 05H ;设置农历日期计算请求标识
 JNB 04H, TIMER1SERVERRET
 PUSH PSW
 PUSH B
 MOV PSW, #00011000B ;
 MOV A, R4 ;如果调整了时间,重新计算当天分钟数
 MOV B, #60
 MUL AB
 ADD A, R5
 MOV 33H, A
 MOV A, B
 ADDC A, #0
 MOV 32H, A
 MOV R6, #0 ;秒清零
 CLR 04H
 POP B
 POP PSW
 ;AJMP TIMER1SERVERRET
 TIMER1SERVERRET:
 MOV 27H, #00H
 CLR TR1
 TIMER1RET:
 POP A
 RETI
 ;****************************************************************************************
 ORG 0080H
 INITTHECLOCK:
 MOV SP, #38H
 JNB 08H, INITRESET
 MOV PSW, #00011000B ;使用3组寄存器(0、1、2、3四组寄存器)
 MOV R7, #00 ;初始时间:00:00:00.00
 MOV R6, #00
 MOV R5, #00
 MOV R4, #00
 MOV R3, #15 ;初始日期:2000.1.1
 MOV R2, #12
 MOV R1, #0D4H
 MOV R0, #7
 MOV 33H, #0 ;初始当天分钟计数器,32H高4位为星期
 MOV 32H, #0
 MOV 27H, #0
 SETB 08H; 标识上电启动,在复位启动时不初始化时间日期
 SETB 05H ;
 INITRESET:
 MOV PSW, #00H
 MOV R0, #28H
 LOOPINIT:
 MOV @R0, #00
 INC R0
 CJNE R0, #30H, LOOPINIT
 CLR P1.7
 CLR P2.2
 MOV IE, #10001011B ;开定时/计数器0、1中断,开外部中断0,关其余中断
 SETB IT0 ;设置INT0为负边沿触发
 MOV IP, #00000010B ;设置定时/计数器0的中断优先级为高
 MOV TMOD, #00010010B ;定义定时/计数器0计数模式,与INT0无关,计数模式为8位自动重装模式
                      ;定义定时/计数器1计数模式,与INT1无关,计数模式为16位计数模式
 MOV TH0, #6 ;拟计数脉冲频率为25K,计数满250时间为10毫秒
 MOV TL0, #6
 SETB TR0 ;启动定时/计数器0
 MOV PSW, #00000000B
 MOV P2, #11111111B
 ;显示字符、闹铃检测比较循环程序
 DISPLAYPREPARATIVE:
 JNB 05H, LUNARDATETODISPLAY
 CLR 05H
 PUSH PSW ;计算农历日期
 MOV PSW, #00010000B
 ACALL SETLUNARDATE
 POP PSW
 LUNARDATETODISPLAY:
 LCALL ALARMCLOCK ;闹铃检测及服务程序
 MOV DPTR, #0F90H ;数字1~9的共阴极显示码首地址
 MOV A, 27H       ;取运行状态寄存器,以选择显示方式
 JNZ DISABNORMAL
 DISPLAYNORMAL:
 MOV A, 32H ;正常时间显示模式下,取星期显示码
 SWAP A
 ANL A, #0FH
 JNZ DISWEEKDAY
 MOV A, #8
 DISWEEKDAY:
 MOVC A, @A+DPTR
 MOV 6FH, A
 MOV R0, #19H  ;取年分显示码,共4位
 MOV R1, #70H
 ACALL DISYEARCODE
 MOV R0, #1AH  ;取日期(月日)显示码,共4位
 ACALL DISCODE
 INC R0        ;取时间(时分)显示码,共4位
 ACALL DISCODE
 MOV R0, #36H  ;取农历日期(月日)显示码,共4位
 ACALL DISCODE
 AJMP DISPLAYRUN
 DISABNORMAL: ;设置及万年历模式下,显示方式
 JB 3CH, DISSTATE1XH
 JB 3DH, DISSTATE2XH
 JB 3EH, DISSTATE3XH
 JB 3FH, DISSTATE4XH
 AJMP DISPLAYPREPARATIVE
 DISSTATE3XH:
 AJMP JMPDISSTATE3XH
 DISSTATE4XH:
 AJMP JMPDISSTATE4XH
 DISSTATE1XH: ;状态1(设置闹钟),星期栏显示闹钟号(1~4),闹铃标志亮,时间栏显示,其余不显示
 MOV A, 27H ;取状态字
 ANL A, #00000111B
 INC A
 MOVC A, @A+DPTR
 MOV 6FH, A  ;在星期一栏显示闹钟号(1~4)
 MOV R1, #70H ;阳历的年月日日期都不显示,送显示码00H到显示缓冲区
 LOOPDISSTATE1XH:
 MOV @R1, #0
 INC R1
 CJNE R1, #78H, LOOPDISSTATE1XH
 DEC R1
 MOV R0, #0CH ;时间时,分显示码,第1组寄存器R4、R5
 ACALL DISCODE
 INC R1
 LOOPDISSTATE1XH1: ;农历日期兰不显示,送显示码00H到显示缓冲区
 MOV @R1, #0
 INC R1
 CJNE R1, #80H, LOOPDISSTATE1XH1
 JB 07H, DISSTATE1XHFLICKER
 AJMP DISPLAYRUN
 DISSTATE1XHFLICKER: ;设置时的闪烁显示
 JB 3BH, DISSTATE1XHFLICKERMINUTE
 MOV 78H, #0         ;时消隐
 MOV 79H, #0
 AJMP DISPLAYRUN
 DISSTATE1XHFLICKERMINUTE:
 MOV 7AH, #0         ;分消隐
 MOV 7BH, #0
 AJMP DISPLAYRUN
 DISSTATE2XH: ;状态2(万年历),时间栏不显示,只显示阴阳历日期及星期
 MOV A, 26H  ;取星期显示码,高4位
 ANL A, #0F0H
 SWAP A
 JNZ DISSTATE2XHWEEKDAY
 MOV A, #8
 DISSTATE2XHWEEKDAY:
 MOVC A, @A+DPTR
 MOV 6FH, A
 MOV R0, #09H  ;取年显示码,共4位
 MOV R1, #70H
 ACALL DISYEARCODE
 MOV R0, #0AH  ;取日期(月日)显示码,共4位
 ACALL DISCODE
 LOOPDISSTATE2XH: ;时间不显示,送0为显示码
 INC R1
 MOV @R1, #0
 CJNE R1, #7BH, LOOPDISSTATE2XH
 MOV R0, #0EH   ;取阴历(月日)显示码,共4位
 ;MOV R1, #7BH
 ACALL DISCODE
 JB 07H, DISSTATE2XHFLICKER
 AJMP DISPLAYRUN
 DISSTATE2XHFLICKER:
 JB 38H, DISSTATE2XHFLICKERYEAR10
 JB 39H, DISSTATE2XHFLICKERYEAR1
 JB 3AH, DISSTATE2XHFLICKERMONTH
 JB 3BH, DISSTATE2XHFLICKERDATE
 AJMP DISPLAYRUN
 DISSTATE2XHFLICKERYEAR10:
 MOV 72H, #0
 AJMP DISPLAYRUN
 DISSTATE2XHFLICKERYEAR1:
 MOV 73H, #0
 AJMP DISPLAYRUN
 DISSTATE2XHFLICKERMONTH:
 MOV 74H, #0
 MOV 75H, #0
 AJMP DISPLAYRUN
 DISSTATE2XHFLICKERDATE:
 MOV 76H, #0
 MOV 77H, #0
 AJMP DISPLAYRUN
 JMPDISSTATE3XH: ;状态3(设置时间日期),不显示农历的日期和星期
 MOV 6FH, #0  ;星期,不显示
 MOV R0, #19H  ;取年分显示码,共4位
 MOV R1, #70H
 ACALL DISYEARCODE
 MOV R0, #1AH  ;取日期(月日)显示码,共4位
 ACALL DISCODE
 INC R0        ;取时间(时分)显示码,共4位
 ACALL DISCODE
 LOOPDISSTATE3XH: ;时间不显示,送0为显示码
 INC R1
 MOV @R1, #0
 CJNE R1, #7FH, LOOPDISSTATE3XH
 JB 07H, DISSTATE3XHFLICKER
 AJMP DISPLAYRUN
 DISSTATE3XHFLICKER:
 JB 38H, DISSTATE3XHFLICKERYEAR
 JB 39H, DISSTATE3XHFLICKERMONTH
 JB 3AH, DISSTATE3XHFLICKERDATE
 JB 3BH, DISSTATE3XHFLICKERHOUR
 ;DISSTATE3XHFLICKERINUTE:
 MOV 7AH, #0
 MOV 7BH, #0
 AJMP DISPLAYRUN
 DISSTATE3XHFLICKERYEAR:
 MOV 70H, #0
 MOV 71H, #0
 MOV 72H, #0
 MOV 73H, #0
 AJMP DISPLAYRUN
 DISSTATE3XHFLICKERMONTH:
 MOV 74H, #0
 MOV 75H, #0
 AJMP DISPLAYRUN
 DISSTATE3XHFLICKERDATE:
 MOV 76H, #0
 MOV 77H, #0
 AJMP DISPLAYRUN
 DISSTATE3XHFLICKERHOUR:
 MOV 78H, #0
 MOV 79H, #0
 AJMP DISPLAYRUN
 JMPDISSTATE4XH:
 AJMP DISPLAYNORMAL
 ;AJMP DISPLAYRUN
 DISPLAYRUN: ;显示码送显示驱动器
 MOV C, 06H
 MOV P2.0, C ;
 MOV C, 07H
 MOV P2.1, C ;
 MOV P0, 6FH
 SETB P2.2
 ACALL DELAY
 CLR P2.2
 MOV R0, #70H
 MOV R2, #0
 LOOPDISPLAY:
 MOV P0, @R0
 MOV A, R2
 SWAP A
 ANL P2, #0FH
 ORL P2, A
 CLR P2.3
 ACALL DELAY
 SETB P2.3
 INC R0
 INC R2
 CJNE R2, #16, LOOPDISPLAY
 LJMP DISPLAYPREPARATIVE
 DELAY:
 ;显示延迟
 ;((2*R6+1)*R7+1)机器周期
 MOV R7, #5
 LOOPDALAY:
 MOV R6, #100
 LOOPDALAY1:
 DJNZ R6, LOOPDALAY1
 DJNZ R7, LOOPDALAY
 RET
 DISYEARCODE:
 MOV A, @R0 ;计算年的显示码
 CLR C
 SUBB A, #0D0H ;(2000->7D0H)
 MOV B, A
 DEC R0
 MOV A, @R0
 SUBB A, #07H
 JNC DISYEAR2000
 INC R0
 MOV A, @R0
 CLR C
 SUBB A, #06CH ;(1900->76CH)
 MOV B, A
 ;MOV A, 18H
 ;SUBB A, #07H
 MOV A, #1
 MOVC A, @A+DPTR
 MOV @R1, A
 MOV A, #9
 MOVC A, @A+DPTR
 INC R1
 MOV @R1, A
 AJMP DISYEAR10
 DISYEAR2000:
 MOV A, #2
 MOVC A, @A+DPTR
 MOV @R1, A
 MOV A, #0
 MOVC A, @A+DPTR
 INC R1
 MOV @R1, A
 DISYEAR10:
 MOV A, B
 MOV B, #10
 DIV AB
 MOVC A, @A+DPTR
 INC R1
 MOV @R1, A
 MOV A, B
 MOVC A, @A+DPTR
 INC R1
 MOV @R1, A
 RET
 DISCODE:
 MOV A, @R0
 MOV B, #10
 DIV AB
 MOVC A, @A+DPTR
 INC R1
 MOV @R1, A
 MOV A, B
 MOVC A, @A+DPTR
 INC R1
 MOV @R1, A
 INC R0
 MOV A, @R0
 MOV B, #10
 DIV AB
 MOVC A, @A+DPTR
 INC R1
 MOV @R1, A
 MOV A, B
 MOVC A, @A+DPTR
 INC R1
 MOV @R1, A
 RET
 ;****************************************************************************************


;--  作者:hh_dream623
;--  时间:2006-02-28 20:08:09
;--

 SETLUNARDATE:
 MOV A, 19H         ;设置计算总天数程序的入口参数,(年-1925)送R2
 SUBB A, #85H       ;1925D=785H
 MOV R2, A
 MOV R3, 1AH        ;月送R3
 MOV R4, 1BH        ;日送R4
 LCALL CALCULATETOTALDAYS ;计算距离1925年1月1日的总天数
 MOV 30H, R6        ;计算结果送30H、31H单元保存
 MOV 31H, R7
 LCALL SETWEEKDAYS  ;计算星期几
 MOV A, R5
 SWAP A
 ANL 32H, #0FH
 ORL 32H, A         ;计算结果送32H单元高四位保存
 MOV R4, 30H        ;计算农历日期程序入口参数,总天数送R4、R5
 MOV R5, 31H
 LCALL LUNARDATECALULATE
 MOV 37H, R7        ;
 MOV 36H, R4        ;
 MOV A, R2
 ADD A, #85H        ;1925D=785H
 MOV 35H, A
 MOV A, #0
 ADDC A, #07H
 MOV 34H, A
 RET
 ;****************************************************************************************
 ORG 0300H
 ;时间计数器累加,设置当前时间,年月日、时分秒、0.01秒
 ;设置时间
 SETTIMEvalue:
 PUSH PSW            ;压栈保护现场PSW、A、B
 PUSH A
 PUSH B
 MOV PSW, #00011000B ;使用第三组寄存器
 INC 24H             ;250微秒计数器
 MOV A, 24H
 CJNE A, #40, RETTIME
 MOV 24H, #00H
 INC R7              ;百分之一秒(0.01秒)时间计数器
 ;产生周期为1秒及0.5秒的方波脉冲信号
 MS250:
 CJNE R7, #25, MS500
 CPL 07H
 MS500:
 CJNE R7, #50, MS750
 CPL 07H
 CPL 06H
 MS750:
 CJNE R7, #75, MS1000
 CPL 07H
 MS1000:
 CJNE R7, #100, RETTIME
 CPL 07H
 CPL 06H
 MOV R7, #0          ;满一秒钟,百分秒计数器清零
 INC R6              ;秒计数器
 CJNE R6, #60, RETTIME
 MOV R6, #0          ;满一分钟,分计数器清零
 INC R5              ;分钟计数器
 MOV A, 33H          ;当天分钟数计数器(32H低四位、33H)
 ADD A, #1
 MOV 33H, A
 MOV A, #0
 ADDC A, 32H
 MOV 32H, A
 CJNE R5, #60, RETTIME
 MOV R5, #0         ;满一小时,分钟计数器清零
 INC R4             ;时计数器
 CJNE R4, #24, RETTIME
 MOV R4, #0         ;满一天,时计数器清零
 MOV 33H, #0        ;当天分钟计数器清零
 MOV 32H, #0
 ACALL SETDATEvalue ;设置日期计数器
 ;计算日期入口条件设置
 SETB 05H           ;设置请求计算农历日期指示
 RETTIME:
 POP B              ;出栈恢复现场B、A、PSW
 POP A
 POP PSW
 RETI
 ;设置日期
 SETDATEvalue:
 INC R3              ;天计数器
 MOV A, R2           ;判断月份以确定当月的天数
 DEC A
 JZ DAY31;1月
 DEC A
 JZ DAY28;2月
 DEC A
 JZ DAY31;3月
 DEC A
 JZ DAY30;4月
 DEC A
 JZ DAY31;5月
 DEC A
 JZ DAY30;6月
 DEC A
 JZ DAY31;7月
 DEC A
 JZ DAY31;8月
 DEC A
 JZ DAY30;9月
 DEC A
 JZ DAY31;10月
 DEC A
 JZ DAY30;11月
 DEC A
 JZ DAY31;12月
 DAY31:
 CJNE R3,#32,RETDATE ;大月,31天
 AJMP SETMONTH
 DAY30:
 CJNE R3,#31,RETDATE ;小月,30天
 AJMP SETMONTH
 DAY28:              ;2月,平年28天,闰年29天
 MOV A, R1;计算当年-1925年
 SUBB A, #84H ;
 MOV B, #4
 DIV AB
 MOV A, B
 JZ DAY29
 CJNE R3, #29, RETDATE;平年2月28天
 AJMP SETMONTH
 DAY29:
 CJNE R3,#30,RETDATE  ;闰年2月29天
 ;AJMP SETMONTH
 SETMONTH:
 MOV R3, #1           ;满一个月,日计数器设置为1
 INC R2               ;月计数器
 CJNE R2, #13, RETDATE
 MOV R2, #1           ;满一年,月计数器设置为1
 MOV A, #1            ;年计数器(R0、R1)
 ADD A, R1
 MOV R1, A
 MOV A, #0
 ADDC A, R0
 MOV R0, A
 RETDATE:
 RET
 ;*****************************************************************************************
 ORG 0400H
 ;*****************************************************************************************
 ORG 0500H
 ;计算当天距离1925年1月1日的总天数,使用第2组寄存器
 ;入口:R2=年-1925,R3=月,R4=日
 ;出口:R6、R7=总天数
 CALCULATETOTALDAYS:
 MOV A, R2   ;假设1年有365天,计算(年-1925)年的总天数
 MOV B, #6DH ;16DH(365)的低位字节
 MUL AB
 MOV R7, A
 MOV A, R2
 ADD A, B
 MOV R6, A
 MOV A, R2   ;补加(年-1925)中闰年补偿(一年366天)的天数

⌨️ 快捷键说明

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