资源描述
. . .
目 录
摘要1
第一章绪论1
1.1 当前的数字钟解决方案1
1.2 课题研究的主要容1
1.2 本设计的目的和意义1
1.3 本文的主要容1
第二章总体方案设计3
2.1 总体功能分析3
2.2 LED驱动方案选择3
2.2.1 静态显示驱动4
2.2.2动态显示驱动5
2.3 按键检测方案选择6
2.3.1 查询方式读取按键值6
2.3.2 中断方式读取按键值6
2.3 电源方案选择6
2.4 主要器件的选型7
第三章系统硬件设计9
3.1 单片机最小系统电路设计9
3.2 数码管驱动电路设计10
3.3 按键驱动电路设计12
3.4 电源设计13
第四章系统软件设计15
4.1按键读取程序设计15
4.1.1 模式选择按键程序解析15
4.1.2 确定/清零按钮程序解析16
4.1.3 设定位选择按钮程序解析17
4.1.4 开始/暂停计时按钮程序解析17
4.1.5 加按钮程序解析18
4.2 LED显示驱动程序设计19
4.3 计时程序设计20
4.4控制模块程序设计21
第五章系统的PROTUES仿真22
5.1 系统的PROTUES模型22
5.2 时钟运行仿真23
5.3 初始时间设定的仿真24
5.4 增计时的仿真25
5.5 减计时的仿真25
结束语27
参考文献28
致29
27 / 29
摘要
数字钟系统涉与到时钟产生电路、计时控制电路、驱动显示和按键操作等部分,本设计将时钟产生和计时控制部分集成到AT89S51单片机部,单片机外接人际交互界面即显示和按键,来构成了整个数字钟系统。
本系统采用AT89S51单片机作为控制器件,通过单片机部的定时器技术功能实现分频,将系统的12MHz时钟分频得到1mS的触发信号,来触发计时程序,驱动时钟程序的运行, 得到时钟精度较高的时钟。
在完成整个系统的理论分析设计的基础上,还对本系统做了详细的硬件设计和软件编写,在PROTUES软件中完成了整个系统功能的验证,能够实现6位LED数码管实时显示时间,准确完成时、分、秒的计时功能,有10mS级的增计时和减计时(秒表倒计时)功能,还能实现初始时间设定功能,可单独设定时、分、秒,达到了预期的效果。
关键词:数字钟 AT89S51单片机
第一章 绪论
1.1 当前的数字钟解决方案
当前的数字钟系统大都采用集成的实时时钟芯片,这种芯片种类较多,功能和集成度也不一样,主要代表为DS1302芯片。
DS1302 是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302部有一个31×8的用于临时性存放数据的RAM寄存器。DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后备电源双电源引脚,同时提供了对后备电源进行涓细电流充电的能力。DS1302 存在时钟精度不高,易受环境影响,出现时钟混乱等缺点。DS1302可以用于数据记录,特别是对某些具有特殊意义的数据点的记录,能实现数据与出现该数据的时间同时记录。这种记录对长时间的连续测控系统结果的分析与对异常数据出现的原因的查找具有重要意义。传统的数据记录方式是隔时采样或定时采样,没有具体的时间记录,因此,只能记录数据而无法准确记录其出现的时间;若采用单片机计时,一方面需要采用计数器,占用硬件资源,另一方面需要设置中断、查询等,同样耗费单片机的资源,而且,某些测控系统可能不允许。但是,如果在系统中采用时钟芯片DS1302,则能很好地解决这个问题。
1.2 课题研究的主要容
本设计主要是设计出一套基于单片机的数字钟系统,该系统通过6位LED数码管实时显示时间,具有准确的计时功能,能够设定计时初始值,并可以独立设置时、分、秒位,具有倒计时功能。
1.2 本设计的目的和意义
本设计能够实现LED数码管显示数字的功能,完成时、分、秒的显示,时间初始值的调整,秒表功能等。通过本次设计加深对数字电路、单片机等课程的全面认识和复习掌握,对单片机课程的应用进一步了解,并培养自己对单片机课程的兴趣。掌握LED的原理和程序设计方法,通过本次设计能够将单片机软硬件结合起来,对程序进行编写和仿真验证。综合运用单片机技术,数字电子技术的知识设计数字钟计时系统,锻炼自己发现问题和很好地解决问题的能力,培养系统工程设计能力。
1.3 本文的主要容
本文介绍的主要容安排如下:
(1)第一章 绪论。主要介绍了数字钟的发展和应用价值,对纯硬件数字电路构成数字钟系统存在的问题作了探讨。
(2)第二章 总体方案设计。介绍了系统设计方案和工作原理,以与核心器件的选型和系统的参数计算。
(3)第三章 系统的硬件设计。对系统各模块的硬件设计进行详细介绍,给出了系统硬件设计的总体框图和各模块的详细电路图。
(4)第四章 系统的软件设计。主要介绍了本系统中AT89S51单片机编程的技巧和程序原理流程图。
(5)结束语阐述了本系统的设计思想,简要描述了本系统的设计特点,并对进一步的研究提出了展望。
第二章 总体方案设计
2.1 总体功能分析
本设计采用单片机作为主控制器,相比数字电路硬件实现来说,将计时和控制电路用单片机软件实现,提高了系统的集成度和开发难度,有利于缩短开发周期和减小产品体积和成本。本设计将数字钟的所有功能集成在一起,由一个控制器来完成所有部分的控制,主要功能模块分为按键、按键驱动电路、LED驱动电路,LED显示、微控制器和供电系统等部分,如图2-1所示。
按键
AT89S51单片机
LED驱动
LED显示
电源系统
按键驱动
图2-1 数字钟电路总体框图
开始
系统初始化
10mS计时到?
时钟计数加1
增计数加1
判断进位
判断进位
刷新显示缓冲
减计数减1
判断借位
是否到0?
停止减计数
刷新显示缓冲
刷新显示缓冲
图2-2 系统的软件总体框图
按键驱动电路主要实现按键和单片机的接口,当有按键操作的时候,按键驱动电路通知单片机读取按键值,本设计采用中断方式读取按键,中断方式相比查询能够提高系统的响应速度,占用更少的系统资源,而且当单片机具有低功耗模式的时候,在没有操作的时候可以进入低功耗模式,在有操作的时候通过安检驱动电路来唤醒单片机读取按键值,这样可以很好的降低系统的功耗。LED显示和LED驱动电路主要完成单片机给定数据的显示,通过6位数码管实时显示时、分、秒,本设计采用8位锁存芯片74HC574来驱动LED显示,采用的是静态驱动显示。
2.2 LED驱动方案选择
数码管是一种半导体发光器件,其基本单元是发光二极管。按发光二极管单元连接方式分为共阳极数码管和共阴极数码管。共阳极数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管,共阳极数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮,当某一字段的阴极为高电平时,相应字段就不亮。共阴极数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管,共阴极数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮,当某一字段的阳极为低电平时,相应字段就不亮。
a
b
c
d
e
f
g
a b c d e f g
COM
图2-3 共阳极数码管原理图
a
b
c
d
e
f
g
a b c d e f g
COM
图2-4 共阴极数码管原理图
2.2.1 静态显示驱动
静态驱动也称直流驱动。静态驱动是指每个数码管的每一个段码都由一个单片机的I/O端口进行驱动,或者使用如BCD码二-十进制译码器译码进行驱动。静态驱动的优点是编程简单,显示亮度高,缺点是占用I/O端口多,如驱动5个数码管静态显示则需要5×8=40根I/O端口来驱动,要知道一个89S51单片机可用的I/O端口才32个呢:),实际应用时必须增加译码驱动器进行驱动,增加了硬件电路的复杂性。
2.2.2动态显示驱动
数码管动态显示接口是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划"a,b,c,d,e,f,g,dp"的同名端连在一起,另外为每个数码管的公共极COM增加位选通控制电路,位选通由各自独立的I/O线控制,当单片机输出字形码时,所有数码管都接收到一样的字形码,但究竟是那个数码管会显示出字形,取决于单片机对位选通COM端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位就显示出字形,没有选通的数码管就不会亮。通过分时轮流控制各个数码管的的COM端,就使各个数码管轮流受控显示,这就是动态驱动。在轮流显示过程中,每位数码管的点亮时间为1~2ms,由于人的视觉暂留现象与发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O端口,而且功耗更低。
当前大部分产品中用到的是数码管的动态扫描驱动显示,有很多的集成LED数码管动态扫描驱动芯片可供选择,其中MAXIM公司的MAX7219就是用的很广泛的一片驱动芯片。MAX7219/MAX7221是一种集成化的串行输入/输出共阴极显示驱动器,它连接微处理器与8位数字的7段数字LED显示,也可以连接条线图显示器或者64个独立的LED。其上包括一个片上的B型BCD编码器、多路扫描回路,段字驱动器,而且还有一个8*8的静态RAM用来存储每一个数据。 只有一个外部寄存器用来设置各个LED的段电流。 MAX7221与SPI™、 QSPI™以与 MICROWIRE™相兼容,同时它有限制回转电流的段驱动来减少EMI(电磁干扰)。 一个方便的四线串行接口可以联接所有通用的微处理器。 每个数据可以寻址在更新时不需要改写所有的显示。MAX7219/MAX7221同样允许用户对每一个数据选择编码或者不编码。 整个设备包含一个150μA的低功耗关闭模式,模拟和数字亮度控制,一个扫描限制寄存器允许用户显示1-8位数据,还有一个让所有LED发光的检测模式。 在应用时要求3V的操作电压或segment blinking,可以查阅MAX6951数据资料。
2.3 按键检测方案选择
2.3.1 查询方式读取按键值
查询方式读取按键值是指,单片机不断重复的读取按键所接端口的值,判断是否有按键被按下的一种方法,在简单的单片机系统中,查询方式读取按键用得较多,这种方式下的软件编程比较容易,只需要简单的单片机读端口数据即可实现。但是这一方式下单片机的负担较重,需要间隔很小的时间扫描一次按键,在没有按键按下的时候,相当于单片机是在做无用功,浪费了系统资源和能量。
2.3.2 中断方式读取按键值
中断方式读取按键值与查询方式读取按键值相比较,在系统资源占用和低功耗方面性能要高很多。中断方式读取按键值就是当有按键被按下的时候,通过外部的逻辑电路来触发单片机的外部中断引脚,中断单片机现有的任务,去读取按键值,这种方式下单片机外围的硬件设计相比较查询方式下要稍显复杂,但是其优势是不可忽视的。
2.3 电源方案选择
电源是每个电子产品不可缺少的部分,在低电压的电子产品中,主要的电源解决方案有两种:变压器降压加线性稳压芯片结合和开关电源降压型电源。
变压器降压加线性稳压芯片结合的方案是比较传统的方案,在小功率的电子产品中用的较多,但是当电子产品的功率上升后,降压变压器的体积和重量是一个没有办法解决的问题,因为这里的变压器是工频变压器,其磁芯是硅钢片叠起来的,由于频率较低为50Hz,变压器的磁芯无法减小体积。
开关电源是利用现代电力电子技术,控制开关管开通和关断的时间比率,维持稳定输出电压的一种电源,开关电源一般由脉冲宽度调制(PWM)控制IC和MOSFET构成。开关电源和线性电源相比,二者的成本都随着输出功率的增加而增长,但二者增长速率各异。线性电源成本在某一输出功率点上,反而高于开关电源,这一点称为成本反转点。随着电力电子技术的发展和创新,使得开关电源技术也在不断地创新,这一成本反转点日益向低输出电力端移动,这为开关电源提供了广阔的发展空间。开关电源高频化是其发展的方向,高频化使开关电源小型化,并使开关电源进入更广泛的应用领域,特别是在高新技术领域的应用,推动了高新技术产品的小型化、轻便化。另外开关电源的发展与应用在节约能源、节约资源与保护环境方面都具有重要的意义。开关电源高频化是其发展的方向,高频化使开关电源小型化,并使开关电源进入更广泛的应用领域,特别是在高新技术领域的应用,推动了高新技术产品的小型化、轻便化。另外开关电源的发展与应用在节约能源、节约资源与保护环境方面都具有重要的意义。
2.4 主要器件的选型
本设计采用了价廉的 AT89S51芯片(目前一片价格在5-9元/片左右)。AT89S51是一个低功耗,高性能CMOS 8位单片机,片含4k Bytes ISP(In-system programmable)的可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统与80C51引脚结构,芯片集成了通用8位中央处理器和ISP Flash存储单元,AT89S51在众多嵌入式控制应用系统中得到广泛应用。
AT89S51芯片有40个引脚,核心部分为MCS-51核。片集成4k Bytes Flash片程序存储器、128 Bytes RAM数据存储器、2个16位可编程定时器/计数器、5个中断优先级、2层中断嵌套中断、6个中断源、32个外部双向I/0端口和两个全双工的串口通信接口UART,工作频率最高可达33MHz,支持在线编程下载,即ISP下载功能,AT89SXX系列单片机实现了ISP下载功能,故而取代了89CXX系列的下载方式,也是因为这样,ATMEL公司已经停止生产89CXX系列的单片机,现在市面上的AT89CXX多是停产前的库存产品。
P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的低八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。
P1口是一个部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。
P2口为一个部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口管脚是8个带部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。P3口除了作为普通I/O口,还有第二功能:
数码管驱动电路采用8位数据脉冲触发锁存芯片74HC574,该芯片是三态输出的8位D触发器,在CP端的上升沿将输入数据触发到输出端,输出使能端(OE)控制三态输出,当使能端OE为高的时候,8位数据段输出为高阻态。
按键驱动电路采用的是8位数据锁存器/缓冲器74HC541,具有数据缓冲器、线路驱动等功能,支持三态输出,和74HC540的功能相近。
第三章 系统硬件设计
3.1 单片机最小系统电路设计
本设计选用的是Atmel公司的8位单片机AT89S51,该单片机是基于MCS-51核,具有在线编程(ISP)的4k Bytes Flash存储器,256Bytes RAM空间,可外扩存储空间64k Bytes,32个可编程的I/O引脚,集成了异步串口和16位定时器,最高工作时钟频率可达33MHz。
单片机的最小系统电路包括ISP程序下载接口、电源电路、晶振电路和上电复位电路,下面做详细分析。
ISP程序下载接口是一个双排10针的接口座子,与单片机的P1.5(MOSI)、P1.6(MISO)、P1.7(SCK)和复位引脚RESET连接。
图3-1 ISP下载接口
电源滤波电容如图3-2所示,本设计选择了一个470μF的电解电容和两个0.1μF的瓷片电容,电解电容用于储能,抑制电压波动对单片机的影响,瓷片电容可以滤除电源中的高频干扰信号,在设计PCB时,这几个电容要尽量靠近单片机的电源和地引脚。
图3-2电源滤波电容
本系统的单片机时钟选择12M晶振,如图3-3所示,晶振两端分别接22pF电容到地。
图3-3 时钟电路
单片机的上电复位电路采用一个10μF电容和10kΩ电阻串联,在上电时候,电容和电阻分压,给单片机的复位引脚提供了一个高电平信号,使单片机复位,当电容充电完成后,复位引脚被下拉到地,单片机正常工作。
图3-4 上电复位电路
单片机最小系统的整体电路详见附录。
3.2 数码管驱动电路设计
本设计采用了静态驱动的方式来驱动数码管,数码管驱动芯片74HC574的电路连接如图3-6所示,数据输入端接单片机的数据总线,数据输出端串连一个510Ω的电阻后接数码管的段驱动端,数码管选用的是共阳极型,其公共端位阳极,接电源,输出使能端直接接地,时钟触发端信号是由片选信号和写使能信号经过一个或门电路后得到的,当片选和写使能都有效的时候,拉低时钟触发端,然后单片机将数据加载到数据总线上,当写使能或者片选信号被单片机释放后,在74HC574的时钟触发端就会出现一个上升沿信号,利用这一个信号即可将数据总线上的数据锁存到输出。该驱动电路对应的的数码管显示数字0--9数据译码如表3-1所示。
表3-1 数码管显示译码表
段号
数字
1
2
3
4
5
6
7
8
9
0
a
0
1
1
0
1
1
1
1
1
1
b
1
1
1
1
0
0
1
1
1
1
c
1
0
1
1
1
1
1
1
1
1
d
0
1
1
0
1
1
0
1
1
1
e
0
1
0
0
0
1
0
1
0
1
f
0
0
0
1
1
1
0
1
1
1
g
0
1
1
1
1
1
0
0
1
0
DP
0
0
0
0
0
0
0
0
0
0
共阳码
F9
A4
B0
99
92
82
F8
80
90
C0
图3-5 74HC138译码电路
本设计中的LED数码管驱动电路需要驱动6位数码管,相对应有6片数码管驱动芯片,本设计采用一片74HC138作为6片驱动芯片的地址译码器,其电路如图3-5所示。单片机的地址线A8、A9、A10、A11分别接74HC138的译码输入信号线A0、A1、A2和高使能端E3,地使能端直接接地,其输出端Y0---Y5分别接6片数码管驱动该芯片74HC574。数码管驱动芯片的地址译码如表3-2所示。
表3-2 6位数码管的地址译码表
LED5
LED4
LED3
LED2
LED1
LED0
A8
1
0
1
0
1
0
A9
0
0
1
1
0
0
A10
1
1
0
0
0
0
A11
1
1
1
1
1
1
地址码
D00
C00
B00
A00
900
800
图3-6 LED数码管驱动电路
3.3 按键驱动电路设计
为了提高系统的快速响应速度,按键采用中断读取的方式来设计,当有按键按下后,通过单片机的外部中断来通知单片机读取按键值,这样能够提高系统对按键的响应速度,也可以减少查询方式下的编程工作量,而且,当单片机具有低功耗功能的时候,可以使单片机在没有任务的时候进入低功耗模式,有按键按下的时候再唤醒单片机开始工作,或者在计数器需要CPU干预的时候唤醒CPU工作,这样可以能耗的提高系统的低功耗效果,达到最小的功率消耗。
按键读取电路如图3-7所示,5个按键的输出端接10kΩ的上拉电阻和0.1uF的滤波防抖动电容后,输出到单片机的数据端,5个按键的输出信号经过相与后接到单片机的外部中断检测引脚。当没有按键按下的时候,KEY0---KEY4都为高电平,经过如图3-7所示的与门电路后输出EXINT0为高电平,当有任意一个按键按下后,EXINT0端就会出现低电平,所以当按键按下就会在EXINT0端输出一个下降沿信号,当松开所按下的按键就会在EXINT0端产生一个上升沿信号,因此,只要设置单片机的外部中断触发方式为下降沿触发即可实现按键中断。单片机检测到按键中断后,再来读取KEY0---KEY4的按键值,判断具体的按下的按键。
图3-7 按键读取电路
3.4 电源设计
本系统的电源设计如图3-8所示,这是直接通过交流220VAC市电给系统供电的电路原理图。接线端子P2接交流市电,F1位过流保护熔断丝,T1为工频变压器,本设计选用220VAC输入,9VAC输出,功率为5VA的交流降压变压器即可满足需要,变压器的将220VAC输入降压位9VAC输出,经过整流桥和平波电容C12后,转换为直流电,因为变压器的输出9VAC是交流有效值,其交流峰值电压为
从变压器的输出端看变压器的输入端,整个电网相当于一个无限大功率系统,所以整流后的输出直流电压也为12.7V左右。
整流和滤波后的输出电压高达12.7V不能直接供给单片机系统,本设计采用了一片线性稳压芯片LM7805稳压后作为单片机系统的供电。用LM78/LM79系列三端稳压IC来组成稳压电源所需的外围元件极少,电路部还有过流、过热与调整管的保护电路,使用起来可靠、方便,而且价格便宜。图3-8中电源输出端并联了一个100uF电解电容,用于平波和储能,两个0.1uF的瓷片电容用于抑制数字电路工作的时候产生的高频噪声,提高电源的质量。
图3-8 电源电路图
在实际的数字钟应用中,考虑到计时的可靠性,需要系统能够长期不断电运行,这就需要在系统电源中加上应急供电部分。如图3-9所示,采用一个电池和抑制低压降二极管,即可实现对数字钟系统的不间断供电,为了降低电池的利用效率,这里的二极管可以采用压降只有0.2V的锗二极管,因为整个系统的工作电流较小,在设计的时候在电池上串联了一只100Ω的电阻,用于在单片机系统电源短路的时候保护电池不会因为过流和过热被烧坏。
图3-9 电池供电电路
第四章 系统软件设计
系统的软件设计主要包括5个模块,分别是按键读取模块、LED显示驱动模块、计时模块、秒表模块和控制模块。
4.1按键读取程序设计
按键读取模块的程序流程图如图4-1所示,从流程图可以看出,这就是一个简单的中断服务程序框图,当读取到按键值后,再根据当前的工作模式和状态来确定下一步的工作状态。
进入中断
退出中断
读取按键值
根据当前工作模式和按键值确定按键功能
图4-1 按键读取程序流程图
4.1.1 模式选择按键程序解析
以下是模式选择按钮按下后的程序反应,总共定义了四种工作模式,分别表示为0x01、0x02、0x04和0x08,按下“模式选择”按钮后,通过当前模式变量CurrentModle左移一位来切换工作模式,当切换到0x08后先一步自动回到0x01模式。
#define DctModle 0x08
#define ClkModle 0x04
#define CntModle 0x02
#define SetModle 0x01
if(Keytemp == 0x08)
{
CurrentModle<<=1;
if(CurrentModle>0x08)
CurrentModle=0x01;
}
4.1.2 确定/清零按钮程序解析
系统的“确定/清零”按钮主要有三个功能,分别如下程序所示,当前模式为时间初始设置模式,按下“确定/清零”按钮后,系统将设定的时间零时初值写入到时间值,并将当前模式切换到时钟模式。
当前模式为增计数模式时,按下“确定/清零”按钮后,系统会将计数值归零。
当前模式为减计数模式时,按下“确定/清零”按钮后,系统会清零减计数值,并停止减计数器工作。
if(Keytemp == 0x01)
{
if(CurrentModle == SetModle)
{
CLKTime[0] = CLKTemp[0];
CLKTime[1] = CLKTemp[1];
CLKTime[2] = CLKTemp[2];
CLKTime[3] = CLKTemp[3];
CLKTime[4] = CLKTemp[4];
CLKTime[5] = CLKTemp[5];
CurrentModle = ClkModle;
}
else if(CurrentModle == CntModle)
{
CLKCnt[0]=0;
CLKCnt[1]=0;
CLKCnt[2]=0;
CLKCnt[3]=0;
CLKCnt[4]=0;
CLKCnt[5]=0;
}
else if(CurrentModle == DctModle)
{
CLKDct[0]=0;
CLKDct[1]=0;
CLKDct[2]=0;
CLKDct[3]=0;
CLKDct[4]=0;
CLKDct[5]=0;
DctRunning=0;
}
4.1.3 设定位选择按钮程序解析
系统的“设定位选择”按钮程序如下,这个按钮只在时钟初值设置模式和减计数模式初值设定时有作用。当在初值设定模式下,将当前的设定位加一,如果设定位超过了最高位,则自动跳转到最低位,这两种模式下的初值设定用了一样的变量。
if(Keytemp == 0x02)
{
if(CurrentModle == SetModle)
{
if(++CurrentDig>=0x06)
CurrentDig=0;
}
else if(CurrentModle == DctModle)
{
if(++CurrentDig>=0x06)
CurrentDig=0;
}
}
4.1.4 开始/暂停计时按钮程序解析
系统的“开始/暂停计时”按钮的程序如下,该按钮只在增计时和减计时模式下有作用,并且在这两种模式下的功能都一样,即将变量CntRunning和DctRunning清零和置一,如果变量当前值为一,则清零,如果变量当前值位零,则置一。
if(Keytemp == 0x10)
{
if(CurrentModle == CntModle)
{
if(CntRunning)
CntRunning=0;
else
CntRunning=1;
}
else if(CurrentModle == DctModle)
{
if(DctRunning)
DctRunning=0;
else
DctRunning=1;
}
}
4.1.5 加按钮程序解析
系统的“加”按钮程序如下所示,主要在当前模式为时钟初值设定模式,或者位减计数模式并且减计数没有开始计时的工作状态下有作用。在时钟初值设定模式下,根据CurrentDig变量的值来确定调整的数据位,在小时为调整的过程中,需要考虑到小时为的十位为2的时候,个位需要满4进1,而在小时的十位为0或者1的时候,个位需要满10进1。在减计数初值设定的时候,利用减计数工作状态变量DctRunning来确定是否开启设定计数设定功能,当减计数功能正在运行的时候,关闭初值设定功能。
if(Keytemp == 0x04)
{
if(CurrentModle == SetModle)
{
if(CurrentDig==0){if(++CLKTemp[0]>=3) CLKTemp[0]=0; }
else if(CurrentDig == 1) {
if(CLKTemp[0]==2){ if(++CLKTemp[1]>=4) CLKTemp[1]=0; }
else{if(++CLKTemp[1]>=10) CLKTemp[1]=0; }
}
else if(CurrentDig == 2) { if(++CLKTemp[2]>=6) CLKTemp[2]=0; }
else if(CurrentDig == 3) { if(++CLKTemp[3]>=10) CLKTemp[3]=0; }
else if(CurrentDig == 4) { if(++CLKTemp[4]>=6) CLKTemp[4]=0; }
else if(CurrentDig == 5) { if(++CLKTemp[5]>=10) CLKTemp[5]=0; }
}
else if((CurrentModle == DctModle)&&(DctRunning==0))
{
if(CurrentDig==0){ if(++CLKDct[0]>=6) CLKDct[0]=0;}
else if(CurrentDig == 1){ if(++CLKDct[1]>=10) CLKDct[1]=0;}
else if(CurrentDig == 2) { if(++CLKDct[2]>=6)CLKDct[2]=0; }
else if(CurrentDig == 3) { if(++CLKDct[3]>=10) CLKDct[3]=0; }
else if(CurrentDig == 4) { if(++CLKDct[4]>=10) CLKDct[4]=0; }
else if(CurrentDig == 5) { if(++CLKDct[5]>=10) CLKDct[5]=0; }
}
}
4.2 LED显示驱动程序设计
数码管显示程序如下所示,本设计采用C语言和汇编语言交叉调用的方式来显示数字,在系统顶层调用Display(unsigned char dig,unsigned char dat),即可控制数码管显示,其中参数dig位显示位选择,围为0---5,参数dat为显示的数字,从0---9,函数过一个switch语句来实现共阳极数码管显示码的译码,当显示码译码后,需要将显示码写到对应外部地址的数码管驱动芯片中,本设计在Display()函数中调用了汇编函数_ Place来实现数据输出,双参数传递用到了R5和R7两个寄存器。
#define One 0x0f9
#define Two 0x0a4
#define Thr 0x0b0
#define Fur 0x99
#define Fiv 0x92
#define Six 0x82
#define Sev 0x0f8
#define Egt 0x80
#define Nin 0x90
#define Zer 0x0c0
void Display(unsigned char dig,unsigned char dat)
{ unsigned char datatemp;
switch(dat) {
case 0:datatemp=Zer;break;
case 1:datatemp=One;break;
case 2:datatemp=Two;break;
case 3:datatemp=Thr;break;
case 4:datatemp=Fur;break;
case 5:datatemp=Fiv;break;
case 6:datatemp=Six;break;
case 7:datatemp=Sev;break;
case 8:datatemp=Egt;break;
case 9:datatemp=Nin; }
Place(dig,datatemp);
}
_ Place:
MOVA,R7
ADD A,#10h
MOVDPH,A
clr A
MOVDPL,A
MOVA,R5
MOVX DPTR,A
RET
4.3 计时程序设计
本设计中,单片机晶振采用了最常用的12MHz无源晶振,单片机计数器的时钟输入信号频率为晶振频率的12分频,即1MHz,如果要得到1kHz信号,即1mS延时,需要单片机的计数器对1MHz的信号进行1000分频。
为了提高时钟的精度,设置单片机的计数模式为自动重载模式,即TL0用于计数,TH0用于存放计数器初值,当计数到零后,系统自动将TH0中的计数初值加载到TL0中,不用CPU的干预,也不会中断时钟计数,很好地提高了系统的计时精度。这种模式下,计数器的最大计数值只有256,所以在对1MHz信号1000分频的时候,需要的定时器自动重载次数至少为
所以,需要定时器至少重载4次,每次计数值为
设置好计数器的计数初值后,计数器每中断4就是1mS时间到,在中断服务程序中实现时、分、秒和毫秒的进位运算,在每次进位产生的时候讲相应的标识为置一,用于在主控制模块中控制增计数和减计数的运行。
4.4控制模块程序设计
系统的主控制模块主要完成三部分的工作,即在每次10mS位加一时,完成增计时功能的10mS位加一,完成减计时功能的10mS位减一,以与各模式下的显示容的切换。
以下是主控制程序主循环中的增计时程序,当每个10mS信号到来之后,如果增计时功能正在运行,即CntRunning被置一了,那么增计数值就会累加,以下程序主要完成计数值累加和进位。
if(CntRunning) {
if(++CLKCnt[5]>9) { CLKCnt[5]=0;
if(++CLKCnt[4]>9) { CLKCnt[4]=0;
if(++CLKCnt[3]>9) { CLKCnt[3]=0;
if(++CLKCnt[2]>5) { CLKCnt[2]=0;
if(++CLKCnt[1]>9) { CLKCnt[1]=0;
if(++CLKCnt[0]>5) CL
展开阅读全文