最新单片机汇编语言的数字钟课程设计报告-
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
单片微型计算机课程设计报告多功能电子数字钟
姓名许伟敏
学号 060301021124
1
班级电气二班
指导教师林卫
2009-06-25
目录
一:概述 (1
二:设计基本原理简介 (2
三:设计要求及说明 (3
四:整体设计方案 (4
系统硬件电路设计 4
系统软件总流程设计 5
模块划分及分析 6
五:单模块流程设计 (8
各模块设计概述、流程图 8 模块源程序集合及注释 13
六:单模块软件测试 (23
七:系统检测调试 (24
硬件电路调试
软件部分烧写调试
八:系统优化及拓展 (26
九:心得体会 (28
单片微型计算机课程设计基于汇编语言的电子数字钟概述
课程设计流程图↑
一、概述
课程设计题目:电子数字钟
应用知识简介:
● 51单片机
单片机又称单片微控制器,它不是完成某一个逻辑功能
的芯片,而是把一个计算机系统集成到一个芯片上。
作为嵌入式系统控制核心的单片机具有其体积小、功能全、性价比高等诸多优点。
51系列单片机是国内目前应用最广泛的单片机之一,随着嵌入式系统、片上系统等概念的提出和普遍接受及应用,51系列单片机的发展又进入了一个新的阶段。
在今后很长一段时间内51系列单片机仍将占据嵌入式系统产品的中低端市场。
● 汇编语言
汇编语言是一种面向机器的计算机低级编程语言,通常
是为特定的计算机或系列计算机专门设计的。
汇编语言保持了机器语言的优点,具有直接和简捷的特点,其代码具有效
率高实时性强等优点。
但是对于复杂的运算或大型程序,用汇编语言编写将非常耗时。
汇编语言可以与高级语言配合使用,应用十分广泛。
● ISP
ISP (In-System Programming 在系统可编程,
是当今流行的单片机编程模式,指电路板上的空白元器
件可以编程写入最终用户代码,而不需要从电路板上取
下元器件。
已经编程的器件也可以用ISP 方式擦除或再
编程。
本次课程设计便使用ISP 方式,直接将编写好的
程序下载到连接好的单片机中进行调试。
选题目的及设计思想简介:
课程设计是一次难得的对所学的知识进行实践的机会,我希望通过课程设计独立设计一个简
单的系统从而达到强化课本知识并灵活运用的目的。
电子数字钟是日常生活钟随处可见的简单系统。
对电子数字钟的设计比较容易联系实际并进行拓展, 在设计中我将力求尽可能跳出课本的样板,从现实生活中寻找设计原型和设计思路,争取有所突破。
如图所示便是我本次课程设计流程图,设计的整个过程运用自顶向下分析、自底向上实现的
办法进行设计,借鉴在软件工程中学习到的软件设计流程和规范来完成系统设计并在设计过程中体会软件设计的流程。
二、设计基本原理简介
数字钟的设计首先要保证其走时尽可能准确,其次再根据人们日常的使用习惯来设定其附加功能。
在设计中利用单片机定时计数器来完成走时并用两组输出口控制数码管来显示;通过编程向某一输出口输出方波实现报时及闹铃;利用输入端口外接各种开关来完成对走时及显示的控制(如预置时间等。
在设计中需要用到许多技巧。
以下为我在学习单片机课程中总结的一些设计思想或方法:
● 占空比概念在设计中的运用
如图所示的一串方波序列,导通时间同周期的比值
即占空比。
在用单片机控制对多个数码管的扫描显示
中,数码管接收到的电压可以看成是一串方波序列,占
空比控制了数码管的亮度。
实际上对显示延时时间的调
节就是调节数码管电压的占空比,当占空比大于一定数
值的时候数码管可以显示,实验证明占空比在0.1时仍可以使数码管清晰显示。
利用这个概念可以比较直观地理解显示延时的调节。
● CPU的分时复用
单片机只有一个CPU,因此在一个时间内只能执行一条语句,要使单片机同时控制多个外部元件(比如扬声器和数码管就必须对单片机的CPU进行分时复用,让单片机在一小段时间内连续交替执行控制多个器件的语句,从表面上看,单片机便用一个CPU控制了多个元件。
本次课程设计中对整点报时和闹铃功能的实现便用到了这个概念。
● 单片机位寻址区的使用
单片机内部数据存储器由20H到2FH共有16个字节的位寻址区可以被作为程序执行过程中的状态参数,许多程序模块至于两个状态(比如闪烁与正常显示,报时与不报时等用位寻址区中的某一位来记录程序执行状态,在需要对状态进行判断的时
候十分方便并且节约空间,一个字节便可以判断八个状态,而非位寻址区的地址记录程序状态时可能需要先进行变换,增加了执行成本且容易出错。
● 检测开关时需要注意的问题
对于用各种开关控制程序执行状态的程序设计中,需要注意实时地进行开关的检测,以确保一旦有开关动作,程序状态立即随之改变。
此外,在用多个开关控制不同执行状态时,应注意设置开关检测的优先级以防止多个开关同时按下时出现错误。
● 系统资源分配与使用
单片机有许多资源是有限的不能滥用,比如定时计数器T,外部中断等,在设计一个多模块程序时,要注意先做一个整体规划,把稀缺资源用在最需要用的地方。
此外在有多个模块时,要注意模块间的数据传递,比如累加器A和进位标志C,在使用时要注意不能让前一个模块的数据对下一个模块产生不希望有的影响。
在模块间的数据传递比较多时最好用固定的内部数据存储器,以避免冲突发生错误。
三、设计要求及说明
㈠设计要求:
基于单片机电路,借鉴生活中常见的电子钟的功能,结合课本的要求使用汇编语言设计一个简单的电子钟系统。
要求使用简便,功能实用,错误少,有一定创新性。
㈡电子数字钟实现的主要功能:
①实现正常走时(秒→分→时→日→月→年进位
②能够预置时间和日期
③能够自动区分平闰年和大小月
④具有闹铃及设定闹铃时间功能
⑤具有整点报时功能
⑥具有生日提醒功能,能够预置生日时间
⑦在任何一种预置状态下,预置项目会闪烁显示
㈢其它设计说明
①优先级:预置>闹铃>报时>生日提醒>正常显示,即预置状态下闹铃、报时功
能及生日提醒功能都无效
②生日时间到五个数码管显示“HAPPY”
③生日显示状态下,按下中断INT0恢复正常显示且此后只有在下更改生日日期
或第二年生日显示才有效。
④正常显示状态下按下中断INT0进入预置状态,再按一次恢复。
⑤用数码管(K0,K1控制显示状态:00:时间,01:闹铃时间,10:日期,11:
生日时间且显示样板如下图所示:
⑥预置由拨码开关K2/K3/K4分别控制数码管12/34/56显示值,预置优先级:
LED34>LED12>LED56(相应数码管显示的项目,显示状态下才能预置
⑦整点报时声音为59分51、53、55、57秒的后半秒报四声低音, 59秒的后半秒
报一声高音
⑧闹铃每次响一分钟
⑨不论是预置状态还是正常走时状态均能够自动区分平闰年和大小月
⑩闹铃使能由拨码开关K5控制并实时显示
生日:6 月1 日生日,最后两位bd 为birthday 的缩写
闹铃:于早晨6 点10 分响,最后一位为一表示使能有效时间:12 点39 分45 秒日期:08 年2 月29 日
四、整体设计方案
㈠硬件电路设计
系统硬件电路根据系统功能可知,需要六个数码管,一个外部中断INT0,一个扬声器,由此结合单片机课程学习中对实验面板的了解,做
出如下电路:
如图,晶振频率12MHz,拨码开关数值由P0口读入;P2口的输出作为控制数码管的段控信号,经74LS573即8位数据锁存器接到数码管中。
数
码管采用共阴接法(图中未标示;P1.0-P1.5作为数码管的位控信号输
出端;开关W2经一个基本RS锁存器接入INT0,每按一次开关INTO取反一
次,按两次输入一个下降沿;扬声器由P1.6口控制。
㈡系统软件总流程设计
根据系统要求,设计出系统软件总流程图如下以T0作为正常走时的
计时器,T1作为预置状态下预置项目值自动跳升的控制计时器,INT0作为设定预置及清楚生日信号的控制按钮
设计使每一轮显示(即六个数码管都显示一次便检测一次开关使
软件系统总流程图↑
上图的“检测开关值→判断并显示→检测开关值” 的循环时间大约为10ms,即每隔10ms检测一次开关值,每个数码管接收到的电压信号占空比大约为1/7,确保数码管正常显示。
三个中断源中断程序执行时间每次均为几十毫秒,基本不影响主程序的显示及闹铃输出。
中断优先级T0>INT0>T1,首先确保走时尽可能的准确,其次由于T1的开启和关闭是由INT0进行控制的,故INT0优先级较高。
此外有优先级“预置显示>闹铃>整点报时>生日显示”,由于预置显示是人为控制的故优先级最高,考虑到日常生活中假如闹铃或整点报时被生日显示覆盖可能使影响到人们的日常生活故
设定生日优先级最低,且闹铃最多影响生日信号一分钟。
闹铃和整点报时不影响正常的时间等的显示。
㈢模块划分及分析
根据系统功能将模块划分如下
●ONE:初始化程序模块
进行资源分配(EQU,BIT伪指令,设定初值,各中断初始化
●TWO:开关检测模块
检测开关号,将要显示值送入显示缓存
●THREE:显示主程序
显示显示缓存中值,并进行生日,闹铃,报时判断
●SEVEN:显示生日祝福HAPPY程序
经显示主程序判断生日时间到要执行的显示HAPPY程序(其实可以认为是显示主程序的一部分
●EIGHT:闹铃及整点报时判断程序
判断是否闹铃或报时,如果是则CPLP1.6且忽略生日信号,反之则继续执行后续语句
●NINE:中断(TO计时程序
包含了秒→分→时→日→月→年进位以及判断大小月及平闰年以及生日标志设定
●TEN:中断预置程序
控制预置项目的自动加计数的延时时间, 并能判断大小月及平闰年
●ELEVEN:中断(INT0控制程序
控制预置的开/关及生日信号的清楚
●TEWLVE:延时程序
用于闪烁时的数码管亮度控制
模块划分中遇到的问题及解决:
模块划分的过程中遇到的问题不多,只做了一个比较大的修改。
刚开始设置模块的时候并没有设定显示缓存LED12、LED34、LED56而是将主显示模块THREE 分成四个部分分别实现对时间、日期、闹铃、生日的显示(编号FOUR、FIVE,SIX 便是删去的另外三个部分的程序名并通过检测开关决定跳转到哪一个部分去执行,但经过分析发现这样做极大地浪费了存储空间而设置显示缓存后,只需要在检测开关后将相应要显示的数据送入显示缓存并在主程序中对显示缓存进行显示即可,这样做大大地缩减了程序存储空间而程序可读性也增强了。
在程序编码完成后发现,没有必要将SEVEN 显示HAPPY程序同THREE显示主程序单列开来,TWELVE延时程序也并不是必要的,并且模块的划分还有些值得商榷的地方,本报告中的程序还可以通过模块划分的优化修改得更加精简一些。
五、单模块流程设计
在完成了系统总流程设计后,便进入到了系统设计中工作量最大的单模块流程设计。
由于系统模块划分虽然是系统设计的基础,但比较简单而且模块划分有多种方法,因此单模块的设计可以认为是本程序中最关键的部分。
单模块设计的好坏与否决定了系统功能能否被稳定地实现以及下一阶段调试程序的难度。
鉴于单模块设计的重要性,我在设计中并不急于对模块进行编码,而是反复论证模块的可行性和流程图,为下一阶段的工作做好准备,同时也能够尽早发现系统模块划分的错误,加以解决。
㈠各模块设计概述及模块流程图
①初始化模块(ONE
初始化模块包含了各中断的跳转语句、存储资源的分配、各存储器和寄存器的赋值以及中断及计时器的状态设置。
源程序中共使用了17字节的内部数据存储地址,其中包含3字节位寻址地址以便于进行位判断。
三字节的位寻址地址分配如下:
23H—月的存储地址,方便对大小月平闰年进行判断
另外一个位寻址字节00H地址拆开用做程序状态标志位
00H(bit,BS—生日标志位,到生日那天为1使程序转入生日显示段
01H(bit,SS—预置标志,以INT0控制其值,控制预置闪烁的实现
02H(bit,GS—闪烁标志,在预置标志有效时控制闪烁项目的亮和灭两状态03H(bit,FC—频率控制,在整点报时时控制产生低音还是高音
04H(bit,NB—忽略生日标志,控制预置及报时的优先级高于生日显示
05H(bit—控制生日信号的有效与否,其使用目的参见调试过程
源程序中使用了两个寄存器R1、R0,R1用于控制闪烁的间隔时间, R0用于显示延时。
在初始化模块中设定了中断的优先级、定时计数器的工作模式、并打开了定时计数器TO开始计时
其他资源分配项目参见源程序集合及注释。
初始化模块指令很大一部分都是伪指令,方便了后面程序的编写。
初始化模块流程图↑
②开关检测模块(TWO
开关检测模
块主要执行两个
任务:
⒈读取闹铃
使能控制拨码开
关K5的值并赋予闹铃使能相应值;
⒉读取显示
选择开关(K0,K1 的值并将要显示
的项目值送入显
示缓存LED12、LED34、LED56.当
K5为1时将A1H送
入RE,反之送入
A0H,其中A为“—”的字型码查表偏移量。
当显示生日日期时,将生日Birthday 的缩写“bd”的字型码送入显示缓存LED56。
开关检测模块的执行时间大约在40uS左右。
③显示主程序(THREE
显示主程序是程序中最复杂的模块,实现的功能也最多,占用了程序运行过程当中90%以
上的执行时间。
流程图中由判断SS(预置信号开始分成两个分支,当SS=1,即预置状态下程序进入预置闪烁部分。
预置闪烁的优先级是:LED34>LED12>LED56即同预置优先级相同(参见调试部分的详细说
明闪烁首先判断是否对LED34进行判断闪烁,如果是则另外两个显示值直接显示,否则判断是否对LED12进行闪烁,如果是则直接显示LED56的值,只有当前两个显示值都不闪烁的时候,才判断是否对LED56进行闪烁,这样就确保了每次只有一个显示值闪烁。
预置通过GS标志位判断预置的亮/灭,由R1控制每50轮显示对GS 取反一次。
当SS=0时进入判断闹铃/报时及正常显示模块,模块EIGHT(参见其说明对闹铃及报时条件
进行判断,符合条件则对P1.6取反一次并使NB(忽略生日有效,此时不进行对BS(生日标志的判断,即使响铃优先级高于生日显示(其实也可以对程序进行修改使响铃和生日显示不发生冲突,修改方法参见程序优化。
当不响铃并且生日标志BS有效时显示HAPPY
④显示HAPPY子程序(SEVEN
本程序实际上是显示主程序的分支,
在模块的划分过程中为了简化显示主程序的编写而将
开关检测模块流程图↑
其单列开来。
本程序由生日标志BS控制,当到达生日时间时,T0中断程序会将BS置1使之有效在显示主程序中通过判断BS的置来控制是否执行本模块。
说明:* 只有当在预置日期时,才需要对LED56进行预置闪烁判断。
并且当LED34(即月份的显示缓存
已经判断需要闪烁后,LED56便不需要闪烁而直接显示(闪烁优先级LED56最低,每次只对一个项
目进行预置,只有一个项目需要闪烁。
这个设置使同时拨下两个以上预置开关时不会出错,参
见调试部分说明
**
闹铃及报时判断程序EIGHT执行过程参见其说明
显示主程序及显示”HAPPY”模块流程图↑
⑤闹铃及整点报时判断程序(EIGHT
在显示主程序中每隔一段时间调用一次本程序来实现闹铃及报时功能。
符合闹铃条件时,每调用一次本程序对P1.6取反一次,调节调用的时间间隔便可以调节报时的输出频率。
在主程序中设置每完成对一个数码管的显示变调用一次本程序,显示一个数码管的时间大约为1ms,因此响铃频率高音约为500Hz,低音约为250Hz。
程序判断闹铃使能RE后分成两个分支,当RE=A1时判断闹铃条件是否满足,满足则对P1.6取反一次,否则跳转判断整点报时条件是否满足。
当RE=0时,直接怕暖整点报时条件是否满足。
判断整点报时条件时当当前时间满足:
(MIN=59∩(SECOND=59 ∩(COUNT>10
时报高音;当满足:
(MIN=59∩(SECOND=51/53/55/57 ∩(COUNT>10
时报低音。
利用位寻址区来存储SECOND的方法,只要
(SECOND>50∩(SE COND.0=1时便满足报低音的秒条件。
利用TO中断次数存储器COUNT的大小可以判断是否到了后半秒(T0每50ms中断一次,中断20次到达一秒。
通过增加一个标志位FC来时下对高低音的区分,高音不受FC的影响,低音只有当FC=0的时候才对P1.6取反一次。
并且每调用一次本程序便对FC取反一次,便达
到每调用两次取反一次P1.6的效果。
本程序的执行时间小于40us,因此多次调用不过分影响执行时间
⑥中断(TO计时程序(NINE
中断计时程序的流程比较简单。
程序除实现正常走时外还需要判断是否到达生日时间置生
闹铃及整点报时判断程序流程图↑
中断(TO计时程序流程图↑
程序的输出均为BCD码,方便了显示程序对高低位的分离并查表显示。
程先将年由BCD码转化为二进制码,此时当年的后两位为其共同特点就是二进制后两位为零,否则为平年。
当MONTH≠2时判断是否为
大小月,MOUTH<7时单月(即MONTH.0=1的月为大月,否则为小月;当MONTH>7
时双月为大月。
⑦中断(T1预置程序(TEN
T1通过中断INT0控制开启或关闭,每次定时50毫秒,存储地址COUNTS计数15次执行一次中断程序。
由开关(K0,K1控制预置项目,通过开关K2/K3/K4 来分别控制LED12/LED34/LED56的预置,当两个开关都是有效时,具有优先级
的区分,确保无论按几个开关都最多
只有一个项目被预置。
判断预置的优
先级顺序是:
LED34>LED12>LED56
这样安排
的原因是由于
根据生活经验
LED34所对应的
4个项目(小时、
闹铃分、月、生
日日被预置的
可能性最大。
在预置日
期和生日是要注意对大小月
及平闰年进行判断(判断方法与中断计时程序中说明的方法类似,但不需要
考虑进位且月和日在溢出后应置一而不是归零。
⑧中断(INT0设定程序(ELEVEN 中断INT0设置是否进行预置以及对生日标志的清除。
且有如下设置顺序:
清除预置信号并关T1>清除生日标志>设定预置信号并开T1。
每按一次中断都
只执行其中一个项目
⑨延时程序(TWELVE 延时时间约2ms即显示两个数码管的时间,用于预置闪烁调节数码关的电压占空比一致而不出现数码管随着闪烁亮度改变的现象。
中断(T1预置程序↑
㈡模块源程序集合及注释
;*************************************************************ONE 初始化 ORG 0
SJMP ONE
ORG 0003H
LJMP ELEVEN
ORG 000BH
LJMP NINE
ORG 001BH
LJMP TEN
ONE:LED12 EQU 30H ;数码管12显示缓存
LED34 EQU 31H ;数码管34显示缓存
LED56 EQU 32H ;数码管56显示缓存
COUNT EQU 33H ;定时器T0(用来走时计数值存储器(计数中断20次到1秒
COUNTS EQU 34H ;定时器T1(用来预置计数值存储器(计数中断15次到预置值加一 HOUR EQU 40H ;以下为时间,日期,闹铃时间,生日的存储地址
MIN EQU 41H SECOND EQU 22H YEAR EQU 50H MONTH EQU 23H DAY EQU 52H
RH EQU 60H ;闹铃小时RM EQU 61H ;闹铃分RE EQU 62H ;闹铃使能BM EQU 71H ;生日-月份BD EQU 72H ;生日-天MOV LED12,#0
MOV LED34,#0
MOV LED56,#0
MOV COUNT,#0
MOV COUNTS,#0 MOV HOUR,#0
MOV MIN,#0
MOV SECOND,#0 MOV YEAR,#0
MOV MONTH,#1
MOV DAY,#1
MOV RH,#0
MOV RM,#0
MOV RE,#0
MOV BM,#6
MOV BD,#1
BS BIT 00H ;birthday symbol生日标志(到生日那天就为1
SS BIT 01H ;set symbol预置信号(按下中断预置为1,便开始闪烁和预置GS BIT 02H ;glisten symbol闪烁标志
FC BIT 03H ;frequency control频率控制
NB BIT 04H ;neglect bitrhday symbol 忽略生日标志
CLR BS
CLR SS
CLR GS
CLR FC
CLR NB
SETB 05H ;生日显示有效标志位
MOV IP,#02H;中断优先级:T0>INT0>T1
MOV TMOD,#11H
MOV IE,#8BH
SETB IT0
MOV TH0,#3CH ;50ms
MOV TL0,#0B0H
SETB TR0
MOV R1,#50 ;显示延时用
MOV R0,#0 ;显示延时用
;************************************************************** TWO 检测开关号 TWO:MOV P0,#0FFH
JB P0.5,TWO1
MOV RE,#0A0H ;0A0表示闹铃无效,送0A0是为了方便将使能查表显示,表中第A项为"-"
SJMP TWO2
TWO1:MOV RE,#0A1H
TWO2:JB P0.0,TWO4
JB P0.1,TWO3
MOV LED12,HOUR
MOV LED34,MIN
MOV LED56,SECOND
SJMP THREE
TWO3:MOV LED12,YEAR
MOV LED34,MONTH
MOV LED56,DAY
SJMP THREE
TWO4:JB P0.1,TWO5
MOV LED12,RH
MOV LED34,RM
MOV LED56,RE
SJMP THREE
TWO5:MOV LED12,BM
MOV LED34,BD
MOV LED56,#0BCH
SJMP THREE
;************************************** THREE显示主程序(同时包含了闹铃,预置闪烁,闹铃功能 THREE:MOV P1,#0
MOV P0,#0FFH
MOV DPTR,#TAB3
JNB SS,THREEB ;判断预置信号是否有效,预置有效则转入判断闪烁显示模块,否则转入正常显示模块
SJMP THREEA
THREEB:LJMP THREE11 ;THREE11是正常显示并判断整点报时及闹铃模块
THREEA:JNB P0.3,THREE1 ;开始是判断闪烁显示,这句判断是否预置分/月/生日的日/闹铃分 JNB GS,THREE1 ;是否闪烁?
LCALL TWELVE ;闪烁则调用延时不显示LED34
SJMP THREE4
THREE1:MOV A,LED34
ANL A,#0FH
MOVC A,@A+DPTR
MOV P2,A
THREE2:SETB P1.3
NOP
DJNZ R0,THREE2
CLR P1.3
MOV A,LED34
SWAP A
ANL A,#0FH
MOVC A,@A+DPTR
MOV P2,A
THREE3:SETB P1.2
NOP
DJNZ R0,THREE3
CLR P1.2
JNB P0.2,THREE4 ;判断是否预置小时/年/生日月/闹铃的小时JNB GS,THREE4 ;是否显示小时/年/生日月/闹铃的小时LCALL TWELVE
SJMP THREE7
THREE4:MOV A,LED12
ANL A,#0FH
MOVC A,@A+DPTR
MOV P2,A
THREE5:SETB P1.1
NOP
DJNZ R0,THREE5
CLR P1.1
MOV A,LED12
SWAP A
ANL A,#0FH
MOVC A,@A+DPTR
MOV P2,A
THREE6:SETB P1.0
NOP
DJNZ R0,THREE6
CLR P1.0
JB P0.0,THREE7 ;数码管56只有在显示日期的天时才有预置闪烁功能,其余三项都不需要判断闪烁 JNB P0.1,THREE7
JB P0.3,THREE7
JNB P0.4,THREE7
JNB GS,THREE7
LCALL TWELVE
SJMP THREE10
THREE7:MOV A,LED56
ANL A,#0FH
MOVC A,@A+DPTR
MOV P2,A
THREE8:SETB P1.5
NOP
DJNZ R0,THREE8
CLR P1.5
MOV A,LED56
SWAP A
ANL A,#0FH
MOVC A,@A+DPTR
MOV P2,A
THREE9:SETB P1.4
NOP
DJNZ R0,THREE9
CLR P1.4
THREE10:DJNZ R1,TWOA
SJMP TWOB
TWOA:LJMP TWO
TWOB:MOV R1,#50 ;判断闪烁一次是否完成CPL GS ;取反闪烁标志,用于控制闪烁的亮和灭LJMP TWO ;一轮显示完后再判断开关号
;**************************正常显示
THREE11:LCALL EIGHT ;判断是否取反P1.6即输出闹铃或整点报时,以下每次显示都要调用一次 JB NB,THREE12 ;如果是在整点报时状态就不显示生日提醒,报时过后显示提醒
JNB BS,THREE12
SJMP SEVEN ;跳到生日提醒程序
THREE12:CLR NB ;开始正常显示时间及判断闹铃输出
ANL A,#0FH
MOVC A,@A+DPTR
MOV P2,A
THREE13:SETB P1.3
NOP
DJNZ R0,THREE13
CLR P1.3
MOV A,LED34
SWAP A
ANL A,#0FH
MOVC A,@A+DPTR
MOV P2,A
THREE14:SETB P1.2 NOP
DJNZ R0,THREE14 CLR P1.2
LCALL EIGHT MOV A,LED12
ANL A,#0FH MOVC A,@A+DPTR MOV P2,A
THREE15:SETB P1.1 NOP
DJNZ R0,THREE15 CLR P1.1
MOV A,LED12 SWAP A
ANL A,#0FH MOVC A,@A+DPTR MOV P2,A
THREE16:SETB P1.0
NOP
DJNZ R0,THREE16 CLR P1.0
LCALL EIGHT MOV A,LED56
ANL A,#0FH MOVC A,@A+DPTR MOV P2,A
THREE17:SETB P1.5 NOP
DJNZ R0,THREE17 CLR P1.5
MOV A,LED56 SWAP A
ANL A,#0FH MOVC A,@A+DPTR MOV P2,A
THREE18:SETB P1.4 NOP
DJNZ R0,THREE18
CLR P1.4
LJMP TWO ;一轮显示完后判开关
TAB3:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H 7FH,6FH,40H,7CH,5EH
;0.1.2.3.4.5.6.7.8.9.-.b.d,的字形表"bd"在显示生日时间时显示在LED56
;**************************************************SEVEN生日时显示生日祝福语”HAPPY” SEVEN:MOV P1,#01H
DJNZ R0,SEVEN
SEVEN1:MOV P1,#02H
MOV P2,#77H
DJNZ R0,SEVEN1
SEVEN2:MOV P1,#04H
MOV P2,#73H
DJNZ R0,SEVEN2
SEVEN3:MOV P1,#08H
MOV P2,#73H
DJNZ R0,SEVEN3
SEVEN4:MOV P1,#10H
MOV P2,#6EH
DJNZ R0,SEVEN4
LJMP TWO ;一轮显示完后判开关
;******************************************************************E IGHT判断是否闹铃子程序 EIGHT:MOV A,RE
CJNE A,#0A1H,EIGHT1
MOV A,MIN
CJNE A,RM,EIGHT1
MOV A,HOUR
CJNE A,RH,EIGHT1
SJMP EIGHT4 ;闹铃时间到则CPLP1.6一次并忽略生日标志(即NB有效
EIGHT1:MOV A,MIN
CJNE A,#59H,EIGHT7
MOV A,SECOND
CJNE A,#59H,EIGHT5 ;是否等于59分59秒
EIGHT2:MOV A,COUNT ;是否到达后半秒
CJNE A,#10,EIGHT3
EIGHT3:JC EIGHT7
EIGHT4:CPL P1.6
SETB NB
SJMP EIGHT7
EIGHT5:MOV A,SECOND
CJNE A,#51H,EIGHT6 ;是否大于51秒
EIGHT6:JC EIGHT7
JNB 10H,EIGHT7 ;判断是否报低音
JB FC,EIGHT7 ; 只有FC有效时才输出
SJMP EIGHT2
EIGHT7:CPL FC ;用来控制报低音和高音,满足报低音条件时,调用两次本程序对P1.6取反一
次,高音时调用一次取反一次
RET
;******** NINE中断(T0计时程序(包含了秒-分-时-日-月-年间的进位及判断大小月,平闰年 NINE:MOV TH0,#3CH ;开定时器
MOV TL0,#0B0H
SETB TR0
INC COUNT
MOV A,COUNT
CJNE A,#20,INEAA
SJMP AAA
INEAA:LJMP NINE1
AAA:MOV COUNT,#0 ; 计时MOV A,SECOND
ADD A,#01
DA A ;换成bcd码以方便显示MOV SECOND,A
CJNE A,#60H,INEAA
MOV A,MIN
ADD A,#01
DA A
MOV MIN,A
CJNE A,#60H,INEAA
MOV MIN,#0
MOV A,HOUR
ADD A,#01
DA A
MOV HOUR,A
CJNE A,#24H,INEAA
MOV HOUR,#0
MOV A,DAY
ADD A,#01
DA A
MOV DAY,A
;************************判断平闰年及大小月MOV A,MONTH
CJNE A,#02H,TEN6A
MOV A,YEAR ;把年由BCD码换成二进制码
ANL A,#0F0H
SWAP A
MOV B,#10
MUL AB
MOV 24H,A
MOV A,YEAR
ANL A,#0FH
ADD A,24H
JB ACC.0,TEN5A ;二进制码后两位为00表示为闰年JB ACC.1,TEN5A
MOV 24H,#01
MOV A,DAY
CJNE A,#30H,NINE1
MOV DAY,#1
SJMP NINE0
TEN5A:MOV A,DAY
CJNE A,#29H,NINE1
MOV DAY,#1
SJMP NINE0
;**************判断大小月;大于等于8月时双月为大月,小于8月时单月为大月 TEN6A:MOV A,MONTH
CJNE A,#08H,TEN7A
TEN7A:JC TEN9A
JB 18H,TEN8A
MOV A,DAY
CJNE A,#32H,NINE1
MOV DAY,#1
SJMP NINE0
TEN8A:MOV A,DAY
CJNE A,#31H,NINE1
MOV DAY,#1
SJMP NINE0
TEN9A:JNB 18H,TEN10A MOV A,DAY
CJNE A,#32H,NINE1 MOV DAY,#1
SJMP NINE0
TEN10A:MOV A,DAY CJNE A,#31H,NINE1 MOV DAY,#1
;******************* NINE0:MOV A,MONTH ADD A,#01
DA A
MOV MONTH,A
SETB 05H
CJNE A,#13H,NINE1 MOV MONTH,#1
MOV A,YEAR
ADD A,#01
DA A
MOV YEAR,A
NINE1:MOV A,MONTH
CJNE A,BM,NINE2
MOV A,DAY
CJNE A,BD,NINE2
JNB 05H,NINE2
SETB BS
NINE2:RETI
;*****************************************TEN中断(T1预置加一程序由INT0控制其的开启与关闭 ;*******************判断预置项目
TEN:MOV TH1,#3CH
MOV TL1,#0B0H
SETB TR1
INC COUNTS
MOV A,COUNTS
CJNE A,#15,TENE
MOV COUNTS,#0
JB P0.0,RBRB
JB P0.1,DAT
SJMP TIME
DAT: LJMP DATE
RBRB:JB P0.1,BDAT
LJMP RTIME
BDAT:LJMP BDATE
TENE:RETI
;**********************预置时间TIME: JNB P0.3,TEN1
MOV A,MIN
ADD A,#01
DA A
MOV MIN,A
CJNE A,#60H,TENA
MOV MIN,#0
SJMP TENA
TEN1:JNB P0.2,TENA
MOV A,HOUR
ADD A,#01
DA A
MOV HOUR,A
CJNE A,#24H,TENA
MOV HOUR,#0
TENA:RETI
;******************预置日期DATE:JNB P0.3,TEN3
MOV A,MONTH
ADD A,#01
DA A
MOV MONTH,A
CJNE A,#13H,TENB
MOV MONTH,#1
SJMP TENB
TEN3:JNB P0.2,TEN4
MOV A,YEAR
ADD A,#01
DA A
MOV YEAR,A
SJMP TENB
TEN4:JNB P0.4,TENB
MOV A,DAY
ADD A,#01
DA A
MOV DAY,A
;***************判断平闰年 MOV A,MONTH CJNE A,#02H,TEN6
MOV A,YEAR
ANL A,#0F0H
SWAP A
MOV B,#10
MUL AB
MOV 24H,A
MOV A,YEAR
ANL A,#0FH
ADD A,24H
JB ACC.0,TEN5
JB ACC.1,TEN5
MOV A,DAY
CJNE A,#30H,TENB
MOV DAY,#1
SJMP TENB
TEN5:MOV A,DAY
CJNE A,#29H,TENB
MOV DAY,#1
SJMP TENB
;**************判断大小月 TEN6:CJNE A,#08H,TEN7 TEN7:JC TEN9
JB 18H,TEN8
MOV A,DAY
CJNE A,#32H,TENB
MOV DAY,#1
SJMP TENB
TEN8:MOV A,DAY
CJNE A,#31H,TENB
MOV DAY,#1
SJMP TENB
TEN9:JNB 18H,TEN10
MOV A,DAY
CJNE A,#32H,TENB
MOV DAY,#1
SJMP TENB
TEN10:MOV A,DAY
CJNE A,#31H,TENB
MOV DAY,#1
TENB: RETI
;**************************预置闹铃时间 RTIME:JNB P0.3,TEN12 MOV A,RM
ADD A,#01
DA A
MOV RM,A
CJNE A,#60H,TENC
MOV RM,#0
SJMP TENC
TEN12:JNB P0.2,TENC
MOV A,RH
ADD A,#01
DA A
MOV RH,A
CJNE A,#24H,TENC
MOV RH,#0
TENC:RETI
;************************预置生日日期 BDATE:JNB P0.3,TEN14 MOV A,BD
ADD A,#01
DA A
MOV BD,A
MOV A,BM
CJNE A,#02H,TEN15
MOV A,BD
CJNE A,#30H,TEND
MOV BD,#1
SJMP TEND
TEN15:CJNE A,#08H,TEN16。