毕业设计(论文)单片机万年历程序7052931
毕业设计(论文)单片机万年历程序7052931
单片机实验
报告
软件系统测试报告下载sgs报告如何下载关于路面塌陷情况报告535n,sgs报告怎么下载竣工报告下载
Luangeng
一.实验要求 内容
本实验要求做出时间显示包括时分秒,可调时间,日期,日期滚动显示,闹铃设置及
到时响铃,倒计时,秒表计时和播放音乐等功能.这些功能需要的单片机知识有单片机
基本寻址方式及汇编程序设计,定时与中断,数码管扫描显示,键盘扫描检测及音乐播
放的基本原理等.
二.硬件环境与工作原理 接口地址
设备选择了 Atmel的 AT89C51,设置波特率 38400,频率 11.0592MHz,数码管段
选地址:8FFFH,数码管位选地址:9FFFH,段选和位选驱动都为高电平有效.蜂鸣器 P1.6,
为高电平有效.4*4的键盘复用了数码管位选地址8FFFH,写信号 /WR 控制行,读信号
/RD 控制列.
三.资源使用
键盘用了 16 个.定时中断 T0及 T1.寄存器 R0~R7,储存器如下.
储存变量定义如下:
CLK EQU 20H.0
CEK EQU 20H.1
HOUR EQU 40H
MIN EQU 41H
SEC EQU 42H ;存放秒钟变量
N EQU 43H ;存放5ms 计数值
CHH EQU 44H
CMM EQU 45H
CSS EQU 46H ;闹铃设置秒钟变量
RUN EQU 23H
DAY EQU 24H ;日期变量
MONTH EQU25H
YEARL EQU 26H
YEARH EQU 27H
BUF1 EQU28H ;显示缓
冲区
BUF2 EQU29H
BUF3 EQU2AH
BUF4 EQU2BH
BUF5 EQU2CH
BUF6 EQU2DH
BUF7 EQU2EH
BUF8 EQU2FH
BUF9 EQU30H
BUF10 EQU31H
BUF11 EQU32H
CHH_D EQU 48H ;倒数时
间小时数
CMM_D EQU 49H
CSS_D EQU 4AH
STOP_S EQU 4BH ;秒表
STOP_M EQU 4CH
STOP_MS EQU 4DH
SEG1 EQU 50H ;数码
管
SEG2 EQU51H
SEG3 EQU52H
SEG4 EQU53H
SEG5 EQU54H
SEG6 EQU55H
SEG7 EQU56H
SEG8 EQU57H
TEMP EQU 58H ;临时变量
FMQ EQU P1.6 ;蜂鸣器
四.程序原理与框图
第一部分是变量定义区,第二部分是主函数,包括初始化和键盘循环检测.第三部分
是子函数区,第四部分为常数区.子函数包括定时器初始化,年月日转换,数码管扫描显
示,键盘操作,调整时间,设置闹铃,闹铃时间转换,检查闹铃是否到,闹铃到了响应,倒计
时程序,日期转换,日期扫描显示,日期设置,闰年判断,秒表子程序,音乐,响音乐时的显
示和 3个延迟子函数.
主函数流程:
调用数据初始化子程序
调用定时器初始化子程序
调用显示时间子函数
调用键盘读取子程序
根据读到的键调用响应的子函数
主函数代码:
MAIN:
ACALL INITALL
ACALL INIT_TIMER
MAINLOOP: ;循环区
ACALL CONV
ACALL CLK_ON
ACALL SEG_DISP
;设置时间
ACALL KEYBOARD ;DU DI1 JIAN
CJNEA,#00H,M1
ACALL SET_TIME
JMP MAINLOOP ;设置
闹铃时间
M1:
CJNEA,#01H,M2
ACALL SET_CLK
JMP MAINLOOP
M2: ;闹钟开关
CJNEA,#0DH,M3
CPLCLK
JNBCLK,M2_1 ;闹铃启动
LCALL BZ
LCALL BZ
JMP MAINLOOP
M2_1:
LCALL BZ ;闹铃停止
JMP MAINLOOP
M3: ;设置倒计时
CJNEA,#0BH,M4
ACALL SET_DOWN
JMP MAINLOOP
M4: ;滚动日期
CJNEA,#0EH,M5
ACALL DATE_DISP
JMP MAINLOOP ;调整日期
M5:
CJNEA,#02H,M6
ACALL DATA_SET
JMP MAINLOOP ;秒表
M6:
CJNEA,#03H,M7
ACALL STOP
JMP MAINLOOP
M7: CJNEA,#0AH,M8
ACALL MUSIC
JMP MAINLOOP
M8:
JMP MAINLOOP
秒表原理及流程:
为了秒表计时的准确,使用了定时器作为时间源,由于定时器为
5ms定时,故先
需要对它 2分频,采用奇偶方法分频.然后 ms 位满 100 进 1,s位满
60 进 1.
流程描述
Miaobiao:
初始化数据
Readkey;
If key start goto start;
If key end gotoend;
Start:
读取定时器N;
If N为偶数 ms 加一;
Readkey;
If key pause gotopause;
If key end gotoend;
Pause:
Readkey;
If key start goto start;
If key end gotoend;
End:
初始化数据;
Return;
歌曲信息及发音原理:
使用定时器根据频率和间隔产生高低变化的方波信号,使扬声器不断置高低
电平,从而发声.遇到休止符,则暂停发声,当下一个音符到来的时候,再打开定时器,
继续产生方波,驱动蜂鸣器发音.
译为频率和间隔时间的十六进制:
DB 0FDH,0C6H,02H,0FEH,02H,02H
DB 0FEH,2AH,04H,0FEH,02H,02H
DB 0FEH,2AH,04H,0FEH,84H,04H
DB 0FEH,02H,02H
DB 00H,00H,04H
DB 0FDH,08H,02H,0FDH,08H,02H
DB 0FDH,0C6H,03H,0FDH,80H,02H
DB 0FDH,0C6H,04H,0FEH,2AH,04H
DB 0FDH,80H,04
DB 00H,00H,04H
DB 0FDH,08H,02H,0FDH,08H,02H
DB 0FDH,30H,03H,0FDH,08H,02H
DB 0FDH,30H,02H,0FEH,2AH,03H
DB 0FDH,08H,04H
DB 00H,00H,04H
DB 0FEH,2AH,02H,0FEH,2AH,02H
DB 0FEH,2AH,03H,0FEH,02H,03H
DB 0FDH,30H,02H,0FDH,30H,04H
DB 0FEH,02H,04H,0FEH,02H,04H
DB 0FFH,0FFH
五.操作说明
键位安排: S0 到 S15 分别代表各键位值;S0 为进入时间设置和完成返回键;S1为
进入闹铃设置和完成返回按键;S2 为进入日期设置和完成按键;S3为进入秒表和退出
按键;S11 为进入倒计时和退出键;S4,S8,S12 分别为年月日及时分秒家一按
键,S5,S9,S13 分别为年月日及时分秒减一按键;S6 为闹钟开关键;S10 为日期滚动
键,S14 为播放音乐按键.具体见图.
键位安排
六.调试与实际运行结果
调试结果: 调试过程中没有什么错误.
运行结果: 所有功能皆可完美的实现,当然还存在着一些小错误和可改进的地方.
可以改进的地方:
1.秒表忘记了清零的键,故功能不全,可以加入.
2.在音乐响完后蜂鸣器继续发声,虽然解决过,但偶尔还会出现问题,原因不明.
3.键盘由于使用次数多而发生不灵的现象,可改变键盘除抖和延迟时间加以优化.
4.定时器 1 的定时间隔太短,故系统负荷较重.可更改计时模式,增大间隔.
编译结果: Program Size: data 8.0 xdata 0code 5453
七.总结与体会
这是单片机基本编程练习,未涉及硬件,所以是非常基本的.在实际的工作中,这样
的简单程序只能做个电子表,而这种产品已经充斥着市场,稍微学习过的人都会做,所
以是没有经济价值的.故对学习单片机的学习才只是个开头,以后的学习要多向实际
应用发展.做别人不会做的,才能成为高手.这次是用汇编语言做的,而 C 语言对汇编来
说是有他自己的长处的,所以下次应该练习用C语言写程序,之后学习综合使用C和汇
编写程序,才能综合两者长处,提高编程效率.再有,硬件很重要,不会单片机硬件就是外
行.总之在繁重的专业课之余,找时间学习单片机!
附录:
ORG0000H
JMP MAIN
ORG000BH
JMP T0_SRV
ORG 1000H
CLK EQU 20H.0
CEK EQU 20H.1
HOUR EQU 40H
MIN EQU 41H
SEC EQU 42H ;存放秒钟变量
N EQU 43H ;存放
5ms 计数值
CHH EQU 44H
CMM EQU 45H
CSS EQU 46H ;闹铃设置秒钟变量
RUN EQU 23H
DAY EQU 24H
MONTH EQU25H
YEARL EQU 26H
YEARH EQU 27H
BUF1 EQU28H
BUF2 EQU29H
BUF3 EQU2AH
BUF4 EQU2BH
BUF5 EQU2CH
BUF6 EQU2DH
BUF7 EQU2EH
BUF8 EQU2FH
BUF9 EQU30H
BUF10 EQU31H
BUF11 EQU32H
SEC0 EQU 47H ;存放旧的
秒数
CHH_D EQU 48H ;倒数时间小时数
CMM_D EQU 49H
CSS_D EQU 4AH
STOP_S EQU 4BH ;秒表
STOP_M EQU 4CH
STOP_MS EQU 4DH
SEG1 EQU 50H ;数码管
SEG2 EQU51H
SEG3 EQU52H
SEG4 EQU53H
SEG5 EQU54H
SEG6 EQU55H
SEG7 EQU56H
SEG8 EQU57H
TEMP EQU 58H
FMQ EQU P1.6
;***************************************主程序区
******************************
INITALL:
CLRCEK
CLRCLK
MOV N,#0
MOVSEC,#55 ;时间
MOVMIN,#19
MOVHOUR,#02
MOV CHH,#2 ;闹钟
MOV CMM,#20
MOV CSS,#0
MOV CHH_D,#0 ;倒计时
MOV CMM_D,#0
MOV CSS_D,#0
MOV DAY,#06 ;日期
MOV MONTH,#03
MOV YEARL,#11
MOV YEARH,#20
MOV TEMP,#033H
RET
MAIN:
ACALL INITALL
ACALL INIT_TIMER
MAINLOOP: ;循
环区
ACALL CONV
ACALL CLK_ON
ACALL SEG_DISP
;设置时间
ACALL KEYBOARD ;DU
DI1 JIAN
CJNEA,#00H,M1
ACALL SET_TIME
JMP MAINLOOP ;设置闹铃时间
M1:
CJNEA,#01H,M2
ACALL SET_CLK
JMP MAINLOOP
M2: ;
闹钟开关
CJNEA,#0DH,M3
CPL CLK
JNBCLK,M2_1 ;
闹铃启动
LCALL BZ
LCALL BZ
JMP MAINLOOP
M2_1:
LCALL BZ ;闹铃
停止
JMP MAINLOOP
M3: ;设置
倒计时
CJNEA,#0BH,M4
ACALL SET_DOWN
JMP MAINLOOP
M4: ;
滚动日期
CJNEA,#0EH,M5
ACALL DATE_DISP
JMP MAINLOOP ;
调整日期
M5:
CJNEA,#02H,M6
ACALL DATA_SET
JMP MAINLOOP ;
秒表
M6:
CJNEA,#03H,M7
ACALL STOP
JMP MAINLOOP
M7: CJNEA,#0AH,M8
ACALL MUSIC
JMP MAINLOOP
M8:
JMP MAINLOOP
;
INIT_TIMER:
;初始化定时器,实用定时器T0 模式0 计时
MOV TMOD,#00H ;设置定时器T0 模式0
MOV IE,#82H ;启用定时器T0 中断产生
MOV TL0,#00H ;加载初始化数据
MOV TH0,#70H
SETB TR0 ;启动定时器0开始计时
RET
T0_SRV: ;定时器T0 中断程序每隔5ms 中
断一次
PUSH ACC
MOV TL0,#00H;重加载初始化数据
MOV TH0,#70H
INC N ;加1
;秒输出
MOV A,N
CJNEA,#200,TT1
MOV N,#0
INC SEC ;秒计数加1
MOV A,SEC
CJNEA,#60,TT1 ;是否1min到了
;分输出
INC MIN ;分计数加1
MOV SEC,#0
MOV A,MIN
CJNEA,#60,TT1 ;是否1h到了
;时输出
INC HOUR
MOV MIN,#0
MOV A,HOUR
CJNEA,#24,TT1 ;是否1 天到
了
;天输出
INC DAY
MOV HOUR,#0
MOV DPTR,#MONTHTAB
MOV A,MONTH
MOVC A,@A+DPTR
MOV B,DAY
CJNEA,B,TT1
;月输出 ;是否
1 月到了
INC MONTH
MOV DAY,#1
MOV A,MONTH
CJNEA,#13,TT1 ;是否1
年到了
;年输出
INC YEARL
MOV MONTH,#1
MOV A,YEARL
CJNEA,#100,TT1
INC YEARH
MOV YEARL,#0
MOV A,YEARH
CJNEA,#100,TT1
MOV SEC,#0H
MOV MIN,#0H
MOV HOUR,#0H
MOV DAY,#1H
MOV MONTH,#1H
MOV YEARL,#0H
MOV YEARH,#0H
TT1: POPACC
RETI
CONV:
MOVDPTR,#SEGTAB
MOVA,SEC
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVSEG2,A
MOVA,B
MOVC A,@A+DPTR
MOVSEG1,A
MOVA,MIN
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVSEG5,A
MOVA,B
MOVC A,@A+DPTR
MOVSEG4,A
MOVA,HOUR
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVSEG8,A
MOVA,B
MOVC A,@A+DPTR
MOVSEG7,A
JNBCEK,CLKOFF
MOV SEG3,#80H
MOV SEG6,#80H
JMP ENDING
JNBCLK,CLKOFF
MOVSEG3,#0C0H
MOVSEG6,#0C0H
RET
CLKOFF:
MOVSEG3,#40H
MOVSEG6,#40H
ENDING: RET
;
SEG_DISP:
PUSH 00H
PUSH 06H
MOVR0,#SEG1
MOVR6,#08H
MOVA,#00H
MOVR2,#01H
SEG_LOOP:
MOVDPTR,#9FFFH
MOVA,@R0
INC R0
MOVX @DPTR,A
MOVDPTR,#8FFFH
MOVA,R2
MOVX @DPTR,A
RL A
MOVR2,A
LCALL DLY400US
MOVA,#00H
MOVX @DPTR,A
DJNZ R6,SEG_LOOP
POP06H
POP00H
RET
;
KEYBOARD:
MOVDPTR,#9FFFH
MOVA,#00H
MOVX @DPTR,A
LCALL KEY_SCAN
JNZ CHUDOU ;除抖
LJMP END_KEYBOARD
CHUDOU:LCALL DLY10MS
LCALL KEY_SCAN
JNZ KEY_READ ;扫描
LJMP END_KEYBOARD
KEY_READ:
MOVR3,#01H
MOVB,#00H
MOVA,R3
KP4:MOVX @DPTR,A
MOVX A,@DPTR
JNB ACC.0,K1
MOVA,#00H
LJMP KP5
K1: JNB ACC.1,K2
MOVA,#04H
LJMP KP5
K2: JNB ACC.2,K3
MOVA,#08H
LJMP KP5
K3: JNB ACC.3,NEXT
MOVA,#0CH
KP5:ADDA,B
PUSH ACC
KP3:LCALL DLY10MS
LCALL KEY_SCAN
JNZ KP3
POPACC
RET
NEXT: INC B
MOVA,R3
JB ACC.3,END_KEYBOARD
RL A
MOVR3,A
LJMP KP4
END_KEYBOARD:
MOVA,#0FFH
RET
KEY_SCAN:
MOVDPTR,#8FFFH
MOVA,#0FH
MOVX @DPTR,A
MOVX A,@DPTR
ANL A,#0FH
RET
;--------------调整时间子程序
SET_TIME:
SETB CEK
CLRTR0 ;定时器工作暂停
ACALL CONV
ACALL SEG_DISP
KEY0:
LCALL SEG_DISP ;扫描显示
LCALL KEYBOARD
CJNEA,#04H,KEY1 ;未按下S1 键,则继续扫描
;S1 小时调整
INC HOUR
MOV A,HOUR
CJNEA,#24,L11 ;是否24 小时到了
MOV HOUR,#0H ;小时变量清零
L11:
ACALL CONV ;转换显示数据
ACALL SEG_DISP ;扫描显示
JMP KEY0
KEY1:
CJNEA,#08H,KEY3 ;未按下S2 键,则继续扫
描
;S2 分钟调整
INC MIN
MOV A,MIN
CJNEA,#60,L21 ;是否60min到了
MOV MIN,#0H ;分钟变量清零
L21:
ACALL CONV
ACALL SEG_DISP
JMP KEY0
KEY3:
CJNEA,#0CH,KEY2 ;未按下S2 键,则继续扫
描
;MIAO 调整
INC SEC
MOV A,SEC
CJNEA,#60,L31 ;是否60MIAO 到了
MOV SEC,#0H ;变量清零
L31:
ACALL CONV
ACALL SEG_DISP
JMP KEY0
KEY2:
CJNEA,#00H,KEY0 ;未按下S3 键,则继续扫描
SETB TR0 ;启动定时器
CLR CEK
RET
;----------------设置闹铃时间
;设置闹铃时间
SET_CLK:
ACALL CONVA ;加载闹铃时间数据
N0:
ACALL SEG_DISP
ACALL KEYBOARD
CJNEA,#04H,N1 ;未按下S1键则继续扫描
;S1 调整小时
INC CHH
MOV A,CHH
CJNEA,#24,N11
MOV CHH,#0
N11:
ACALL CONVA
ACALL SEG_DISP
JMP N0
N1:
CJNEA,#08H,N2 ;未按下S2 键则继续扫
描
;S2 调整分钟
INC CMM
MOV A,CMM
CJNEA,#60,N21
MOV CMM,#0
N21:
ACALL CONVA
ACALL SEG_DISP
JMP N0
N2:
CJNEA,#01H,N0 ;未按下S3 键则继续
扫描
;S3 设置完成
ACALL CONV
RET
;
CONVA:
;转换数据
MOV DPTR,#SEGTAB
MOVA,CSS
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVSEG2,A
MOVA,B
MOVC A,@A+DPTR
MOVSEG1,A
MOVSEG3,#80H
MOVA,CMM
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVSEG5,A
MOVA,B
MOVC A,@A+DPTR
MOVSEG4,A
MOVSEG6,#80H
MOVA,CHH
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVSEG8,A
MOVA,B
MOVC A,@A+DPTR
MOVSEG7,A
RET
;
CLK_ON:
JBCLK,TI3
RET
TI3:
MOV A,HOUR
MOV B,CHH
CJNEA,B,BK ;检查闹铃小时时间
MOV A,MIN
MOV B,CMM
CJNEA,B,BK ;检查闹铃分钟时间
MOV A,SEC
MOV B,CSS
CJNEA,B,BK ;检查闹铃秒钟时间
ACALL TIME_OUT ;调用执行检查闹铃时间处理
子程序
BK:
RET
;
TIME_OUT: ;闹铃时间到了
LCALL MUSIC ;蜂鸣器发声
MOV TMOD,#00H
MOV IE,#82H
ACALL CONV
ACALL SEG_DISP
RET
;********************倒计时程序
;设置倒计时时间
SET_DOWN:
ACALL DOWN_CONV
ACALL SEG_DISP
S0:
ACALL SEG_DISP
ACALL KEYBOARD
CJNEA,#0CH,S12
INC CSS_D
MOV A,CSS_D
CJNEA,#60,S11
MOV CSS_D,#0
INC CMM_D
S11:
ACALL DOWN_CONV
ACALL SEG_DISP
JMP S0
S12:
CJNEA,#0DH,S2
DEC CSS_D
MOV A,CSS_D
CJNEA,#0,S21
MOV CSS_D,#60
S21:
ACALL DOWN_CONV
ACALL SEG_DISP
JMP S0
S2:
CJNEA,#0FH,S4
;按S3 设置完成
LCALL BZ
LCALL BZ
JMP S3
S4:CJNEA,#08H,S5
INC CMM_D
MOV A,CMM_D
CJNEA,#60,S111
MOV CMM_D,#0
S111:
ACALL DOWN_CONV
ACALL SEG_DISP
JMP S0
S5:CJNEA,#0BH,S0
RET
S3:
ACALL DOWN_TIME
ACALL DOWN_CONV
ACALL SEG_DISP
ACALL KEYBOARD
CJNEA,#0BH,S3
MOV CMM_D,#00H
MOV CSS_D,#00H
RET
;
;显示倒数时间
DOWN_CONV:
MOVDPTR,#SEGTAB
MOVA,CSS_D
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVSEG2,A
MOVA,B
MOVC A,@A+DPTR
MOVSEG1,A
MOVA,CMM_D
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVSEG5,A
MOVA,B
MOVC A,@A+DPTR
MOVSEG4,A
MOVA,#40H
MOVSEG8,A
MOV A,#40H
MOVSEG7,A
MOVSEG3,#80H
MOVSEG6,#40H
RET
;---------检查倒计时
;检查倒计时
DOWN_TIME:
MOV A,SEC
MOV B,SEC0
CJNEA,B,D01
RET
D01:
MOV SEC0,SEC
DEC CSS_D
MOV A,CSS_D
CJNEA,#0,D11
MOV A,CMM_D
CJNEA,#0,D12
;秒钟数为0 且分钟数为0,则倒数终止
ACALL TIME_OUT
JMP MAINLOOP
RET
D12:
MOV CSS_D,#59
DEC CMM_D
D11:
ACALL DOWN_CONV
RET
;**************************日期显示
********************************
DATE_CONV:
MOVDPTR,#SEGTAB
MOVA,DAY
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVSEG2,A
MOVA,B
MOVC A,@A+DPTR
MOVSEG1,A
MOVA,MONTH
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVSEG4,A
MOVA,B
MOVC A,@A+DPTR
ORL A,#80H
MOVSEG3,A
MOVA,YEARL
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVSEG6,A
MOVA,B
MOVC A,@A+DPTR
ORL A,#80H
MOVSEG5,A
MOVA,YEARH
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVSEG8,A
MOVA,B
MOVC A,@A+DPTR
MOVSEG7,A
RET
;
DATE_DISP:
MOVDPTR,#SEGTAB
MOVA,YEARH
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVBUF1,A
MOVA,B
MOVC A,@A+DPTR
MOVBUF2,A
MOVA,YEARL
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVBUF3,A
MOVA,B
MOVC A,@A+DPTR
MOVBUF4,A
MOVBUF5,#40H
MOVA,MONTH
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVBUF6,A
MOVA,B
MOVC A,@A+DPTR
MOVBUF7,A
MOVBUF8,#40H
MOVA,DAY
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVBUF9,A
MOVA,B
MOVC A,@A+DPTR
MOVBUF10,A
MOVBUF11,#80H
MOVSEG1,#80H
MOVSEG2,#00H
MOVSEG3,#00H
MOVSEG4,#00H
MOVSEG5,#00H
MOVSEG6,#00H
MOVSEG7,#00H
MOVR6,#05H
DATE_L3:
MOVR0,#BUF1
MOVR7,#11
DATE_L2:MOVR3,#42H
MOVSEG8,SEG7
MOVSEG7,SEG6
MOVSEG6,SEG5
MOVSEG5,SEG4
MOVSEG4,SEG3
MOVSEG3,SEG2
MOVSEG2,SEG1
MOVSEG1,@R0
DATE_L1:
ACALL SEG_DISP
LCALL KEYBOARD
CJNE A,#0EH,JIXU
JMP DATE_QUIT
JIXU: DJNZ R3,DATE_L1
INC R0
DJNZ R7,DATE_L2
DJNZ R6,DATE_L3
DATE_QUIT:
AJMP CONV
AJMP SEG_DISP
RET
;
DATA_SET:
DA0:
LCALL DATE_CONV ;扫描显示
LCALL SEG_DISP
LCALL KEYBOARD
CJNEA,#04H,DA2 ;未按下S7 键,则继续扫
描
;年调整
INC YEARL
MOV A,YEARL
CJNEA,#100,DA21
MOV YEARL,#0 ;变量清零
INC YEARH
MOV A,YEARH
CJNEA,#100,DA21
MOV YEARH,#0
DA21:
ACALL DATE_CONV
ACALL SEG_DISP
JMP DA0
DA2:
CJNEA,#08H,DA3 ;未按下S9 键,则继续扫描
;月调整
INC MONTH
MOV A,MONTH
CJNEA,#13,DA21
MOV MONTH,#1 ;变量循环
DA3:
CJNEA,#0CH,DA4 ;未按下SA键,则继续扫描
;日调整
INC DAY
ACALL RUNNIAN
MOV A,RUN
JZ DA30
JMP DA31
DA30:
MOV DPTR,#MONTHTAB
JMP DA32
DA31:
MOV DPTR,#RUNTAB
JMP DA32
DA32:
MOV A,MONTH
MOVC A,@A+DPTR
MOV B,DAY
CJNEA,B,DA21
MOV DAY,#1 ;变量清零
DA4:
CJNEA,#02H,DA0 ;未按下SB键,则继续扫描
RET
RUNNIAN:
MOV RUN,#00H
MOV B,#04H ;B中置为04H用来测试
MOV A ,YEARL ;年的后两位送A
JZ TJ2 ;若后两位能被100整除则转向
条件2
DIVAB ;检测年的后两位是否能被4整除
MOV A ,B ;假若B中的余数为零则说明是闰年
JZ LEAP
JMP OVER
TJ2:
MOV A ,YEARH ;符合条件2 首先能被100整除
DIVAB ;假若高位能被4整除则说明能被400整除
MOV A ,B
JZ LEAP ;是闰年跳转
SJMPOVER
LEAP:
MOV RUN,#01H
OVER:
RET
;秒表功能程序
STOP_CONV:
MOVDPTR,#SEGTAB
MOVA,STOP_MS
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVSEG2,A
MOVA,B
MOVC A,@A+DPTR
MOVSEG1,A
MOVA,STOP_S
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVSEG5,A
MOVA,B
MOVC A,@A+DPTR
MOVSEG4,A
MOVA,STOP_M
MOV B,#10
DIVAB
MOVC A,@A+DPTR
MOVSEG8,A
MOVA,B
MOVC A,@A+DPTR
MOVSEG7,A
MOVSEG3,#40H
MOVSEG6,#40H
RET
STOP:
MOV STOP_MS,#0
MOV STOP_S,#0
MOV STOP_M,#0
ACALL STOP_CONV
ACALL SEG_DISP
ACALL KEYBOARD
CJNEA,#07H,STOP
JMP LOOP2
LOOP2:
ACALL KEYBOARD
CJNEA,#07H,LOOP3
JMP PAUSE1
LOOP3: ACALL STOP_CONV
ACALL SEG_DISP
LCALL DLY10MS
INC STOP_MS
MOV A,STOP_MS
CJNEA,#100,LOOP2 ;是否1s 到了
MOV STOP_MS,#0 ;里秒数清零
INC STOP_S ;秒计数加1
MOV A,STOP_S
CJNEA,#60,LOOP2 ;是否1min到了
INC STOP_M ;分计数加1
MOV STOP_S,#0
MOV A,STOP_M
CJNEA,#60,LOOP2 ;是否1h到了
MOV STOP_M,#0
PAUSE1:
ACALL STOP_CONV
ACALL SEG_DISP
ACALL KEYBOARD
CJNEA,#03H,PP1
JMP DEAD
PP1: CJNEA,#07H,PP2
JMP LOOP2
PP2: CJNEA,#0FH,PAUSE1
JMP STOP
DEAD:
ACALL CONV
ACALL SEG_DISP
RET
MUSIC:
JMP START
ORG 001BH
JMP EXT0
START:
MOV TMOD,#00010000B
MOV IE,#8AH
MOV R4,#0
MOV A,#80H
MOV DPTR,#9FFFH
MOVX @DPTR,A
MOV DPTR,#MUSICTAB
LOOOP:
MOV A,R4
MOVC A,@A+DPTR
MOV R1,A
INC R4
ACALL WATER
MOV A,R4
MOVC A,@A+DPTR
MOV R0,A
ORL A,R1
JZ NEXT0 ;全0 为休止符
MOV A,R0
ANL A,R1
CJNEA,#0FFH,NNEXT ;全1 表示乐曲
结束
JMP LO1 ;循环演奏
NNEXT:
MOV TH1,R1
MOV TL1,R0
SETB TR1
JMP NEXT1
NEXT0: ;关闭定时器,
停止发音
CLRTR1
SETB FMQ
NEXT1:
INC R4
MOV A,R4
MOVC A,@A+DPTR
MOV R2,A
LOOP1:
ACALL DELAY_1
DJNZR2,LOOP1
INC R4
JMP LOOOP
EXT0:
MOV TH1,R1
MOV TL1,R0
CPL P1.6
RETI
DELAY_1:
MOV R7,#02
DD2:MOV R6,#128
DD3:MOV R5,#248
DJNZR5,$
DJNZR6,DD3
DJNZR7,DD2
RET
MUSICTAB:
;
DB0FDH,0C6H,02H,0FEH,02H,02H
DB0FEH,2AH,04H,0FEH,02H,02H
DB0FEH,2AH,04H,0FEH,84H,04H
DB0FEH,02H,02H
DB00H,00H,04H
DB0FDH,08H,02H,0FDH,08H,02H
DB0FDH,0C6H,03H,0FDH,80H,02H
DB0FDH,0C6H,04H,0FEH,2AH,04H
DB0FDH,80H,04
DB00H,00H,04H
DB0FDH,08H,02H,0FDH,08H,02H
DB0FDH,30H,03H,0FDH,08H,02H
DB0FDH,30H,02H,0FEH,2AH,03H
DB0FDH,08H,04H
DB00H,00H,04H
DB0FEH,2AH,02H,0FEH,2AH,02H
DB0FEH,2AH,03H,0FEH,02H,03H
DB0FDH,30H,02H,0FDH,30H,04H
DB0FEH,02H,04H,0FEH,02H,04H
DB0FFH,0FFH
LO1:
CLRTR1
SETB FMQ ;停止闹铃
RET
WATER:
MOV A,TEMP
MOV DPTR,#8FFFH
MOVX @DPTR,A
RL A
MOV TEMP,A
MOV DPTR,#MUSICTAB
RET
DLY400US:
MOVR5,#2
D100:
MOVR4,#100
DJNZ R4,$
DJNZ R5,D100
RET
DLY10MS:MOV R5,#30
DD100: MOVR4,#150
DJNZ R4,$
DJNZ R5,DD100
RET
BZ:
MOV R6,#250
B1:
ACALL DEX
CPL FMQ
DJNZR6,B1
MOV R5,#30
ACALL DELAY
RET
DELAY:
MOV R4,#04H
DL0:MOVR5,#0E9H
DL1:NOP
DJNZR5,DL1
DJNZR4,DL0
RET
DEX:
MOV R4,#200
DJNZR4,$
RET
SEGTAB: DB 3FH,06H,5BH,4FH,66H
DB 6DH,7DH,07H,7FH,6FH
MONTHTAB:
DB 0,32,29,32,31,32,31
DB 32,32,31,32,31,32
RUNTAB:
DB 0,32,30,32,31,32,31
DB 32,32,31,32,31,32
END