单片微型计算机课程设计报告-多功能电子数字钟.doc_第1页
单片微型计算机课程设计报告-多功能电子数字钟.doc_第2页
单片微型计算机课程设计报告-多功能电子数字钟.doc_第3页
单片微型计算机课程设计报告-多功能电子数字钟.doc_第4页
单片微型计算机课程设计报告-多功能电子数字钟.doc_第5页
免费预览已结束,剩余27页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

多功能电子数字钟 单片微型计算机课程设计报告 多功能电子数字钟 姓 名 学 号 班 级 电气x班 2012-02-21目录一:概述3二:设计基本原理简介4三:设计要求及说明5四:整体设计方案6系统硬件电路设计 系统软件总流程设计模块划分及分析 五:单模块流程设计10各模块设计概述、流程图 模块源程序集合及注释 六:单模块软件测试27七:系统检测调试28硬件电路调试软件部分烧写调试八:心得体会30一、概述课程设计题目:电子数字钟应用知识简介:l 51 单片机 单片机又称单片微控制器,它不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上。作为嵌入式系统控制核心的单片机具有其体积小、功能全、性价比高等诸多优点。51 系列单片机是国内目前应用最广泛的单片机之一,随着嵌入式系统、片上系统等概念的提出和普遍接受及应用,51 系列单片机的发展又进入了一个新的阶段。在今后很长一段时间内51 系列单片机仍将占据嵌入式系统产品的中低端市场。l 汇编语言汇编语言是一种面向机器的计算机低级编程语言,通常是为特定的计算机或系列计算机专门设计的。汇编语言保持了机器语言的优点,具有直接和简捷的特点,其代码具有效率高实时性强等优点。但是对于复杂的运算或大型程序,用汇编语言编写将非常耗时。汇编语言可以与高级语言配合使用,应用十分广泛。l ispisp(in-system programming)在系统可编程,是当今流行的单片机编程模式,指电路板上的空白元器件可以编程写入最终用户代码,而不需要从电路板上取下元器件。已经编程的器件也可以用isp 方式擦除或再编程。本次课程设计便使用isp 方式,直接将编写好的程序下载到连接好的单片机中进行调试。选题目的及设计思想简介:课程设计是一次难得的对所学的知识进行实践的机会,我希望通过课程设计独立设计一个简单的系统从而达到强化课本知识并灵活运用的目的。电子数字钟是日常生活钟随处可见的简单系统。对电子数字钟的设计比较容易联系实际并进行拓展, 在设计中我将力求尽可能跳出课本的样板,从现实生活中寻找设计原型和设计思路,争取有所突破。如图所示便是我本次课程设计流程图,设计的整个过程运用自顶向下分析、自底向上实现的办法进行设计,借鉴在软件工程中学习到的软件设计流程和规范来完成系统设计并在设计过程中体会软件设计的流程。二、设计基本原理简介数字钟的设计首先要保证其走时尽可能准确,其次再根据人们日常的使用习惯来设定其附加功能。在设计中利用单片机定时计数器来完成走时并用两组输出口控制数码管来显示;通过编程向某一输出口输出方波实现报时及闹铃;利用输入端口外接各种开关来完成对走时及显示的控制(如预置时间等)。在设计中需要用到许多技巧。以下为我在学习单片机课程中总结的一些设计思想或方法:l 占空比概念在设计中的运用 如图所示的一串方波序列,导通时间同周期的比值即占空比。在用单片机控制对多个数码管的扫描显示中,数码管接收到的电压可以看成是一串方波序列,占空比控制了数码管的亮度。实际上对显示延时时间的调节就是调节数码管电压的占空比,当占空比大于一定数值的时候数码管可以显示,实验证明占空比在0.1时仍可以使数码管清晰显示。利用这个概念可以比较直观地理解显示延时的调节。l cpu的分时复用单片机只有一个cpu,因此在一个时间内只能执行一条语句,要使单片机同时控制多个外部元件(比如扬声器和数码管)就必须对单片机的cpu进行分时复用,让单片机在一小段时间内连续交替执行控制多个器件的语句,从表面上看,单片机便用一个cpu控制了多个元件。本次课程设计中对整点报时和闹铃功能的实现便用到了这个概念。l 单片机位寻址区的使用单片机内部数据存储器由20h到2fh共有16个字节的位寻址区可以被作为程序执行过程中的状态参数,许多程序模块至于两个状态(比如闪烁与正常显示,报时与不报时等)用位寻址区中的某一位来记录程序执行状态,在需要对状态进行判断的时候十分方便并且节约空间,一个字节便可以判断八个状态,而非位寻址区的地址记录程序状态时可能需要先进行变换,增加了执行成本且容易出错。l 检测开关时需要注意的问题对于用各种开关控制程序执行状态的程序设计中,需要注意实时地进行开关的检测,以确保一旦有开关动作,程序状态立即随之改变。此外,在用多个开关控制不同执行状态时,应注意设置开关检测的优先级以防止多个开关同时按下时出现错误。l 系统资源分配与使用单片机有许多资源是有限的不能滥用,比如定时计数器t,外部中断等,在设计一个多模块程序时,要注意先做一个整体规划,把稀缺资源用在最需要用的地方。此外在有多个模块时,要注意模块间的数据传递,比如累加器a和进位标志c,在使用时要注意不能让前一个模块的数据对下一个模块产生不希望有的影响。在模块间的数据传递比较多时最好用固定的内部数据存储器,以避免冲突发生错误。三、设计要求及说明设计要求:基于单片机电路,借鉴生活中常见的电子钟的功能,结合课本的要求使用汇编语言设计一个简单的电子钟系统。要求使用简便,功能实用,错误少,有一定创新性。电子数字钟实现的主要功能: 实现正常走时(秒分时日月年进位) 能够预置时间和日期 能够自动区分平闰年和大小月 具有闹铃及设定闹铃时间功能 具有整点报时功能 具有生日提醒功能,能够预置生日时间 在任何一种预置状态下,预置项目会闪烁显示其它设计说明 优先级:预置闹铃报时生日提醒正常显示,即预置状态下闹铃、报时功能及生日提醒功能都无效 生日时间到五个数码管显示“happy” 生日显示状态下,按下中断int0恢复正常显示且此后只有在下更改生日日期或第二年生日显示才有效。 正常显示状态下按下中断int0进入预置状态,再按一次恢复。 用数码管(k0,k1)控制显示状态:00:时间,01:闹铃时间,10:日期,11:生日时间且显示样板如下图所示: 预置由拨码开关k2/k3/k4分别控制数码管12/34/56显示值,预置优先级:led34led12led56(相应数码管显示的项目,显示状态下才能预置) 整点报时声音为59分51、53、55、57秒的后半秒报四声低音, 59秒的后半秒报一声高音 闹铃每次响一分钟 不论是预置状态还是正常走时状态均能够自动区分平闰年和大小月 闹铃使能由拨码开关k5控制并实时显示四、整体设计方案硬件电路设计系统硬件电路根据系统功能可知,需要六个数码管,一个外部中断int0,一个扬声器,由此结合单片机课程学习中对实验面板的了解,做出如下电路:如图,晶振频率12mhz,拨码开关数值由p0口读入;p2口的输出作为控制数码管的段控信号,经74ls573即8位数据锁存器接到数码管中。数码管采用共阴接法(图中未标示);p1.0-p1.5作为数码管的位控信号输出端;开关w2经一个基本rs锁存器接入int0,每按一次开关into取反一次,按两次输入一个下降沿;扬声器由p1.6口控制。系统软件总流程设计根据系统要求,设计出系统软件总流程图如下以t0作为正常走时的计时器,t1作为预置状态下预置项目值自动跳升的控制计时器,int0作为设定预置及清楚生日信号的控制按钮设计使每一轮显示(即六个数码管都显示一次)便检测一次开关使上图的“检测开关值判断并显示检测开关值” 的循环时间大约为10ms,即每隔10ms检测一次开关值,每个数码管接收到的电压信号占空比大约为1/7,确保数码管正常显示。三个中断源中断程序执行时间每次均为几十毫秒,基本不影响主程序的显示及闹铃输出。中断优先级t0int0t1,首先确保走时尽可能的准确,其次由于t1的开启和关闭是由int0进行控制的,故int0优先级较高。此外有优先级“预置显示闹铃整点报时生日显示”,由于预置显示是人为控制的故优先级最高,考虑到日常生活中假如闹铃或整点报时被生日显示覆盖可能使影响到人们的日常生活故设定生日优先级最低,且闹铃最多影响生日信号一分钟。闹铃和整点报时不影响正常的时间等的显示。模块划分及分析根据系统功能将模块划分如下l one:初始化程序模块进行资源分配(equ,bit伪指令),设定初值,各中断初始化l two:开关检测模块检测开关号,将要显示值送入显示缓存l three:显示主程序显示显示缓存中值,并进行生日,闹铃,报时判断l seven:显示生日祝福happy程序经显示主程序判断生日时间到要执行的显示happy程序(其实可以认为是显示主程序的一部分)l eight:闹铃及整点报时判断程序判断是否闹铃或报时,如果是则cplp1.6且忽略生日信号,反之则继续执行后续语句上图的“检测开关值判断并显示检测开关值” 的循环时间大约为10ms,即每隔10ms检测一次开关值,每个数码管接收到的电压信号占空比大约为1/7,确保数码管正常显示。三个中断源中断程序执行时间每次均为几十毫秒,基本不影响主程序的显示及闹铃输出。中断优先级t0int0t1,首先确保走时尽可能的准确,其次由于t1的开启和关闭是由int0进行控制的,故int0优先级较高。此外有优先级“预置显示闹铃整点报时生日显示”,由于预置显示是人为控制的故优先级最高,考虑到日常生活中假如闹铃或整点报时被生日显示覆盖可能使影响到人们的日常生活故设定生日优先级最低,且闹铃最多影响生日信号一分钟。闹铃和整点报时不影响正常的时间等的显示。模块划分及分析根据系统功能将模块划分如下l one:初始化程序模块进行资源分配(equ,bit伪指令),设定初值,各中断初始化l two:开关检测模块检测开关号,将要显示值送入显示缓存l three:显示主程序显示显示缓存中值,并进行生日,闹铃,报时判断l seven:显示生日祝福happy程序经显示主程序判断生日时间到要执行的显示happy程序(其实可以认为是显示主程序的一部分)l eight:闹铃及整点报时判断程序判断是否闹铃或报时,如果是则cplp1.6且忽略生日信号,反之则继续执行后续语句五、单模块流程设计在完成了系统总流程设计后,便进入到了系统设计中工作量最大的单模块流程设计。由于系统模块划分虽然是系统设计的基础,但比较简单而且模块划分有多种方法,因此单模块的设计可以认为是本程序中最关键的部分。单模块设计的好坏与否决定了系统功能能否被稳定地实现以及下一阶段调试程序的难度。鉴于单模块设计的重要性,我在设计中并不急于对模块进行编码,而是反复论证模块的可行性和流程图,为下一阶段的工作做好准备,同时也能够尽早发现系统模块划分的错误,加以解决。各模块设计概述及模块流程图初始化模块(one)初始化模块包含了各中断的跳转语句、存储资源的分配、各存储器和寄存器的赋值以及中断及计时器的状态设置。源程序中共使用了17字节的内部数据存储地址,其中包含3字节位寻址地址以便于进行位判断。三字节的位寻址地址分配如下:22h秒的存储地址,方便对整点报时条件进行判断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,即预置状态下程序进入预置闪烁部分。预置闪烁的优先级是:led34led12led56即同预置优先级相同(参见调试部分的详细说明)闪烁首先判断是否对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执行过程参见其说明闹铃及整点报时判断程序(eight)在显示主程序中每隔一段时间调用一次本程序来实现闹铃及报时功能。符合闹铃条件时,每调用一次本程序对p1.6取反一次,调节调用的时间间隔便可以调节报时的输出频率。在主程序中设置每完成对一个数码管的显示变调用一次本程序,显示一个数码管的时间大约为1ms,因此响铃频率高音约为500hz,低音约为250hz。程序判断闹铃使能re后分成两个分支,当re=a1时判断闹铃条件是否满足,满足则对p1.6取反一次,否则跳转判断整点报时条件是否满足。当re=0时,直接怕暖整点报时条件是否满足。判断整点报时条件时当当前时间满足:(min=59)(second=59) (count10)时报高音;当满足:(min=59)(second=51/53/55/57) (count10)时报低音。利用位寻址区来存储second的方法,只要(second50)(second.0=1)时便满足报低音的秒条件。利用to中断次数存储器count的大小可以判断是否到了后半秒(t0每50ms中断一次,中断20次到达一秒)。通过增加一个标志位fc来时下对高低音的区分,高音不受fc的影响,低音只有当fc=0的时候才对p1.6取反一次。并且每调用一次本程序便对fc取反一次,便达到每调用两次取反一次p1.6的效果。本程序的执行时间小于40us,因此多次调用不过分影响执行时间 中断(to)计时程序(nine) 中断计时程序的流程比较简单。程序除实现正常走时外还需要判断是否到达生日时间置生日标志位有效。程序的输出均为bcd码,方便了显示程序对高低位的分离并查表显示。程序比较复杂的地方在于对平闰年及大小月的判断。把月month存储在位寻址区,当month=02h时判断是否是平闰年,先将年由bcd码转化为二进制码,此时当年的后两位为全零的时候为闰年(由于只显示年的个位和十位,由2000年开始,00年、04年为闰年,其共同特点就是二进制后两位为零),否则为平年。当month2时判断是否为大小月,mouth7时双月为大月。中断(t1)预置程序(ten)t1通过中断int0控制开启或关闭,每次定时50毫秒,存储地址counts计数15次执行一次中断程序。由开关(k0,k1)控制预置项目,通过开关k2/k3/k4来分别控制led12/led34/led56的预置,当两个开关都是有效时,具有优先级的区分,确保无论按几个开关都最多只有一个项目被预置。判断预置的优先级顺序是:led34led12led56这样安排的原因是由于根据生活经验led34所对应的4个项目(小时、闹铃分、月、生日日)被预置的可能性最大。在预置日期和生日是要注意对大小月及平闰年进行判断(判断方法与中断计时程序中说明的方法类似,但不需要考虑进位)且月和日在溢出后应置一而不是归零。中断(int0)设定程序(eleven)中断int0设置是否进行预置以及对生日标志的清除。且有如下设置顺序:清除预置信号并关t1清除生日标志设定预置信号并开t1。每按一次中断都只执行其中一个项目延时程序(twelve)延时时间约2ms即显示两个数码管的时间,用于预置闪烁调节数码关的电压占空比一致而不出现数码管随着闪烁亮度改变的现象。模块源程序集合及注释;*one初始化org 0sjmp oneorg 0003hljmp elevenorg 000bhljmp nineorg 001bhljmp tenone: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 41hsecond equ 22hyear equ 50hmonth equ 23hday equ 52hrh equ 60h ;闹铃小时rm equ 61h ;闹铃分re equ 62h ;闹铃使能bm equ 71h ;生日月份bd equ 72h ;生日天mov led12,#0mov led34,#0mov led56,#0mov count,#0mov counts,#0mov hour,#0mov min,#0mov second,#0mov year,#0mov month,#1mov day,#1mov rh,#0mov rm,#0mov re,#0mov bm,#6mov bd,#1bs 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 bsclr ssclr gsclr fcclr nbsetb 05h ;生日显示有效标志位mov ip,#02h;中断优先级:t0int0t1mov tmod,#11hmov ie,#8bhsetb it0mov th0,#3ch ;50msmov tl0,#0b0hsetb tr0mov r1,#50 ;显示延时用mov r0,#0 ;显示延时用;* two检测开关号two:mov p0,#0ffhjb p0.5,two1mov re,#0a0h ;0a0表示闹铃无效,送0a0是为了方便将使能查表显示,表中第a项为-sjmp two2two1:mov re,#0a1htwo2:jb p0.0,two4jb p0.1,two3mov led12,hourmov led34,minmov led56,secondsjmp threetwo3:mov led12,yearmov led34,monthmov led56,daysjmp threetwo4:jb p0.1,two5mov led12,rhmov led34,rmmov led56,resjmp threetwo5:mov led12,bmmov led34,bdmov led56,#0bchsjmp three;* three显示主程序(同时包含了闹铃,预置闪烁,闹铃功能)three:mov p1,#0mov p0,#0ffhmov dptr,#tab3jnb ss,threeb ;判断预置信号是否有效,预置有效则转入判断闪烁显示模块,否则转入正常显示模块sjmp threeathreeb:ljmp three11 ;three11是正常显示并判断整点报时及闹铃模块threea:jnb p0.3,three1 ;开始是判断闪烁显示,这句判断是否预置分/月/生日的日/闹铃分jnb gs,three1 ;是否闪烁?lcall twelve ;闪烁则调用延时不显示led34sjmp three4three1:mov a,led34anl a,#0fhmovc a,a+dptrmov p2,athree2:setb p1.3nopdjnz r0,three2clr p1.3mov a,led34swap aanl a,#0fhmovc a,a+dptrmov p2,athree3:setb p1.2nopdjnz r0,three3clr p1.2jnb p0.2,three4 ;判断是否预置小时/年/生日月/闹铃的小时jnb gs,three4 ;是否显示小时/年/生日月/闹铃的小时lcall twelvesjmp three7three4:mov a,led12anl a,#0fhmovc a,a+dptrmov p2,athree5:setb p1.1nopdjnz r0,three5clr p1.1mov a,led12swap aanl a,#0fhmovc a,a+dptrmov p2,athree6:setb p1.0nopdjnz r0,three6clr p1.0jb p0.0,three7 ;数码管56只有在显示日期的天时才有预置闪烁功能,其余三项都不需要判断闪烁jnb p0.1,three7jb p0.3,three7jnb p0.4,three7jnb gs,three7lcall twelvesjmp three10three7:mov a,led56anl a,#0fhmovc a,a+dptrmov p2,athree8:setb p1.5nopdjnz r0,three8clr p1.5mov a,led56swap aanl a,#0fhmovc a,a+dptrmov p2,athree9:setb p1.4nopdjnz r0,three9clr p1.4three10:djnz r1,twoasjmp twobtwoa:ljmp twotwob:mov r1,#50 ;判断闪烁一次是否完成cpl gs ;取反闪烁标志,用于控制闪烁的亮和灭ljmp two ;一轮显示完后再判断开关号;*正常显示three11:lcall eight ;判断是否取反p1.6即输出闹铃或整点报时,以下每次显示都要调用一次jb nb,three12 ;如果是在整点报时状态就不显示生日提醒,报时过后显示提醒jnb bs,three12sjmp seven ;跳到生日提醒程序three12:clr nb ;开始正常显示时间及判断闹铃输出mov a,led34anl a,#0fhmovc a,a+dptrmov p2,athree13:setb p1.3nopdjnz r0,three13clr p1.3mov a,led34swap aanl a,#0fhmovc a,a+dptrmov p2,athree14:setb p1.2nopdjnz r0,three14clr p1.2lcall eightmov a,led12anl a,#0fhmovc a,a+dptrmov p2,athree15:setb p1.1nopdjnz r0,three15clr p1.1mov a,led12swap aanl a,#0fhmovc a,a+dptrmov p2,athree16:setb p1.0nopdjnz r0,three16clr p1.0lcall eightmov a,led56anl a,#0fhmovc a,a+dptrmov p2,athree17:setb p1.5nopdjnz r0,three17clr p1.5mov a,led56swap aanl a,#0fhmovc a,a+dptrmov p2,athree18:setb p1.4nopdjnz r0,three18clr p1.4ljmp 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,#01hmov p2,#76hdjnz r0,sevenseven1:mov p1,#02hmov p2,#77hdjnz r0,seven1seven2:mov p1,#04hmov p2,#73hdjnz r0,seven2seven3:mov p1,#08hmov p2,#73hdjnz r0,seven3seven4:mov p1,#10hmov p2,#6ehdjnz r0,seven4ljmp two ;一轮显示完后判开关;*eight判断是否闹铃子程序eight:mov a,recjne a,#0a1h,eight1mov a,mincjne a,rm,eight1mov a,hourcjne a,rh,eight1sjmp eight4 ;闹铃时间到则cplp1.6一次并忽略生日标志(即nb有效)eight1:mov a,mincjne a,#59h,eight7mov a,secondcjne a,#59h,eight5 ;是否等于59分59秒eight2:mov a,count ;是否到达后半秒cjne a,#10,eight3eight3:jc eight7eight4:cpl p1.6setb nbsjmp eight7eight5:mov a,secondcjne a,#51h,eight6 ;是否大于51秒eight6:jc eight7jnb 10h,eight7 ;判断是否报低音jb fc,eight7 ; 只有fc有效时才输出sjmp eight2eight7:cpl fc ;用来控制报低音和高音,满足报低音条件时,调用两次本程序对p1.6取反一次,高音时调用一次取反一次ret;* nine中断(t0)计时程序(包含了秒分时日月年间的进位及判断大小月,平闰年)nine:mov th0,#3ch ;开定时器mov tl0,#0b0hsetb tr0inc countmov a,countcjne a,#20,ineaasjmp aaaineaa:ljmp nine1aaa:mov count,#0 ; 计时mov a,secondadd a,#01da a ;换成bcd码以方便显示mov second,acjne a,#60h,ineaamov second,#0mov a,minadd a,#01da amov min,acjne a,#60h,ineaamov min,#0mov a,houradd a,#01da amov hour,acjne a,#24h,ineaamov hour,#0mov a,dayadd a,#01da amov day,a;*判断平闰年及大小月mov a,monthcjne a,#02h,ten6amov a,year ;把年由bcd码换成二进制码anl a,#0f0hswap amov b,#10mul abmov 24h,amov a,yearanl a,#0fhadd a,24hjb acc.0,ten5a ;二进制码后两位为00表示为闰年jb acc.1,ten5amov 24h,#01mov a,daycjne a,#30h,nine1mov day,#1sjmp nine0ten5a:mov a,daycjne a,#29h,nine1mov day,#1sjmp nine0;*判断大小月;大于等于8月时双月为大月,小于8月时单月为大月ten6a:mov a,monthcjne a,#08h,ten7aten7a:jc ten9ajb 18h,ten8amov a,daycjne a,#32h,nine1mov day,#1sjmp nine0ten8a:mov a,daycjne a,#31h,nine1mov day,#1sjmp nine0ten9a:jnb 18h,ten10amov a,daycjne a,#32h,nine1mov day,#1sjmp nine0ten10a:mov a,daycjne a,#31h,nine1mov day,#1;*nine0:mov a,monthadd a,#01da amov month,asetb 05hcjne a,#13h,nine1mov month,#1mov a,yearadd a,#01da amov year,anine1:mov a,monthcjne a,bm,nine2mov a,daycjne a,bd,nine2jnb 05h,nine2setb bsnine2:reti;*ten中断(t1)预置加一程序由int0控制其的开启与关闭;*判断预置项目ten:mov th1,#3chmov tl1,#0b0hsetb tr1inc countsmov a,countscjne a,#15,tenemov counts,#0jb p0.0,rbrbjb p0.1,datsjmp timedat: ljmp daterbrb:jb p0.1,bdatljmp rtimebdat:ljmp bdatetene:reti;*预置时间time: jnb p0.3,ten1mov a,minadd a,#01da amov min,acjne a,#60h,tenamov min,#0sjmp tenaten1:jnb p0.2,tenamov a,houradd a,#01da amov hour,acjne a,#24h,tenamov hour,#0tena:reti;*预置日期date:jnb p0.3,ten3mov a,monthadd a,#01da amov month,acjne a,#13h,tenbmov month,#1sjmp tenbten3:jnb p0.2,ten4mov a,yearadd a,#01da amov year,asjmp tenbten4:jnb p0.4,tenbmov a,dayadd a,#01da amov day,a;*判断平闰年mov a,monthcjne a,#02h,ten6mov a,yearanl a,#0f0hswap amov b,#10mul abmov 24h,amov a,yearanl a,#0fhadd a,24hjb acc.0,ten5jb acc.1,ten5mov a,daycjne a,#30h,tenbmov day,#1sjmp tenbten5:mov a,daycjne a,#29h,tenbmov day,#1sjmp tenb;*判断大小月ten6:cjne a,#08h,ten7ten7:jc ten9jb 18h,ten8mov a,daycjne a,#32h,tenbmov day,#1sjmp tenbten8:mov a,daycjne a,#31h,tenbmov day,#1sjmp tenbten9:jnb 18h,ten10mov a,daycjne a,#32h,tenbmov day,#1sjmp tenbten10:mov a,daycjne a,#31h,tenbmov day,#1tenb: reti;*预置闹铃时间rtime:jnb p0.3,ten12mov a,rmadd a,#01da amov rm,acjne a,#60h,tencmov rm,#0sjmp tencten12:jnb p0.2,tencmov a,rhadd a,#01da amov rh,acjne a,#24h,tencmov rh,#0tenc:reti;*预置生日日期bdate:jnb p0.3,ten14mov a,bdadd a,#01da amov bd,amov a,bmcjne a,#02h,ten15mov a,bdcjne a,#30h,tendmov bd,#1sjmp tendten15:cjne a,#08h,ten16ten16:jc ten18jb 18h,ten17mov a,bdcjne a,#32h,tendmov bd,#1sjmp tendten17:mov a,bdcjne a,#31h,tendmov bd,#1sjmp tendten18:jnb 18h,ten19mov a,bdcjne a,#32h,tendmov bd,#1sjmp tendten19:mov a,bdcjne a,#31h,tendmov bd,#1sjmp tendten14:jnb p0.2,tendmov a,bmadd a,#01da amov bm,acjne a,#13h,tendmov bm,#1tend:setb 05hreti;*eleven中断(int0)控制了预置的开关以及生日信号的清除eleven:jnb ss,eleven1 ;预置有效时按一次int0关预置clr ssclr tr1sjmp eleven3eleven1:jnb bs,eleven2 ;预置无效判断生日信号有效则清除生日信号clr 05hclr bssjmp eleven3eleven2:setb ss ;都无效则令预置有效mov th1,#3chmov tl1,#0b0hsetb tr1eleven3:reti;*twelve 延时小程序twelve:mov p1,#0mov p2,#0djnz r0,twelvetwelve1:mov p1,#0mov p2,#0djnz r0,twelve1ret六、单模块软件测试编码中常用的程序结构说明 jnb ss,threeb;sjmp threeathreeb:ljmpthree11;threea:jnbp0.3,three1由于使用jnb等跳转指令的时候,跳转长度比较短,故需要跳转到比较远的地方时需要用这个结构。相当于:jnb ss,three11jnb p0.3,three1three1:mov a,led34anl a,#0fhmovc a,a+dptrmov p2,athree13:setb p1.3nopdjnz r0,three13clr p1.3mov a,led34swap aanl a,#0fhmovc a,a+dptrmov p2,athree14:setb p1.2nopdjnz r0,three14clr p1.2显示主程序中常用的语句段,分离led34中的高半位和低半位作为字形码段控信号查表偏移量,通过r0延时,延时时间大约为每个数码管1ms。 ten6a:mov a,monthcjne a,#08h,ten7aten7a:jc ten9a判断month

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论