吉林建筑工程学院
电气与电子信息工程学院
《单片机原理及应用》课程设计报告
设计题目: 电子计时器综合系统设计
专业班级: 电子信息科学与技术092
学生姓名:
学 号:
指导教师:
设计时间: 2012.8.27-2012.9.7
目录
第1章 绪论························································1
1.1 课程设计目的···············································1
1.2 课程设计内容···············································1
1.3 课程设计要求···············································1
1.4 电子时钟的简单介绍·········································1
第2章 控制系统的硬件设计·········································4
2.1 单片机型号的选择···········································2
2.2 89C51单片机介绍············································2
2.3 振荡电路···················································4
2.4 复位电路···················································4
2.5 键盘电路···················································4
2.6 数码管显示工作原理·········································5
2.7 整个电路原理图·············································5
第3章 控制系统的软件设计··········································6
3.1 程序流程图·················································6
3.2 程序设计···················································7
第4章 软件仿真···················································8
4.1 Proteus软件介绍············································8
4.2 仿真结果···················································8
第5章 心得体会·················································10
参考文献···························································11
附录······························································12
第1章 绪论
1.1 课程设计目的:
通过《单片机原理与应用》课程设计,掌握单片机及其扩展系统设计的方法和设计原则及相应的硬件调试的方法。进一步加深单片机及其扩展系统设计和应用的理解。
1.2 课程设计内容:
电子计时器综合系统设计
①有6位数码管显示,能按照分秒进制显示时间;
② 能正确手动复位;
③有上电指示灯;
1.3 课程设计要求:
1)独立设计原理图及相应的硬件电路。
2)针对选择的设计题目,设计系统软件。软件要做到:操作方便,实用性强,稳定可靠。
3)设计说明书格式规范,层次合理,重点突出。并附上设计原理图及相应的源程序。
1.4 电子计时器的简单介绍
该电子计时器由AT89C51,BUTTON,八段数码管等构成,采用晶振电路作为驱动电路,有延时程序和循环程序产生的一秒定时,达到时分秒的计时,六十秒为一分钟,六十分钟为一小时,满二十四小时为一天。有两个按键分别控制小时和分钟,当按下控制分钟的按键时,分钟加一,同理按控制小时的按键时,小时加一。
第2章 控制系统的硬件设计
2.1 单片机型号的选择
通过对多种单片机性能的分析,最终认为AT89C51时最理想的电子时钟开发芯片。AT89C51 提供以下标准功能:4k 字节Flash 闪速存储器,128字节内部RAM,32 个I/O 口线,两个16位定时/计数器,一个5向量两级中断结构,一个全双工串行通信口,片内振荡器及时钟电路。同时,AT89C51可降至0Hz的静态逻辑操作,并支持两种软件可选的节电工作模式。空闲方式停止CPU的工作,但允许RAM,定时/计数器,串行通信口及中断系统继续工作。掉电方式保存RAM中的内容,但振荡器停止工作并禁止其它所有部件工作直到下一个硬件复位。
2.2 AT89C51单片机介绍
图1 AT89C51
VCC:电源
GND:接地
P0口:P0口为一个8位漏极开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定能够以为数据/地址的第八位。在FLASH编程时,P0输出原码,此时P0外部必须被拉高。
P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部上拉为低电平时,P1口作为第八位地址接收。
P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写1时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的原因。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高8位。在给出地址1时,它利用内部上拉优势,当对外部8位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入1时,它们被内部上拉位高电平,并用作输入。作为输入,由于外部上拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。
RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
ALE/PROG:当访问外部存储器时 ,地址锁存允许的输出电平用于锁存地址的低位字节。在FLASH编程期间,次引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如果想禁止ALE的输出可在SFR8EH地址上置0.此时,ALE只有在执行MOVX,MOVC指令时ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置为无效。
/PSEN:外部程序存储器的读选通信号,低电平有效。在由外部程序存储器取值期间,每个机器两次/PSEN有效,但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
/EA/VPP:/EA为该引脚的第一功能,即外部程序存储器访问控制允许端。当/EA为高电平时,在PC值不超过0FFFFH时,单片机读片内程序存储器(4KB)中的程序;当PC值超出时,将自动转向片外60KB程序存储器空间中的程序。当/EA引脚为低电平时,只读取外部程序存储器中的内容。VPP为该引脚的第二功能,即在对片内FLASH进行编程时,VPP引脚接入编程电压。
2.3 振荡电路
本次设计采用内部振荡电路,瓷片电容采用33pf,晶振采用12MHZ。电路连接如图2所示
图2 震荡电路
2.4 复位电路
单片机系统的复位电路在这里采用的是上电复位电路的形式,其中电阻R1采用10KΩ的阻值,电容采用电容值为100u的电容。电路连接如图4所示
图3 复位电路
2.5 键盘电路
图4 键盘电路
2.6 数码管显示工作原理
数码管是一个把多个LED显示段集成在一起的显示设备。有两种类型,一种是共阳型,一种是共阴型。共阳型就是把多个LED显示段的阳极接在一起,又称为公共端。共阴型就是把多个LED显示段的阴极接在一起,即为公共商。阳极即为二极管的正极,又称为正极,阴极即为二极管的负极,又称为负极。通常的数码管又分为8段,即8个LED显示段,这是为工程应用方便设计的,称为A、B、C、D、E、F、G、DP,其中DP是小数点位段。而多位数码管,除某一位的公共端会连接在一起,不同位的数码管的相同端也会连接在一起。即,所有的A段都会连在一起,其它的段也是如此,这是最实际的用法。数码管显示方法可分为静态显示和动态显示两种。静态显示就是数码管的8段输入及公共端电平一直有效。动态显示的原理是,各个数码管的相同段连接在一起,共同占用8位段引管线;每位数码管的阳极连在一起组成公共端。利用人眼的视觉暂留性,依次给出各个数码管公共端加有效信号,早同时给出该数码管加有效的数据信号,当全段扫描速度大于视觉暂留速度时,显示就会清晰显示出来。
2.7 整个电路原理图
图6 电路原理图
第3章 控制系统的软件设计
3.1 程序流程图
本系统的软件系统主要可分为主程序、定时计数中断程序、时间调整程序、延时程序四大模块。
主程序流程图:
3.2 程序设计
见附录
第4章 软件仿真
4.1 Proteus软件介绍
Proteus软件是英国Labcenter electronics公司出版的EDA工具软件,是目前最好的模拟单片机外围器件的工具。可以仿真51系列、AVR、PIC等常用的MCU及其外围电路(如LCD、RAM、ROM、键盘、马达、LED、AD/DA,部分SPI器件,部分IIC器件等)。Proteus是世界上著名的EDA工具,从原理图布图、代码调试到单片机与外围设备协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。是目前世界上唯一将电路仿真软件PCB设计软件和虚拟模型仿真软件三合一的设计平台。Proteus具有原理布图、PCB自动或人工布线、SPICE电路仿真的功能。
4.2 仿真结果
图7时钟仿真图
图8秒表仿真结果
第5章 心得体会
课程设计是对课程的实践与总结,只要做了就会有收获。在这次设计中我加深了程序的阅读能力、程序的灵活调用、单片机的设计制作调试方法。为了能顺利的完成这次的课程设计我找了很多资料也因此知道了不少课本上没深入介绍的东西,提高了我的思维空间,拓宽了我的知识面,加深了对单片机课程的兴趣。最主要的是加强了动手的能力。遇到问题是先思考,解决不了再查资料,实在弄不出来就问老师和同学们,毕竟不耻下问是中华名族的优良美德。只有如此才能不断进步。
通过这次课程设计我了解到学好一门汇编语言,最根本的应该是了解所能接触到的程序中最关键的是哪些,实际的应用编写更是非常重要,所以我们一定要自己动手试一下,尝试编写程序。因为做一个旁观者事不能够学到东西的。
此外在此次设计中我对此次设计的内容有一下感触,第一,由于此次设计的过程中设计秒表和时钟的显示,即在一个数码管上显示两种变量,必须确定以下两点:1、必须仔细的核对每一个变量的名字,我曾经在核对变量的名字上面花了很大的力气,由于变量的名字错了,软件编译时很少能检查出,因此仿真时往往不容易发现。
2、要每个子程序的调试,这样才能确认某一个部分是正确的,这样才有继续往下做的信心和勇气。
参考文献
1.《单片机原理及应用》/张毅刚 彭喜元 彭宇主编.高等教育出版社,20##年5月第二版
2.《单片机原理及应用》/张毅刚.高等教育出版社,2004
3.《MCS-51系列单片机实用接口技术》/李华主编.北京:北京航空航天大学出版社,1993.8
4.《单片机C语言轻松入门》周坚编 北京航空航天大学出版社
5.《单片机人机接口实例》公茂法编著,北京航空航天大学出版社
6.《单片机应用系统设计与实践》 陈景初,北京:北京航空航天大学出版社
附录
DISBEG EQU 30H ;显示单元首地址
TIMCON EQU 2FH ;存放报时次数
ORG 0000H ;程序开始
LJMP MAIN
ORG 0003H ;关外中断0
RETI
ORG 000BH ;定时器T0中断程序入口
LJMP INTT0 ;跳至INTTO执行
ORG 0013H ;关中断1
RETI
ORG 001BH ;定时器T1中断程序入口
LJMP INTT1 ;跳至INTT1执行
ORG 0023H ;关串行中断
RETI
TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,88H,0BFH
I_TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,0C6H,0BFH,88H
DLY1M: MOV R6,#14H ;1毫秒延时
DL_LOOP: MOV R7,#19H
DL_LOOP1: DJNZ R7,DL_LOOP1
DJNZ R6,DL_LOOP
RET
DLY20M:
LCALL D_II_PLAY
LCALL D_II_PLAY
LCALL D_II_PLAY
RET
DL_LOOPS: LCALL DL05S
LCALL DL05S
RET
DL05S: MOV R3,#20H ;8毫秒*32=0.196秒
DL05S1: LCALL D_II_PLAY
DJNZ R3,DL05S1
RET
CTIME: MOV A,#10H
MOV B,79H
MUL AB
ADD A,78H
MOV TIMCON,A
CLOOP: LCALL DLY20M
LCALL DL_LOOPS
LCALL DL_LOOPS
LCALL DL_LOOPS
DJNZ TIMCON,CLOOP
CLR 08H ;清整点报时标志
AJMP MLOOP1
MAIN: MOV R0,#00H ;清00H-7FH内存单元
MOV R7,#80H ;
MLOOP: MOV @R0,#00H ;
INC R0 ;
DJNZ R7,MLOOP ;
MOV 20H,#00H ;清20H(标志用)
MOV 7AH,#0AH ;放入"熄灭符"数据
MOV TMOD,#11H ;设T0、T1为16位定时器
MOV TL0,#0B0H ;50MS定时初值(T0计时用)
MOV TH0,#3CH ;50MS定时初值
MOV TL1,#0B0H ;50MS定时初值(T1闪烁定时用)
MOV TH1,#3CH ;50MS定时初值
SETB EA ;总中断开放
SETB ET0 ;允许T0中断
SETB TR0 ;开启T0定时器
MOV R4,#14H ;1秒定时用计数值(50MS×20)
MOV DISBEG,#70H ;显示单元为70-75H
MLOOP1: LCALL D_II_PLAY ;调用显示子程序
JNB P1.0,T_SETSC
JNB P1.1,DLY5 ;秒表功能,P1.1按键调时时作减1加
JNB P1.2,FUNBT ;秒表STOP,PUSE,CLR
JB 08H, CTIME
AJMP MLOOP1 ;P1.0口为1时跳回MLOOP1
FUNBT: LJMP DLY6
TSET: LCALL DLY20M
JB P1.3,MLOOP1 ;
TS_LOOP: JNB P1.3,TS_LOOP ;等待键释放
MINCHG: SETB EA
LCALL D_II_PLAY
JNB P1.2,DLY1 ;分加1
JNB P1.0,DLY3 ;分减1
JNB P1.3,DLY ;进入时调整
AJMP MINCHG
CLRBELL:
AJMP MLOOP1
DLY: LCALL DLY20M ;消抖
JB P1.3, MINCHG
T_SETSC: LJMP R_SETTIM ;转到时间调整程序R_SETTIM
DLY1: LCALL DLY20M ;消抖
JB P1.2, MINCHG
DLY2: LCALL D_II_PLAY ;等键 释放
JNB P1.2, DLY2
CLR EA
CJNE A,#60H,ADD_M ;
ADD_M: JC MINCHG ;小于60分时返回
ACALL CLR_H ;大于或等于60分时分计时单元清0
AJMP MINCHG
DLY3 : LCALL DLY20M ;消抖
JB P1.0, MINCHG
DLY4: LCALL D_II_PLAY ;等键 释放
JNB P1.0, DLY4
CLR EA
MOV R0,#53H ;
LJMP MINCHG
DLY5: LCALL DLY20M
JB P1.1,T_MLOOP1
JNB P1.1,$
CPL 03H
JNB 03H,DIS_SET
MOV DISBEG,#60H ;显示秒表数据单元
MOV 60H,#00H
MOV 61H,#00H
MOV 62H,#00H
MOV 63H,#00H
MOV 64H,#00H
MOV 65H,#00H
MOV TL1,#0F0H ;10MS定时初值()
MOV TH1,#0D8H ;10MS定时初值
SETB TR1
SETB ET1
T_MLOOP1: LJMP MLOOP1
DIS_SET: MOV DISBEG,#70H ;显示时钟数据单元
CLR ET1
CLR TR1
T_MLOOP11: LJMP MLOOP1
DLY6: LCALL DLY20M
JB P1.2,T_MLOOP11
T_EST11: JNB P1.2,T_EST11
CLR ET1
CLR TR1
T_EST22: JNB P1.1,DLY5
JB P1.2,T_EST21
LCALL DLY20M
JB P1.2,T_EST22
T_EST55: JNB P1.2,T_EST51
MOV 60H,#00H
MOV 61H,#00H
MOV 62H,#00H
MOV 63H,#00H
MOV 64H,#00H
MOV 65H,#00H
T_EST33: JNB P1.1,DLY5
JB P1.2,T_EST31
LCALL DLY20M
JB P1.2,T_EST33
T_EST44: JNB P1.2,T_EST41
SETB ET1
SETB TR1
AJMP MLOOP1
T_EST411: LCALL D_II_PLAY
AJMP T_EST11
T_EST21: LCALL D_II_PLAY
AJMP T_EST22
T_EST31: LCALL D_II_PLAY
AJMP T_EST33
T_EST41: LCALL D_II_PLAY
AJMP T_EST44
T_EST51: LCALL D_II_PLAY
AJMP T_EST55
INTT0: PUSH ACC ;累加器入栈保护
PUSH PSW ;状态字入栈保护
CLR ET0 ;关T0中断允许
CLR TR0 ;关闭定时器T0
MOV A,#0B7H ;中断响应时间同步修正
ADD A,TL0 ;低8位初值修正
MOV TL0,A ;重装初值(低8位修正值)
MOV A,#3CH ;高8位初值修正
ADDC A,TH0
MOV TH0,A ;重装初值(高8位修正值)
SETB TR0 ;开启定时器T0
DJNZ R4, I_INT0 ;20次中断未到中断退出
A_DDS: MOV R4,#14H ;20次中断到(1秒)重赋初值
CPL 07H ;闹铃时间隔呜叫用
MOV R0,#71H ;指向秒计时单元(71H-72H)
ACALL ADD_1 ;调用加1程序(加1秒操作)
MOV A,R3 CLR C
CJNE A,#60H,A_DDM
A_DDM: JC I_INT0 ;小于60秒时中断退出
ACALL CLR_H
MOV R0,#77H ;指向分计时单元(76H-77H)
ACALL ADD_1 ;分计时单元加1分钟
MOV A,R3 ;分数据放入A
CLR C ;清进位标志
CJNE A,#60H,A_DDH ;
A_DDH: JC I_INT0 ;小于60分时中断退出
ACALL CLR_H ;大于或等于60分时分计时单元清0
LCALL DLY20M ;正点报时
SETB 08H
MOV R0,#79H ;指向小时计时单元(78H-79H)
ACALL ADD_1 ;小时计时单元加1小时
MOV A,R3 ;时数据放入A
CLR C ;清进位标志
CJNE A,#24H,RSTART ;
RSTART: JC I_INT0 ;小于24小时中断退出
ACALL CLR_H ;大于或等于24小时小时计时单元清0
I_INT0: MOV 72H,76H ;中断退出时将分、时计时单元数据移
MOV 73H,77H ;入对应显示单元
MOV 74H,78H ;
MOV 75H,79H ;
POP PSW ;恢复状态字(出栈)
POP ACC ;恢复累加器
SETB ET0 ;开放T0中断
RETI ;中断返回
INTT1: PUSH ACC ;中断现场保护
PUSH PSW
JB 03H, R_ADDS ;=1时秒表
MOV TL1, #0B0H ;装定时器T1定时初值
MOV TH1, #3CH
DJNZ R2,I_INT1
MOV R2,#06H ;重装0.3秒定时用初值
CPL 02H ;0.3秒定时到对闪烁标志取反
JB 02H,FLASH0 ;02H位为1时显示单元"熄灭"
MOV 72H,76H ;02H位为0时正常显示
MOV 73H,77H
MOV 74H,78H
MOV 75H,79H
I_INT1: POP PSW ;恢复现场
POP ACC
RETI ;中断退出
FLASH0: JB 01H,FLASH1 ;01H位为1时,转小时熄灭控制
MOV 72H,7AH ;01H位为0时,"熄灭符"数据放入分
MOV 73H,7AH ;显示单元(72H-73H),将不显示分数
MOV 74H,78H
MOV 75H,79H
AJMP I_INT1 ;转中断退出
FLASH1: MOV 72H,76H ;01H位为1时,"熄灭符"数据放入小时MOV 73H,77H
MOV 74H,7AH
MOV 75H,7AH
AJMP I_INT1 ;转中断退出
R_ADDS : CLR TR1
MOV A,#0F7H ;中断响应时间同步修正,重装初值(10ms)
ADD A,TL1 ;低8位初值修正
MOV TL1,A ;重装初值(低8位修正值)
MOV A,#0D8H ;高8位初值修正
ADDC A,TH1
MOV TH1,A ;重装初值(高8位修正值)
SETB TR1 ;开启定时器T0
MOV R0,#61H ;指向秒计时单元(71H-72H)
ACALL ADD_1 ;调用加1程序(加1秒操作)
CLR C
MOV A,R3
JZ R_ADDM ;加1后为00,C=0
AJMP I_INT01 ;加1后不为00,C=1
R_ADDM: ACALL CLR_H
MOV R0,#63H ;指向分计时单元(76H-77H)
ACALL ADD_1 ;分计时单元加1分钟
MOV A,R3 ;分数据放入A
CLR C ;清进位标志
CJNE A,#60H,R_ADDH
R_ADDH: JC I_INT01 ;小于60分时中断退出
LCALL CLR_H ;大于或等于60分时分计时单元清0
MOV R0,#65H ;指向小时计时单元(78H-79H)
ACALL ADD_1 ;小时计时单元加1小时
I_INT01: POP PSW ;恢复状态字(出栈)
POP ACC ;恢复累加器
RETI ;中断返回 ;
ADD_1: MOV A,@R0 ;取当前计时单元数据到A
DEC R0 ;指向前一地址
SWAP A ;A中数据高四位与低四位交换
ORL A,@R0 ;前一地址中数据放入A中低四位
ADD A,#01H ;A加1操作
DA A ;十进制调整
MOV R3,A ;移入R3寄存器
ANL A,#0FH ;高四位变0
MOV @R0,A ;放回前一地址单元
MOV A,R3 ;取回R3中暂存数据
INC R0 ;指向当前地址单元
SWAP A ;A中数据高四位与低四位交换
ANL A,#0FH ;高四位变0
MOV @R0,A ;数据放入当削地址单元中
RET ;子程序返回
SUB_M: MOV A,@R0 ;取当前计时单元数据到A
DEC R0 ;指向前一地址
SWAP A ;A中数据高四位与低四位交换
ORL A,@R0 ;前一地址中数据放入A中低四位
JZ SUB_M1
DEC A ;A减1操作
SUB_M11: MOV 3,A ;移入R3寄存器
ANL A,#0FH ;高四位变0
CLR C ;清进位标志
SUBB A,#0AH
SUB_M111: JC SUB_M110
MOV @R0,#09H ;大于等于0AH,为9
SUB_M10: MOV A,R3 ;取回R3中暂存数据
INC R0 ;指向当前地址单元
SWAP A ;A中数据高四位与低四位交换
ANL A,#0FH ;高四位变0
MOV @R0,A ;数据放入当削地址单元中
RET ;子程序返回
SUB_M1: MOV A,#59H
AJMP SUB_M11
SUB_M110: MOV A,R3 ;移入R3寄存器
ANL A,#0FH ;高四位变0
MOV @R0,A
AJMP SUB_M10
SUB_H: MOV A,@R0 ;取当前计时单元数据到A
DEC R0 ;指向前一地址
SWAP A ;A中数据高四位与低四位交换
ORL A,@R0 ;前一地址中数据放入A中低四位
JZ SUB_H1 ;00减1为23(小时)
DEC A ;A减1操作
SUB_H11: MOV R3,A ;移入R3寄存器
ANL A,#0FH ;高四位变0
CLR C ;清进位标志
SUBB A,#0AH ;时个位大于9为9
SUB_H111: JC SUB_H110
MOV @R0,#09H ;大于等于0AH,为9
SUB_H10: MOV A,R3 ;取回R3中暂存数据
INC R0 ;指向当前地址单元
SWAP A ;A中数据高四位与低四位交换
ANL A,#0FH ;高四位变0
MOV @R0,A ;时十位数数据放入
RET ;子程序返回
SUB_H1: MOV A,#23H
AJMP SUB_H11
SUB_H110: MOV A,R3 ;时个位小于0A不处理
ANL A,#0FH ;高四位变0
MOV @R0,A ;个位移入
AJMP SUB_H10
CLR_H: CLR A ;清累加器
MOV @R0,A ;清当前地址单元
DEC R0 ;指向前一地址
MOV @R0,A ;前一地址单元清0
RET ;子程序返回
R_SETTIM: CLR ET0
CLR TR0 ;关闭定时器T0
LCALL DL_LOOPS ;调用1秒延时程序
LCALL DLY20M ;消抖
JB P1.0,SLEEP
MOV R2,#06H ;进入调时状态,赋闪烁定时初值
MOV 70H,#00H ;调时时秒单元为00 秒
MOV 71H,#00H
SETB ET1 ;允许T1中断
SETB TR1 ;开启定时器T1
SET_2: JNB P1.0,SET_1 ;P1.0口为0(键未释放),等待
SETB 00H ;键释放,分调整闪烁标志置1
SET_4: JB P1.0,SET_3 ;等待键按下
LCALL DL05S ;有键按下,延时0.5秒
LCALL DLY20M ;消抖
JNB P1.0,R_SETHH
MOV R0,#77H ;按下时间小于0.5秒加1分钟操作
LCALL ADD_1 ;调用加1子程序
MOV A,R3 ;取调整单元数据
CLR C ;清进位标志
CJNE A,#60H,SET_LOOP ;调整单元数据与60比较
SET_LOOP: JC SET_4 ;调整单元数据小于60转SET_4循环
LCALL CLR_H ;调整单元数据大于或等于60时清0
CLR C ;清进位标志
AJMP SET_4 ;跳转到SET_4循环
SLEEP: SETB ET0 ;省电(LED不显示)状态。开T0中断
SETB TR0 ;开启T0定时器(开时钟)
SET_LOOP1: JB P1.0,SET_LOOP1 ;无按键按下,等待。
LCALL DLY20M ;消抖
JB P1.0,SET_LOOP1
SET_LOOP2: JNB P1.0,SET_LOOP2 ;等待键释放
LJMP MLOOP1 ;返回主程序(LED数据显示亮)
R_SETHH: CLR 00H
SETB 01H ;小时调整标志置1
SET_LOOP3: JNB P1.0,SET_5 ;等待键释放
SET_6: JB P1.0,SET_7 ;等待按键按下
LCALL DL05S ;有键按下延时0.5秒
LCALL DLY20M ;消抖
JNB P1.0,STOP ;按下时间大于0.5秒退出时间调整
MOV R0,#79H ;按下时间小于0.5秒加1小时操作
LCALL ADD_1 ;调加1子程序
MOV A,R3
CLR C
CJNE A,#24H,C_YHH ;计时单元数据与24比较
C_YHH: JC SET_6 ;小于24转SET_6循环
LCALL CLR_H ;大于或等于24时清0操作
AJMP SET_6 ;跳转到SET_6循环
STOP: JNB P1.0,STOP1 ;调时退出程序。等待键释放
LCALL DLY20M ;消抖
JNB P1.0,STOP ;是抖动,返回STOP再等待
CLR 01H ;清调小时标志
CLR 00H ;清调分标志
CLR 02H ;清闪烁标志
CLR TR1 ;关闭定时器T1
CLR ET1 ;关定时器T1中断
SETB TR0 ;开启定时器T0
SETB ET0 ;开定时器T0中断(计时开始)
LJMP MLOOP1 ;跳回主程序
SET_1: LCALL D_II_PLAY
AJMP SET_2 ;防止键按下时无时钟显示
SET_3: LCALL D_II_PLAY
JNB P1.1, DLY7 ;减1分操作
AJMP SET_4 ;调分等待
SET_5: LCALL D_II_PLAY
AJMP SET_LOOP3 ;防止键按下时无时钟显示
SET_7: LCALL D_II_PLAY
JNB P1.1, DLY7B ;小时减1操作
AJMP SET_6 ;调时等待
STOP1: LCALL D_II_PLAY
AJMP STOP ;防止键按下时无时钟显示
DLY7: LCALL DLY20M ;消抖
JB P1.1,SET_41 ;干扰,返回调分等待
DLY7_M: JNB P1.1,DLY7_M ;等待键放开
MOV R0,#77H
LCALL SUB_M ;分减1程序
LJMP SET_4 ;返回调分等待
;
SET_41: LJMP SET_4 ;
DLY7B: LCALL DLY20M ;消抖
JB P1.1,SET_61 ; 干扰,返回调时等待
DLY7_H: JNB P1.1,DLY7_H ; 等待键放开
MOV R0,#79H
LCALL SUB_H ; 时减1程序
LJMP SET_6 ; 返回调时等待
SET_61: LJMP SET_6
D_II_PLAY: MOV R1,DISBEG ;指向显示数据首址
MOV R5,#0FEH ;扫描控制字初值
PLAY: MOV A,R5 ;扫描字放入A
MOV P2,A ;从P2口输出
MOV A,@R1 ;取显示数据到A
MOV DPTR,#TAB ;取段码表地址
MOVC A,@A+DPTR ;查显示数据对应段码
MOV P0,A ;段码放入P1口
MOV A,R5
JB ACC.2,D_LOOP ;小数点处理
CLR P0.7 ;
D_LOOP: JB ACC.4,D_LOOP1 ;小数点处理
CLR P0.7 ;
D_LOOP1: LCALL DLY1M ;显示1MS
INC R1 ;指向下一地址
MOV A,R5 ;扫描控制字放入A
JNB ACC.5,CLOSE ;ACC.5=0时一次显示结束
RL A ;A中数据循环左移
MOV R5,A ;放回R5内
MOV P0,#0FFH
AJMP PLAY ;跳回PLAY循环
CLOSE: MOV P2,#0FFH ;一次显示结束,P2口复位
MOV P0,#0FFH ;P0口复位
RET ;子程序返回
SD_II_PLAY: MOV R1,DISBEG
MOV R5,#0FEH ;扫描控制字初值
I_PLAY: MOV A,R5 ;扫描字放入A
MOV P2,A ;从P2口输出
MOV A,@R1 ;取显示数据到A
MOV DPTR,#I_TAB ;取段码表地址
MOVC A,@A+DPTR ;查显示数据对应段码
MOV P0,A ;段码放入P1口
MOV A,R5
LCALL DLY1M ;显示1MS
INC R1 ;指向下一地址
MOV A,R5 ;扫描控制字放入A
JNB ACC.5,FLSH ;ACC.5=0时一次显示结束
RL A ;A中数据循环左移
MOV R5,A ;放回R5内
AJMP I_PLAY ;跳回PLAY循环
FLSH: MOV P2,#0FFH ;一次显示结束,P2口复位
MOV P0,#0FFH ;P0口复位
RET ;子程序返回
END