多功能数字钟
题目:多功能数码种的设计
一、设计目的
数字钟是一种用数字电路技术实现时、分、秒计时的装置,与机械式时钟相比具有更高的准确性和直观性,且无机械装置,具有更更长的使用寿命,因此得到了广泛的使用。
数字钟从原理上讲是一种典型的数字电路,其中包括了组合逻辑电路和时序电路。
因此,我们此次设计数字钟就是为了了解数字钟的原理,从而学会制作数字钟.而且通过数字钟的制作进一步的了解各种在制作中用到的中小规模集成电路的作用及实用方法.且由于数字钟包括组合逻辑电路和时叙电路.通过它可以进一步学习与掌握各种组合逻辑电路与时序电路的原理与使用方法.
三、原理框图
1.数字钟的构成
数字钟实际上是一个对标准频率(1HZ)进行计数的计数电路。由于计数的起始时间不可能与标准时间(如北京时间)一致,故需要在电路上加一个校时电路,同时标准的1HZ时间信号必须做到准确稳定。通常使用石英晶体振荡器电路构成数字钟。
(a) 数字钟组成框图
2.晶体振荡器电路
晶体振荡器电路给数字钟提供一个频率稳定准确的32768Hz的方波信号,可保证数字钟的走时准确及稳定。不管是指针式的电子钟还是数字显示的电子钟都使用了晶体振荡器电路。一般输出为方波的数字式晶体振荡器电路通常有两类,一类是用TTL门电路构成;另一类是通过CMOS非门构成的电路,本次设计采用了后一种。如图(b)所示,由CMOS非门U1与晶体、电容和电阻构成晶体振荡器电路,U2实现整形功能,将振荡器输出的近似于正弦波的波形转换为较理想的方波。输出反馈电阻R1为非门提供偏置,使电路工作于放大区域,即非门的功能近似于一个高增益的反相放大器。电容C1、C2与晶体构成一个谐振型网络,完成对振荡频率的控制功能,同时提供了一个180度相移,从而和非门构成一个正反馈网络,实现了振荡器的功能。由于晶体具有较高的频率稳定性及准确性,从而保证了输出频率的稳定和准确。
(b) CMOS 晶体振荡器(仿真电路)
3.时间记数电路
一般采用10进制计数器如74HC290、74HC390等来实现时间计数单元的计数功能。本次设计中选择74HC390。由其内部逻辑框图可知,其为双2-5-10异步计数器,并每一计数器均有一个异步清零端(高电平有效)。
秒个位计数单元为10进制计数器,无需进制转换,只需将QA与CPB(下降沿有效)相连即可。CPA(下降没效)与1HZ秒输入信号相连,Q3可作为向上的进位信号与十位计数单元的CPA相连。
秒十位计数单元为6进制计数器,需要进制转换。将10进制计数器转换为6进制计数器的电路连接方法如图 2.4所示,其中Q2可作为向上的进位信号与分个位的计数单元的CPA相连。
十进制-六进制转换电路
分个位和分十位计数单元电路结构分别与秒个位和秒十位计数单元完全相同,只不过分个位计数单元的Q3作为向上的进位信号应与分十位计数单元的CPA相连,分十位计数单元的Q2作为向上的进位信号应与时个位计数单元的CPA相连。
时个位计数单元电路结构仍与秒或个位计数单元相同,但是要求,整个时计数单元应为12进制计数器,不是10的整数倍,因此需将个位和十位计数单元合并为一个整体才能进行12进制转换。利用1片74HC390实现12进制计数功能的电路如图(d)所示。
(d)十二进制电路
另外,图(d)所示电路中,尚余-2进制计数单元,正好可作为分频器2HZ输出信号转化为1HZ信号之用。
4.译码驱动及显示单元电路
选择CD4511作为显示译码电路;选择LED数码管作为显示单元电路。由CD4511把输进来的二进制信号翻译成十进制数字,再由数码管显示出来。这里的LED数码管是采用共阴的方法连接的。
计数器实现了对时间的累计并以8421BCD码的形式输送到CD4511芯片,再由4511芯片把BCD码转变为十进制数码送到数码管中显示出来。
5.校时电路
数字钟应具有分校正和时校正功能,因此,应截断分个位和时个位的直接计数通路,并采用正常计时信号与校正信号可以随时切换的电路接入其中。即为用COMS与或非门实现的时或分校时电路,In1端与低位的进位信号相连;In2端与校正信号相连,校正信号可直接取自分频器产生的1HZ或2HZ(不可太高或太低)信号;输出端则与分或时个位计时输入端相连。当开关打向下时,因为校正信号和0相与的输出为0,而开关的另一端接高电平,正常输入信号可以顺利通过与或门,故校时电路处于正常计时状态;当开关打向上时,情况正好与上述相反,这时校时电路处于校时状态。
实际使用时,因为电路开关存在抖动问题,所以一般会接一个RS触发器构成开关消抖动电路,所以整个较时电路就如图(f)。
(f)带有消抖电路的校正电路
6.整点报时电路
电路应在整点前10秒钟内开始整点报时,即当时间在59分50秒到59分59秒期间时,报时电路报时控制信号。
当时间在59分50秒到59分59秒期间时,分十位、分个位和秒十位均保持不变,分别为5、9和5,因此可将分计数器十位的QC和QA 、个位的QD和QA及秒计数器十位的QC和QA相与,从而产生报时控制信号。
报时电路可选74HC30来构成。74HC30为8输入与非门。
四、元器件
4.共阴八段数码管6个
5.网络线2米/人
6.CD4511集成块6块
7.CD4060集成块1块
8.74HC390集成块3块
9.74HC51集成块1块
10.74HC00集成块4块
11.74HC30集成块1块
12.10MΩ电阻5个
13.500Ω电阻14个
14.30p电容2个
15.32.768k时钟晶体1个
16.蜂鸣器10个
五、各功能块电路图
数字钟从原理上讲是一种典型的数字电路,可以由许多中小规模集成电路组成,所以可以分成许多独立的电路。
(一) 六进制电路
由74HC390、7400、数码管与4511组成,电路如图一。
(二) 十进制电路
由74HC390、7400、数码管与4511组成,电路如图二。
(三) 六十进制电路
由两个数码管、两4511、一个74HC390与一个7400芯片组成,电路如图三。
(四) 双六十进制电路
由2个六十进制连接而成,把分个位的输入信号与秒十位的Qc相连,使其产生进位,电路图如图四。
(五) 时间计数电路
由1个十二进制电路、2个六十进制电路组成,因上面已有一个双六十电路,只要把它与十二进制电路相连即可,详细电路见图五。
(六) 校正电路
由74CH51D、74HC00D与电阻组成,校正电路有分校正和时校正两部分,电路如图六。
(七) 晶体振荡电路
由晶体与2个30pF电容、1个4060、一个10兆的电阻组成,芯片3脚输出2Hz的方波信号,电路如图七。
(八) 整点报时电路
由74HC30D和蜂鸣器组成,当时间在59:50到59:59时,蜂鸣报时,电路如图八。
数字电子钟的设计
一、 绪论
(一)引言
20世纪末,电子技术获得了飞速的发展,在其推动下,现代电子产品几乎渗透了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能进一步提高,产品更新换代的节奏也越来越快。
时间对人们来说总是那么宝贵,工作的忙碌性和繁杂性容易使人忘记当前的时间。忘记了要做的事情,当事情不是很重要的时候,这种遗忘无伤大雅。但是,一旦重要事情,一时的耽误可能酿成大祸。例如,许多火灾都是由于人们一时忘记了关闭煤气或是忘记充电时间。尤其在医院,每次护士都会给病人作皮试,测试病人是否对药物过敏。注射后,一般等待5分钟,一旦超时,所作的皮试试验就会无效。手表当然是一个好的选择,但是,随着接受皮试的人数增加,到底是哪个人的皮试到时间却难以判断。所以,要制作一个定时系统。随时提醒这些容易忘记时间的人。
钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能。诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、定时启闭电路、定时开关烘箱、通断动力设备,甚至各种定时电气的自动启用等,所有这些,都是以钟表数字化为基础的。因此,研究数字钟及扩大其应用,有着非常现实的意义。
(二)论文的研究内容和结构安排
本系统采用石英晶体振荡器、分频器、计数器、显示器和校时电路组成。由LED数码管来显示译码器所输出的信号。采用了74LS系列中小规模集成芯片。使用了RS触发器的校时电路。总体方案设计由主体电路和扩展电路两大部分组成。其中主体电路完成数字钟的基本功能,扩展电路完成数字钟的扩展功能。论文安排如下:
1、绪论 阐述研究电子钟所具有的现实意义。
2、设计内容及设计方案 论述电子钟的具体设计方案及设计要求。
3、单元电路设计、原理及器件选择 说明电子钟的设计原理以及器件的选择,主要从石英晶体振荡器、分频器、计数器、显示器和校时电路五个方面进行说明。
4、绘制整机原理图 该系统的设计、安装、调试工作全部完成。
二、设计内容及设计方案
(一)设计内容要求
1、设计一个有“时”、“分”、“秒”(23小时59分59秒)显示且有校时功能的电子钟。
2、用中小规模集成电路组成电子钟,并在实验箱上进行组装、调试。
3、画出框图和逻辑电路图。
4 、功能扩展:
(1)闹钟系统
(2)整点报时。在59分51秒、53秒、55秒、57秒输出750Hz音频信号,在59分59秒时,输出1000Hz信号,音像持续1秒,在1000Hz音像结束时刻为整点。
(3)日历系统。
(二)设计方案及工作原理
数字电子钟的逻辑框图如图1所示。它由石英晶体振荡器、分频器、计数器、译码器显示器和校时电路组成。振荡器产生稳定的高频脉冲信号,作为数字钟的时间基准,然后经过分频器输出标准秒脉冲。秒计数器满60后向分计数器进位,分计数器满60后向小时计数器进位,小时计数器按照“24翻1”规律计数。计数器的输出分别经译码器送显示器显示。计时出现误差时,可以用校时电路校时、校分。
图1 数字电子钟逻辑框图
三、单元电路设计、原理及器件选择
(一)石英晶体振荡器
1、重要概念的解释
(1) 反馈:将放大电路输出量的一部分或全部,通过一定的方式送回放大电路的输入端。
(2) 耦合:是指信号由第一级向第二级传递的过程。
2、石英晶体振荡器的具体工作原理
石英晶体振荡器的特点是振荡频率准确、电路结构简单、频率易调整。它被广泛应用于彩电、计算机、遥控器等各类振荡电路中。它还具有压电效应:在晶体某一方向加一电场,晶体就会产生机械变形;反之,若在晶片的两侧施加机械压力,则在晶片相应的方向上将产生电场,这种物理现象称为压电效应。在这里,我们在晶体某一方向加一电场,从而在与此垂直的方向产生机械振动,有了机械振动,就会在相应的垂直面上产生电场,从而使机械振动和电场互为因果,这种循环过程一直持续到晶体的机械强度限制时,才达到最后稳定,这种压电谐振的频率即为晶体振荡器的固有频率。
用反相器与石英晶体构成的振荡电路如图2所示。利用两个非门G1和G2 自我反馈,使它们工作在线性状态,然后利用石英晶体JU来控制振荡频率,同时用电容C1来作为两个非门之间的耦合,两个非门输入和输出之间并接的电阻R1和R2作为负反馈元件用,由于反馈电阻很小,可以近似认为非门的输出输入压降相等。电容C2是为了防止寄生振荡。例如:电路中的石英晶体振荡频率是4MHz时,则电路的输出频率为4MHz。
图2 石英晶体振荡电路
(二)分频器
1、8421码制,5421码制
用四位二进制码的十六种组合作为代码,取其中十种组合来表示0-9这十个数字符号。通常,把用四位二进制数码来表示一位十进制数称为二-十进制编码,也叫做BCD码,见表1。
表1
8421码 5421码
0 0000 0000
1 0001 0001
2 0010 0010
3 0011 0011
4 0100 0100
5 0101 1000
6 0110 1001
7 0111 1010
8 1000 1011
9 1001 1100
2、分频器的具体工作原理
由于石英晶体振荡器产生的频率很高,要得到秒脉冲,需要用分频电路。例如,振荡器输出4MHz信号,通过D触发器(74LS74)进行4分频变成1MHz,然后送到10分频计数器(74LS90,该计数器可以用8421码制,也可以用5421码制),经过6次10分频而获得1Hz方波信号作为秒脉冲信号。(见图3)
图3 分频电路
3、图中标志的含义
CP——输入的脉冲信号
C0——进位信号
Q——输出的脉冲信号
(三)计数器
秒脉冲信号经过6级计数器,分别得到“秒”个位、十位,“分”个位、十位以及“时”个位、十位的计时。“秒”、“分”计数器为60进制,小时为24进制。
1、60进制计数器
(1) 计数器按触发方式分类
计数器是一种累计时钟脉冲数的逻辑部件。计数器不仅用于时钟脉冲计数,还用于定时、分频、产生节拍脉冲以及数字运算等。计数器是应用最广泛的逻辑部件之一。按触发方式,把计数器分成同步计数器和异步计数器两种。对于同步计数器,输入时钟脉冲时触发器的翻转是同时进行的,而异步计数器中的触发器的翻转则不是同时。
(2)60进制计数器的工作原理
“秒”计数器电路与“分”计数器电路都是60进制,它由一级10进制计数器和一级6进制计数器连接构成,如图4所示,采用两片中规模集成电路74LS90串接起来构成的“秒”、“分”计数器。
图4 60进制计数电路
IC1是十进制计数器,QD1作为十进制的进位信号,74LS90计数器是十进制异步计数器,用反馈归零方法实现十进制计数,IC2和与非门组成六进制计数。74LS90是在CP信号的下降沿翻转计数,Q A1和 Q C2相与0101的下降沿,作为“分”(“时”)计数器的输入信号,通过与非门和非门对下一级计数器送出一个高电平1(在此之前输出的一直是低电平0)。Q B2 和Q C2计数到0110,产生的高电平1分别送到计数器的清零R0(1), R0(2),74LS90内部的R0(1)和R0(2)与非后清零而使计数器归零,此时传给下一级计数器的输入信号又变为低电平0,从而给下一级计数器提供了一个下降沿,使下一级计数器翻转计数,在这里IC2完成了六进制计数。由此可见IC1和 IC2串联实现了六十进制计数。
其中:74LS90——可二/五分频十进制计数器
74LS04——非门
74LS00——二输入与非门
2、24进制计数器
小时计数电路是由IC5和IC6组成的24进制计数电路,如图5所示。
当“时”个位IC5计数输入端CP5来到第10个触发信号时,IC5计数器自动清零,进位端QD5向IC6“时”十位计数器输出进位信号,当第24个“时”(来自“分”计数器输出的进位信号)脉冲到达时,IC5计数器的状态为“0100”,IC6计数器的状态为“0010”,此时“时”个位计数器的QC5和“时”十位计数器的QB6输出为“1”。把它们分别送到IC5和IC6计数器的清零端R0(1)和R0(2),通过7490内部的R0(1)和R0(2)与非后清零,从而完成24进制计数。
图5 24进制计数电路
(四) 译码与显示电路
1、显示器原理(数码管)
数码管是数码显示器的俗称。常用的数码显示器有半导体数码管,荧光数码管,辉光数码管和液晶显示器等。
本设计所选用的是半导体数码管,是用发光二极管(简称LED)组成的字形来显示数字,七个条形发光二极管排列成七段组合字形,便构成了半导体数码管。半导体数码管有共阳极和共阴极两种类型。共阳极数码管的七个发光二极管的阳极接在一起,而七个阴极则是独立的。共阴极数码管与共阳极数码管相反,七个发光二极管的阴极接在一起,而阳极是独立的。
当共阳极数码管的某一阴极接低电平时,相应的二极管发光,可根据字形使某几段二极管发光,所以共阳极数码管需要输出低电平有效的译码器去驱动。共阴极数码管则需输出高电平有效的译码器去驱动。
2、译码器原理(74LS47)
译码为编码的逆过程。它将编码时赋予代码的含义“翻译”过来。实现译码的逻辑电路成为译码器。译码器输出与输入代码有唯一的对应关系。74LS47是输出低电平有效的七段字形译码器,它在这里与数码管配合使用,表2列出了74LS47的真值表,表示出了它与数码管之间的关系。
表2
输 入 输 出 显示数字符号
LT(——) RBI(——-) A3 A2 A1 A0 BI(—)/RBO(———)
a(—) b(—) c(—) d(—) e(—) f(—) g(—)
1 1 0 0 0 0 1 0 0 0 0 0 0 1 0
1 X 0 0 0 1 1 1 0 0 1 1 1 1 1
1 X 0 0 1 0 1 0 0 1 0 0 1 0 2
1 X 0 0 1 1 1 0 0 0 0 1 1 0 3
1 X 0 1 0 0 1 1 0 0 1 1 0 0 4
1 X 0 1 0 1 1 0 1 0 0 1 0 0 5
1 X 0 1 1 0 1 1 1 0 0 0 0 0 6
1 X 0 1 1 1 1 0 0 0 1 1 1 1 7
1 X 1 0 0 0 1 0 0 0 0 0 0 0 8
1 X 1 0 0 1 1 0 0 0 1 1 0 0 9
X X X X X X 0 1 1 1 1 1 1 1 熄灭
1 0 0 0 0 0 0 1 1 1 1 1 1 1 熄灭
0 X X X X X 1 0 0 0 0 0 0 0 8
(1)LT(——):试灯输入,是为了检查数码管各段是否能正常发光而设置的。当LT(——)=0时,无论输入A3 ,A2 ,A1 ,A0为何种状态,译码器输出均为低电平,若驱动的数码管正常,是显示8。
(2)BI(—):灭灯输入,是为控制多位数码显示的灭灯所设置的。BI(—)=0时。不论LT(——)和输入A3 ,A2 ,A1,A0为何种状态,译码器输出均为高电平,使共阳极数码管熄灭。
(3)RBI(——-):灭零输入,它是为使不希望显示的0熄灭而设定的。当对每一位A3= A2 =A1 =A0=0时,本应显示0,但是在RBI(——-)=0作用下,使译码器输出全为高电平。其结果和加入灭灯信号的结果一样,将0熄灭。
(4)RBO(———):灭零输出,它和灭灯输入BI(—)共用一端,两者配合使用,可以实现多位数码显示的灭零控制。
3、译码器与显示器的配套使用
译码是把给定的代码进行翻译,本设计即是将时、分、秒计数器输出的四位二进制数代码翻译为相应的十进制数,并通过显示器显示,通常显示器与译码器是配套使用的。我们选用的七段译码驱动器(74LS47)和数码管(LED)是共阳极接法(需要输出低电平有效的译码器驱动)。译码显示电路如图6所示。
图6 译码显示电路
(五)校时电路
1、RS触发器(见图7)
图7 基本RS触发器
R(—) S(—)
Q Q(—)
说 明
0 1
1 0
1 1
0 0 0
1
0或1
1 1
0
1或0
1 置0
置1
保持原来状态
不正常状态,0信号消失后,触发器状态不定
2、无震颤开关电路
无震颤开关电路的原理:(见图8)当开关K的刀扳向1点时,S(—)=0,R(—)=1,触发器置1。S(—)端由于开关K的震颤而断续接地几次时,也没有什么影响,触发器置1后将保持1状态不变。因为K震颤只是使S(—)端离开地,而不至于使R(—)端接地,触发器可靠置1。
当开关K从S(—)端扳向R(—)端时,有同样的效果,触发器可靠置0。从Q端或Q(—)端反映开关的动作,输出电平是稳定的。
3、校时电路的实现原理
当电子钟接通电源或者计时发现误差时,均需要校正时间。校时电路分别实现对时、分的校准,由于4个机械开关具有震颤现象,因此用RS触发器作为去抖动电路。采用RS基本触发器及单刀双掷开关,闸刀常闭于2点,每搬动一次产生一个计数脉冲,实现校时功能,电路如图8所示。
图8 校时电路
(六)调 试
毕满清等.电子技术实验与课程设计.北京:机械工业出
版社,1995.131~132
这本书上很全
module clock(clk,rst,set, set_typ, set_data, yr, mon, dt, hr, min, sec,
alarm_en, alm_typ, alm_yr, alm_mon, alm_dt, alm_hr, alm_min, alm_sec, alarm_output)
input clk,rst,set
input [2:0] set_typ //
input [6:0] set_data//
output [6:0] yr, mon, dt, hr, min, sec
input alarm_en
input [2:0] alm_typ //
input [6:0] alm_yr, alm_mon, alm_dt, alm_hr, alm_min, alm_sec
output alarm_output
parameter C_FR= 32'd20_000_000-32'd1 //定义系统时钟20MHz
reg [31:0] fr_cnt
reg [3:0] sec_cnt
reg pp1s //秒脉冲
//==================================================
//fr_cnt
always@(posedge clk)//
if(!rst)
fr_cnt <= 32'b0
else if (fr_cnt >= C_FR)
fr_cnt <= 32'b0
else
fr_cnt <= fr_cnt + 1'b1
//pp1s
always@(posedge clk)//
if(!rst)
pp1s <= 1'b0
else if (fr_cnt == C_FR)
pp1s <= 1'b1
else
pp1s <= 1'b0
///time counter
always@(posedge clk)
if(!rst)
begin
yr <= 7'b0
mon <= 7'b0
dt <= 7'b0
hr <= 7'b0
min <= 7'b0
sec <= 7'b0
end
else if (set)
begin
case (set_typ)
3'b000: yr <= set_data
3'b001: mon <= set_data
3'b010: dt <= set_data
3'b011: hr <= set_data
3'b100: min <= set_data
3'b101: sec <= set_data
end
else if (pp1s)
begin
if (sec >= 7'd59)
sec <= 7'd0
else
sec <= sec + 1'b1
if (sec >= 7'd59)
begin
if (min >= 7'd59)
min <= 7'd0
else
min <= min + 1'b1
end
if (sec >= 7'd59 &&min >= 7'd59)
begin
if (hr >= 7'd23)
hr <= 7'd0
else
hr <= hr + 1'b1
end
///data,mon, year, 大月小月,闰年等,依此类推
//
end
//=================================
//alarm
always@(posedge clk)
if(!rst)
alarm_output <= 1'b0
else if (alarm_en)
case (alm_typ)
3'b000:
if (yr == alm_yr &&mon == alm_mon &&dt == alm_dt &&hr == alm_hr &&min == alm_min &&sec == alm_sec)
alarm_output <= 1'b1
else
alarm_output <= 1'b0
3'b001:
if (mon == alm_mon &&dt == alm_dt &&hr == alm_hr &&min == alm_min &&sec == alm_sec)
alarm_output <= 1'b1
else
alarm_output <= 1'b0
3'b010:
if (dt == alm_dt &&hr == alm_hr &&min == alm_min &&sec == alm_sec)
alarm_output <= 1'b1
else
alarm_output <= 1'b0
3'b011:
if (hr == alm_hr &&min == alm_min &&sec == alm_sec)
alarm_output <= 1'b1
else
alarm_output <= 1'b0
3'b100:
if (min == alm_min &&sec == alm_sec)
alarm_output <= 1'b1
else
alarm_output <= 1'b0
default
alarm_output <= 1'b0
endcase
endmodule
摘 要 I
Abstract II
目录 III
第一章 绪 论 - 1 -
1.1课题的背景 - 1 -
1.2课题意义 - 2 -
1.3本章小结 - 3 -
第二章 总体设计方案与论证 - 4 -
2.1 电源模块方案的选择与论证 - 4 -
2.2 时钟电路方案的选择与论证 - 4 -
2.3 显示电路方案的选择与论证 - 5 -
2.4 闹钟电路方案的选择与论证 - 5 -
2.5 键扫描电路方案的选择与论证 - 6 -
2.6 本章小结 - 6 -
第三章 系统硬件设计 - 7 -
3.1 主控芯片STC89C52的介绍 - 7 -
3.1.1 STC89C52的主要性能参数 - 7 -
3.1.2 STC89C52单片机的功能特性概述: - 8 -
3.2时钟部分功能介绍及电路设计 - 11 -
3.3显示模块功能介绍及电路设计 - 14 -
3.4闹钟电路模块介绍及电路设计 - 16 -
3.5功能按键模块介绍及电路设计 - 17 -
3.6电源模块介绍及电路设计 - 17 -
3.7 本章小结 - 18 -
第四章 系统软件设计 - 19 -
4.1日历程序设计 - 19 -
4.2 时间调整程序设计 - 20 -
4.3 闹钟设置程序设计 - 22 -
4.4 闹钟蜂鸣程序设计 - 23 -
4.5本章小结 - 23 -
第五章 系统调试 - 24 -
5.1系统的调试 - 24 -
5.2系统的调试出现的问题及解决 - 24 -
5.3本章小结 - 24 -
第六章 结 论 - 25 -
参考文献 - 26 -
致 谢 - 27 -
附录 - 28 -
附录一 :本设计电路原理图 - 28 -
附录二:数字日历钟电路设计的C程序 - 29 -
源代码如下 自己把各个模块打好包 下面有个图 自己看看
LIBRARY IEEE
USE IEEE.STD_LOGIC_1164.ALL
USE IEEE.STD_LOGIC_UNSIGNED.ALL
ENTITY TZKZQ IS
PORT(KEY: IN STD_LOGIC_VECTOR(1 DOWNTO 0) --按键信号
CLK_KEY: IN STD_LOGIC --键盘扫描信号
MAX_DAYS:IN STD_LOGIC_VECTOR(4 DOWNTO 0) --本月最大天数
SEC_EN,MIN_EN,HOUR_EN,DAY_EN,MON_EN,YEAR_EN,WEEK_EN:OUT STD_LOGIC --异步并行置位使能
HOUR_CUR:IN STD_LOGIC_VECTOR(4 DOWNTO 0)
MIN_CUR,SEC_CUR:IN STD_LOGIC_VECTOR(5 DOWNTO 0)
YEAR_CUR:IN STD_LOGIC_VECTOR(6 DOWNTO 0)
MON_CUR :IN STD_LOGIC_VECTOR(3 DOWNTO 0)
DAY_CUR :IN STD_LOGIC_VECTOR(4 DOWNTO 0)
WEEK_CUR:IN STD_LOGIC_VECTOR(2 DOWNTO 0)
SEC,MIN:BUFFER STD_LOGIC_VECTOR(5 DOWNTO 0)
HOUR:BUFFER STD_LOGIC_VECTOR(4 DOWNTO 0)
DAY :BUFFER STD_LOGIC_VECTOR(4 DOWNTO 0)
MON :BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0)
YEAR:BUFFER STD_LOGIC_VECTOR(6 DOWNTO 0)
WEEK:BUFFER STD_LOGIC_VECTOR(2 DOWNTO 0))
END ENTITY TZKZQ
ARCHITECTURE ART OF TZKZQ IS
TYPE STATETYPE IS (NORMAL,SEC_SET,MIN_SET,HOUR_SET,DAY_SET,MON_SET,
YEAR_SET,WEEK_SET)
SIGNAL MODE:STATETYPE
BEGIN
PROCESS(KEY,CLK_KEY)
BEGIN
IF CLK_KEY'EVENT AND CLK_KEY='1' THEN
IF KEY="01" THEN
SEC_EN<='1'MIN_EN<='1'HOUR_EN<='1'
DAY_EN<='1'MON_EN<='1'YEAR_EN<='1'
WEEK_EN<='1'
CASE MODE IS
WHEN NORMAL => MODE<=SEC_SETSEC<=SEC_CURSEC_EN<='0'
WHEN SEC_SET => MODE<=MIN_SETMIN<=MIN_CURSEC_EN<='1'MIN_EN<='0'
WHEN MIN_SET => MODE<=HOUR_SETHOUR<=HOUR_CURMIN_EN<='1'HOUR_EN<='0'
WHEN HOUR_SET=> MODE<=DAY_SETDAY<=DAY_CURHOUR_EN<='1'DAY_EN<='0'
WHEN DAY_SET => MODE<=MON_SETMON<=MON_CURDAY_EN<='1'MON_EN<='0'
WHEN MON_SET => MODE<=YEAR_SETYEAR<=YEAR_CUR MON_EN<='1'
YEAR_EN<='0'
WHEN YEAR_SET => MODE<=WEEK_SETWEEK<=WEEK_CURYEAR_EN<='1'WEEK_EN<='0'
WHEN WEEK_SET => MODE<=NORMAL
END CASE
ELSIF KEY="10" THEN --如果按下调整键,则自加
CASE MODE IS
WHEN SEC_SET => SEC_EN<='0'
--异步并行置位使能有效
IF SEC="111011" THEN SEC<="000000"
--如果秒计数到59,返回到0重新计数
ELSE SEC<=SEC+1 --否则继续计数
END IF
WHEN MIN_SET => MIN_EN<='0'
IF MIN="111011" THEN MIN<="000000"
ELSE MIN<=MIN+1
END IF
WHEN HOUR_SET=> HOUR_EN<='0'
IF HOUR="11000" THEN HOUR<="00000"
ELSE HOUR<=HOUR+1
END IF
WHEN DAY_SET => DAY_EN<='0'
IF DAY=MAX_DAYS THEN DAY<="00001"
ELSE DAY<=DAY+1
END IF
WHEN WEEK_SET=> WEEK_EN<='0'
IF WEEK="111" THEN WEEK<="001"
ELSE WEEK<=WEEK+1
END IF
WHEN OTHERS=>NULL
END CASE
END IF
END IF
END PROCESS
END ARCHITECTURE ART
LIBRARY IEEE
USE IEEE.STD_LOGIC_1164.ALL
USE IEEE.STD_LOGIC_UNSIGNED.ALL
ENTITY CNT60 IS
PORT(LD: IN STD_LOGIC
CLK: IN STD_LOGIC
DATA: IN STD_LOGIC_VECTOR(5 DOWNTO 0)
NUM: BUFFER STD_LOGIC_VECTOR(5 DOWNTO 0)
CO: OUT STD_LOGIC)
END ENTITY CNT60
ARCHITECTURE ART OF CNT60 IS
BEGIN
PROCESS(CLK,LD) IS
BEGIN
IF(LD='0') THEN
NUM<=DATA
ELSIF CLK'EVENT AND CLK='1' THEN
IF NUM="111011" THEN --59
NUM<="000000"CO<='1'
ELSE
NUM<=NUM+1CO<='0'
END IF
END IF
END PROCESS
END ARCHITECTURE ART
LIBRARY IEEE
USE IEEE.STD_LOGIC_1164.ALL
USE IEEE.STD_LOGIC_UNSIGNED.ALL
ENTITY CNT60 IS
PORT(LD: IN STD_LOGIC
CLK: IN STD_LOGIC
DATA: IN STD_LOGIC_VECTOR(5 DOWNTO 0)
NUM: BUFFER STD_LOGIC_VECTOR(5 DOWNTO 0)
CO: OUT STD_LOGIC)
END ENTITY CNT60
ARCHITECTURE ART OF CNT60 IS
BEGIN
PROCESS(CLK,LD) IS
BEGIN
IF(LD='0') THEN
NUM<=DATA
ELSIF CLK'EVENT AND CLK='1' THEN
IF NUM="111011" THEN --59
NUM<="000000"CO<='1'
ELSE
NUM<=NUM+1CO<='0'
END IF
END IF
END PROCESS
END ARCHITECTURE ART
LIBRARY IEEE
USE IEEE.STD_LOGIC_1164.ALL
USE IEEE.STD_LOGIC_UNSIGNED.ALL
ENTITY CNT24 IS
PORT(LD: IN STD_LOGIC
CLK: IN STD_LOGIC
DATA: IN STD_LOGIC_VECTOR(4 DOWNTO 0)
NUM: BUFFER STD_LOGIC_VECTOR(4 DOWNTO 0)
CO: OUT STD_LOGIC)
END ENTITY CNT24
ARCHITECTURE ART OF CNT24 IS
BEGIN
PROCESS(CLK,LD) IS
BEGIN
IF(LD='0') THEN
NUM<=DATA
ELSIF CLK'EVENT AND CLK='1' THEN
IF NUM="11000" THEN --24
NUM<="00000"CO<='1'
ELSE
NUM<=NUM+1CO<='0'
END IF
END IF
END PROCESS
END ARCHITECTURE ART
LIBRARY IEEE
USE IEEE.STD_LOGIC_1164.ALL
USE IEEE.STD_LOGIC_UNSIGNED.ALL
ENTITY CNT30 IS
PORT(LD:IN STD_LOGIC
CLK:IN STD_LOGIC
NIAN:IN STD_LOGIC_VECTOR(6 DOWNTO 0)
YUE :IN STD_LOGIC_VECTOR(3 DOWNTO 0)
DATA:IN STD_LOGIC_VECTOR(4 DOWNTO 0)
NUM:BUFFER STD_LOGIC_VECTOR(4 DOWNTO 0)
MAX_DAYS:OUT STD_LOGIC_VECTOR(4 DOWNTO 0)
CO:OUT STD_LOGIC)
END ENTITY CNT30
ARCHITECTURE ART OF CNT30 IS
SIGNAL TOTAL_DAYS:STD_LOGIC_VECTOR(4 DOWNTO 0)
BEGIN
PROCESS(CLK,LD) IS
VARIABLE IS_RUNNIAN:STD_LOGIC
BEGIN
CASE NIAN IS
WHEN "0000000" => IS_RUNNIAN:='1' --0
WHEN "0000100" => IS_RUNNIAN:='1' --4
WHEN "0001000" => IS_RUNNIAN:='1' --8
WHEN "0001100" => IS_RUNNIAN:='1' --12
WHEN "0010000" => IS_RUNNIAN:='1' --16
WHEN "0010100" => IS_RUNNIAN:='1' --20
WHEN "0011000" => IS_RUNNIAN:='1' --24
WHEN "0011100" => IS_RUNNIAN:='1' --28
WHEN "0100000" => IS_RUNNIAN:='1' --32
WHEN "0100100" => IS_RUNNIAN:='1' --36
WHEN "0101000" => IS_RUNNIAN:='1' --40
WHEN "0101100" => IS_RUNNIAN:='1' --44
WHEN "0110000" => IS_RUNNIAN:='1' --48
WHEN "0110100" => IS_RUNNIAN:='1' --52
WHEN "0111000" => IS_RUNNIAN:='1' --56
WHEN "0111100" => IS_RUNNIAN:='1' --60
WHEN "1000000" => IS_RUNNIAN:='1' --64
WHEN "1000100" => IS_RUNNIAN:='1' --68
WHEN "1001000" => IS_RUNNIAN:='1' --72
WHEN "1001100" => IS_RUNNIAN:='1' --76
WHEN "1010000" => IS_RUNNIAN:='1' --80
WHEN "1010100" => IS_RUNNIAN:='1' --84
WHEN "1011000" => IS_RUNNIAN:='1' --88
WHEN "1011100" => IS_RUNNIAN:='1' --92
WHEN "1100000" => IS_RUNNIAN:='1' --96
WHEN OTHERS => IS_RUNNIAN:='0'
END CASE
CASE YUE IS
WHEN "0001" => TOTAL_DAYS<="11111" --1
WHEN "0011" => TOTAL_DAYS<="11111" --3
WHEN "0101" => TOTAL_DAYS<="11111" --5
WHEN "0111" => TOTAL_DAYS<="11111" --7
WHEN "1000" => TOTAL_DAYS<="11111" --8
WHEN "1010" => TOTAL_DAYS<="11111" --10
WHEN "1100" => TOTAL_DAYS<="11111" --12
WHEN "0100" => TOTAL_DAYS<="11110" --4
WHEN "0110" => TOTAL_DAYS<="11110" --6
WHEN "1001" => TOTAL_DAYS<="11110" --9
WHEN "1011" => TOTAL_DAYS<="11110" --11
WHEN "0010" =>
IF (IS_RUNNIAN='1') THEN
TOTAL_DAYS<="11101"
ELSE
TOTAL_DAYS<="11100"
END IF
WHEN OTHERS=>NULL
END CASE
IF(LD='0') THEN
NUM<=DATA
ELSIF CLK'EVENT AND CLK='1' THEN
MAX_DAYS<=TOTAL_DAYS
IF NUM=TOTAL_DAYS THEN --99
NUM<="00001"CO<='1'
ELSE
NUM<=NUM+1CO<='0'
END IF
END IF
END PROCESS
END ARCHITECTURE ART
LIBRARY IEEE
USE IEEE.STD_LOGIC_1164.ALL
USE IEEE.STD_LOGIC_UNSIGNED.ALL
ENTITY CNT7 IS
PORT(LD: IN STD_LOGIC
CLK: IN STD_LOGIC
DATA: IN STD_LOGIC_VECTOR(2 DOWNTO 0)
NUM: BUFFER STD_LOGIC_VECTOR(2 DOWNTO 0))
END ENTITY CNT7
ARCHITECTURE ART OF CNT7 IS
BEGIN
PROCESS(CLK,LD) IS
BEGIN
IF(LD='0') THEN
NUM<=DATA
ELSIF CLK'EVENT AND CLK='1' THEN
IF NUM="111" THEN --7
NUM<="000"
ELSE
NUM<=NUM+1
END IF
END IF
END PROCESS
END ARCHITECTURE ART
LIBRARY IEEE
USE IEEE.STD_LOGIC_1164.ALL
USE IEEE.STD_LOGIC_UNSIGNED.ALL
ENTITY CNT12 IS
PORT(LD: IN STD_LOGIC
CLK: IN STD_LOGIC
DATA: IN STD_LOGIC_VECTOR(3 DOWNTO 0)
NUM: BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0)
CO: OUT STD_LOGIC)
END ENTITY CNT12
ARCHITECTURE ART OF CNT12 IS
BEGIN
PROCESS(CLK,LD) IS
BEGIN
IF(LD='0') THEN
NUM<=DATA
ELSIF CLK'EVENT AND CLK='1' THEN
IF NUM="1100" THEN --12
NUM<="0000"CO<='1'
ELSE
NUM<=NUM+1CO<='0'
END IF
END IF
END PROCESS
END ARCHITECTURE ART
LIBRARY IEEE
USE IEEE.STD_LOGIC_1164.ALL
USE IEEE.STD_LOGIC_UNSIGNED.ALL
ENTITY CNT99 IS
PORT(LD: IN STD_LOGIC
CLK: IN STD_LOGIC
DATA: IN STD_LOGIC_VECTOR(6 DOWNTO 0)
NUM: BUFFER STD_LOGIC_VECTOR(6 DOWNTO 0))
END ENTITY CNT99
ARCHITECTURE ART OF CNT99 IS
BEGIN
PROCESS(CLK,LD) IS
BEGIN
IF(LD='0') THEN
NUM<=DATA
ELSIF CLK'EVENT AND CLK='1' THEN
IF NUM="1100011" THEN --12
NUM<="0000000"
ELSE
NUM<=NUM+1
END IF
END IF
END PROCESS
END ARCHITECTURE ART
二、设计任务及要求:
1、有“时”、“ 分”、“ 秒”(23小时59分59秒)显示且有校时功能。(设计秒脉冲发生器)
2、有整点报时功能。(选:上下午、日期、闹钟等)
3、用中规模、小规模集成电路及模拟器件实现。
4、供电方式:AC220V 50HZ。(设计5V直流稳压电源)
三、 工作原理
数字电子钟是一个将“ 时”,“分”,“秒”显示于人的视觉器官的计时装置。它的计时周期为24小时,显示满刻度为23时59分59秒,另外应有校时功能和
报时功能。因此,一个基本的数字钟电路主要由译码显示器、“时”,“分”,“秒”计数器、校时电路、报时电路和振荡器组成。主电路系统由秒信号发生器、“时、分、秒”计数器、译码器及显示器、校时电路、整点报时电路组成。秒信号产生器是整个系统的时基信号,它直接决定计时系统的精度,一般用石英晶体振荡器加分频器来实现。将标准秒信号送入“秒计数器”,“秒计数器”采用60进制计数器,每累计60秒发出一个“分脉冲”信号,该信号将作为“分计数器”的时钟脉冲。“分计数器”也采用60进制计数器,每累计60分钟,发出一个“时脉冲”信号,该信号将被送到“时计数器”。“时计数器”采用24进制计时器,可实现对一天24小时的累计。译码显示电路将“时”、“分”、“秒”计数器的输出状态用七段显示译码器译码,通过七段显示器显示出来。整点报时电路时根据计时系统的输出状态产生一脉冲信号,然后去触发一音频发生器实现报时。校时电路时用来对“时”、“分”、“秒”显示数字进行校对调整。
带万年历的LCD显示多功能数字钟
程序清单:
SMC1602接口程序(MCS51模拟口线方式)
***************************************************************************
连线图: *LCM---8031* *LCM---8031* *LCM------------8031*
*DB0---P0.0* *DB4---P0.4* *RS-------------P2.0*
*DB1---P0.1* *DB5---P0.5* *RW-------------P2.1*
*DB2---P0.2* *DB6---P0.6* *E--------------P2.2*
*DB3---P0.3* *DB7---P0.7* *VLCD接10K可调电阻到GND*
注:8051的晶振频率为11.0592MHz R0设置数据存放 S8为设置键 S7为加键 S4为确认键
**************************************************************************
P0口液晶显示
P2.4位选键P2.3加一键P2.2返回键及报时功能键闹钟设置P2.0控制显示键
寄存器 clr rs0 setb rs1 R0 R4 R5在按键中用到 延时中用到 SETB RS0 SETB RS1的R0 R1 R2
SETB RS0 CLR RS1显示中用到 CLR RS0 CLR RS1 在闹钟调整子程序中用到R1
*********************************************************************
报时功能P2.6 和闹钟功能P2.5 闹钟调整时间功能已经可以设置 显示的切换方式变了 再关闭的情况下一切正常运行
*****************************
RSPIN BIT P1.2
RWPIN BIT P1.1
EPIN BIT P1.0
WEIXUAN BIT P2.4 位选键设置键
JIAJIAN BIT P2.3 加一键
JIANJIAN BIT P2.2 减一键
FANHUI BIT P2.1 返回键
NZKG BIT P2.0 闹钟设置键
SECONTL EQU 30H 秒
SECONTH EQU 31H 秒
MAOHAOL EQU 32H :
MINIUTL EQU 33H 分
MINIUTH EQU 34H 分
MAOHAOH EQU 35H :
HOURL EQU 36H 时
HOURH EQU 37H 时
*****************************日期部分***************************
DAYL EQU 40H 日个
DAYH EQU 41H 日十
HENL EQU 42H -
MONTHL EQU 43H yue
MONTHH EQU 44H yue
HENH EQU 45H -
YEARO EQU 46H 年
YEART EQU 47H
YEARS EQU 48H
YEARF EQU 49H
TEMP EQU 50H 用做存储单元显示子程序(DISPLAY)里用到
BIJIAO EQU 51H 加一子程序(JIAYI)中用到
ZDRQO EQU 55H 中断加一程序中用到
ZDRQT EQU 56H 中断加一程序中用到
ZDRQS EQU 57H 中断加一程序中用到
ZDRQF EQU 58H 中断加一程序中用到
DIZHI EQU 59H 键盘(JIANPAN)子程序里用到
NZBZ BIT 60H 定时标志位在(闹钟开关部分)
38H到3FH没用到
BSCSBZ BIT 39H 报时次数转换标志 (BSCS)里用到
BSCSCC EQU 3AH 报时次数存储 (BSCS)里用到
ZDBSBZ BIT 3BH 整点报时标志 (SSBS)里用到
ZMBSBZ BIT 3CH 整秒闪烁标志 (SSBS)里用到
BSKGBZ BIT 3DH 报时开启标志 (BSKG)里用到
XKQHBZ BIT 3EH 显示开启关闭标志 (XIANKONG)里用到
ORG 0000H
AJMP MAIN
ORG 000BH
AJMP ZD
ORG 0030H
MAIN: MOV SP,#60H 给堆栈指针赋初值
MOV 30H,#05H 秒
MOV 31H,#05H 秒
MOV 32H,#3AH :
MOV 33H,#09H 分
MOV 34H,#05H 分
MOV 35H,#3AH :
MOV 36H,#03H 时
MOV 37H,#01H 时
*****************************日期部分***************************
MOV 40H,#09H 日个
MOV 41H,#02H 日十
MOV 42H,#2DH -
MOV 43H,#09H yue
MOV 44H,#00H yue
MOV 45H,#2DH -
MOV 46H,#09H 年
MOV 47H,#09H
MOV 48H,#09H
MOV 49H,#02H
CLR P2.5 闹钟
CLR P2.6 整点报时
MOV 03H,#00H 闹钟分个位
MOV 04H,#00H 闹钟分十位
MOV 06H,#04H 闹钟时个位
MOV 07H,#01H 闹钟时十位
CLR P1.5
CLR P1.4
MOV B,#20
MOV TMOD,#01H 定时器工作方式1
MOV TH0,#4CH
MOV TL0,#08H
SETB ET0 允许T0中断
SETB EA 总中断开放
LCALL LCDRESET 初始化LCD
LCALL DISPSTART 调用显示初始状态
SETB TR0 开启定时器
CLR NZBZ 闹钟开启关闭标志
CLR BSKGBZ 报时开启关闭标志
CLR XKQHBZ 显示开启关闭标志
LOOP: LCALL JIANPAN 按键子程序
LCALL DISPLAY 显示子程序
LCALL NZBF NAOZHONG BUFENG
LCALL NZBJ NAOZHONG BIJIAO
LCALL BSKG BAOSHIKAIGUAN
LCALL BSCS BAOSHICISHU
LCALL SSBS 闪烁报时
SJMP LOOP
==============================中断加一程序===================================
ZD: PUSH ACC
MOV TH0,#4CH
MOV TL0,#08H
DJNZ B,ZDEND
MOV B,#20
INC SECONTL
SETB ZMBSBZ
MOV A,SECONTL
CJNE A,#0AH,ZDEND
MOV SECONTL,#00H
INC SECONTH
MOV A,SECONTH
CJNE A,#06H,ZDEND
MOV SECONTH,#00H
INC MINIUTL
MOV A,MINIUTL
CJNE A,#0AH,ZDEND
MOV MINIUTL,#00H
INC MINIUTH
MOV A,MINIUTH
CJNE A,#06H,ZDEND
MOV MINIUTH,#00H
INC HOURL
SETB BSCSBZ
SETB ZDBSBZ
MOV A,HOURL 24小时的判断
CJNE A,#04H,ZDF
MOV A,HOURH
CJNE A,#02H,ZDEND
MOV HOURL,#00H
MOV HOURH,#00H
LCALL ZDRQ
SJMP ZDEND
ZDF: CJNE A,#0AH,ZDEND
MOV HOURL,#00H
INC HOURH
ZDEND: POP ACC
RETI
日期部分
ZDRQ: PUSH ACC
INC DAYL
判断天数28,30,31部分
MOV A,MONTHH 用于判断月份时为31天30天28天
CJNE A,#01H,LL
MOV 55H,#0AH 存放月份的十位转化为个位是0AH
MOV A,MONTHL
ADD A,55H 月分高低相加用于查表
SJMP LL3
LL: MOV A,MONTHL
ADD A,MONTHH
LL3: MOV 56H,A 存放相加后的月份数据
MOV DPTR,#TAB5
MOVC A,@A+DPTR 查十位和天数的十位比较
MOV 57H,A
MOV A,56H
MOV DPTR,#TAB6 查个位和天数的个位比较
MOVC A,@A+DPTR
MOV 58H,A
MOV A,DAYH
CJNE A,57H,LL2
MOV A,DAYL
CJNE A,58H,LL2
MOV DAYH,#00H
MOV DAYL,#01H
SJMP LL4
LL2: MOV A,DAYL
CJNE A,#0AH,ZDRQEND
MOV DAYL,#00H
INC DAYH
MOV A,DAYH 比较天数是否要进位
CJNE A,57H,ZDRQEND
MOV A,DAYL
CJNE A,58H,ZDRQEND
MOV DAYH,#00H
MOV DAYL,#01H
月份和年份
LL4: INC MONTHL
MOV A,MONTHL
CJNE A,#03H,ZDRQ1 用于判断月份时为12月时进位
MOV A,MONTHH
CJNE A,#01H,ZDRQ1
MOV MONTHL,#01H 天数符合要求
MOV MONTHH,#00H
SJMP ZDRQ2
ZDRQ1: CJNE A,#0AH,ZDRQEND
MOV MONTHL,#00H
INC MONTHH
SJMP ZDRQEND
ZDRQ2: INC YEARO 年的加一
MOV A,YEARO
CJNE A,#0AH,ZDRQEND
MOV YEARO,#00H
INC YEART 年的进位
MOV A,YEART
CJNE A,#0AH,ZDRQEND
MOV YEART,#00H
INC YEARS
MOV A,YEARS
CJNE A,#0AH,ZDRQEND
MOV YEARS,#00H
INC YEARF
MOV A,YEARF
CJNE A,#0AH,ZDRQEND
MOV YEARF,#00H
ZDRQEND:
POP ACC
RET
液晶初始化
========================初始化程序=======================================
LCDRESET: 初始化程序
LCALL DELAY5MS 延时15MS
LCALL DELAY5MS
LCALL DELAY5MS
MOV A,#38H 显示模式设置(不检测忙信号)
LCALL LCDWCN 共三次
LCALL DELAY5MS
MOV A,#38H
LCALL LCDWCN
LCALL DELAY5MS
MOV A,#38H
LCALL LCDWCN
MOV A,#38H 显示模式设置(以后均检测忙信号)
LCALL LCDWC
MOV A,#08H 显示关闭
LCALL LCDWC
MOV A,#01H 显示清屏
LCALL LCDWC
MOV A,#06H 显示光标移动设置
LCALL LCDWC
MOV A,#0CH 显示开及光标设置
LCALL LCDWC
RET
==============================写指令===================================
LCDWC: 送控制字子程序(检测忙信号)
LCALL WAITIDLE
******写指令*******送控制字子程序(不检测忙信号)
LCDWCN: CLR RSPIN RS=0 RW=0 E=高脉冲
CLR RWPIN
MOV P0,A
SETB EPIN (
NOP 给高电平脉冲
CLR EPIN )
RET
==========================写数据=======================================
LCDWD: 写字符子程序
LCALL WAITIDLE
SETB RSPIN RS=1 RW=0 E=高脉冲
CLR RWPIN
MOV P0,A
SETB EPIN
NOP
CLR EPIN
RET
===============================等待控制器空闲==================================
WAITIDLE:
PUSH ACC 正常读写操作之前必须检测LCD控制器状态
MOV P0,#0FFH
lcall DELAY5MS 4566666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666
CLR RSPIN RS=0 RW=1 E=高电平
SETB RWPIN
SETB EPIN
lcall DELAY5MS 465555546465464654648791313848946113134849845461313579641613131354649498
WTD_PA: NOP DB7: 0 LCD控制器空闲
JB P0.7,WTD_PA 1 LCD控制器忙
CLR EPIN
POP ACC
RET
***********************初始状态子程序*******************************
DISPSTART: 显示初始状态子程序
PUSH ACC
MOV A,#80H
LCALL LCDWC
MOV DPTR,#TAB 显示字符
DISP1: CLR A
MOVC A,@A+DPTR
JZ DISP2
LCALL LCDWD
INC DPTR
SJMP DISP1
DISP2: MOV A,#0C0H
LCALL LCDWC
MOV DPTR,#TAB1
DISP3: CLR A
MOVC A,@A+DPTR
JZ DISP_END
LCALL LCDWD
INC DPTR
SJMP DISP3
DISP_END:
POP ACC
RET
==========================显示子程序=======================================
DISPLAY:PUSH PSW
PUSH ACC
SETB RS0
CLR RS1
MOV A,#85H
LCALL LCDWC
MOV R1,#38H 第一行显示数据存储单元的启始地址
MOV TEMP,#30H 第一行显示数据存储单元的结束地址
MOV R6,#2
PLAY: DEC R1
CJNE R1,#32H,PLY 判断是否为冒号位
MOV A,MAOHAOL 是者送冒号的ACSI码
SJMP PLAY1
PLY: CJNE R1,#35H,PLY1
MOV A,MAOHAOH
SJMP PLAY1
PLY1: CJNE R1,#42H,PLY2 判断是否为横杠的位置
MOV A,HENL 是者送横杠的ACSI码
SJMP PLAY1
PLY2: CJNE R1,#45H,PLY3
MOV A,HENH
SJMP PLAY1
PLY3: MOV A,@R1 用查表法送要显示的数据
MOV DPTR,#TAB2
MOVC A,@A+DPTR
PLAY1: LCALL LCDWD
MOV A,R1
CJNE A,TEMP,PLAY 判断第一行是否显示好了
MOV A,#0C5H
LCALL LCDWC
MOV R1,#4AH 第二行显示数据存储单元的启始地址
MOV TEMP,#40H 第二行的结束地址
DJNZ R6,PLAY R6为0时两行显示结束
POP ACC
POP PSW
RET
************************按键子程序************************
JIANPAN:clr rs0 键盘子程序
setb rs1 键盘子程序
JB WEIXUAN,JIAN_ZEND 设置键的判断
LCALL DELAY5MS
JB WEIXUAN,JIAN_ZEND
PUSH ACC
JNB WEIXUAN,$
MOV A,#0FH 开启光标闪烁设置
LCALL LCDWCN
fah: JNB NZBZ,JPNZSJ 为“1”闹钟 为“0”时钟
LCALL JPXS
MOV R4,#86H 闹钟设定时间R4存放显示位地址
MOV R5,#2 闹钟设定时间第一行第二行•••••位置改变次数
MOV DIZHI,#8CH 闹钟设定时间第一行结束地址
MOV R0,#06H
SJMP GIVED
JPNZSJ: CLR TR0
MOV R4,#86H R4存放显示位地址
MOV R5,#2 第一行第二行•••••位置改变次数
MOV DIZHI,#8DH 第一行结束地址
MOV R0,#36H
GIVED: MOV A,#0FH 开启光标闪烁设置555555555555555555555555555555555555555555555
LCALL LCDWCN
MOV A,R4
LCALL LCDWC
UPONE: JB FANHUI,UPtwo 返回键的判断
LCALL DELAY5MS
JB FANHUI,UPtwo
JNB FANHUI,$
SJMP GOBACK
JIAN_ZEND:SJMP JIAN_END 中继跳转6666666666666666666666666666666666666666666666666666666666666666
UPtwo: JB JIAJIAN,IAM 加一键的判断
LCALL DELAY5MS
JB JIAJIAN,IAM
JNB JIAJIAN,$
LCALL JIAYI 调用按键加一子程序
MOV A,#0FH 开启光标闪烁设置555555555555555555555555555555555555555555555
LCALL LCDWCN
IAM: JB JIANJIAN,IAM22 减一键的判断
LCALL DELAY5MS
JB JIANJIAN,IAM22
JNB JIANJIAN,$
LCALL JIANYI 调用按键减一子程序
AJMP GIVED
IAM22: JB WEIXUAN,UPONE 位选键的判断
LCALL DELAY5MS
JB WEIXUAN,UPONE
JNB WEIXUAN,$
DEC R0
INC R4
LCALL JIAN 调用位选比较程序
CJNE r4,#88H,JJ11
DEC R0
INC R4
SJMP JJ22
JJ11: CJNE r4,#8BH,JJ22
DEC R0
INC R4
JJ22: MOV A,R4
CJNE A,DIZHI,GIVED
JB NZBZ,fah 为“1”闹钟 为“0”时钟
MOV R4,#0C5H
MOV DIZHI,#0CFH
MOV R0,#49H
DJNZ R5,GIVED
LJMP fah
GOBACK: MOV A,#0CH 关闭光标闪烁设置
LCALL LCDWCN
POP ACC
JIAN_END:
SETB TR0
RET
1111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111
JPXS: MOV A,#85H
LCALL LCDWC
MOV R1,#08H 第一行显示数据存储单元的启始地址
JPXS_LL:DEC R1
CJNE R1,#05H,JPXS_LP
MOV A,#3AH
SJMP JPXS_LY
JPXS_LP:MOV A,@R1 用查表法送要显示的数据
MOV DPTR,#TAB2
MOVC A,@A+DPTR
JPXS_LY:LCALL LCDWD
CJNE R1,#03H,JPXS_LL
RET
111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111
************************位选比较控制程序************************
在调整时间时这几位是符号冒号和横杠的数据
在这几位时跳过到下一位
JIAN: CJNE R4,#87H,JIAN5
DEC R0
INC R4
SJMP JIANEND
JIAN5: CJNE R4,#8AH,JIAN1
DEC R0
INC R4
SJMP JIANEND
JIAN1: CJNE R4,#0C9H,JIAN2
DEC R0
INC R4
SJMP JIANEND
JIAN2: CJNE R4,#0CCH,JIANEND
DEC R0
INC R4
JIANEND:RET
************************按键加一子程序********************
JIAYI: INC @R0
CJNE @R0,#0AH,JIAYI_END
MOV @R0,#0
CJNE R4,#86H,JIAYI55
SJMP JIAYI33
JIAYI55:CJNE r4,#89H,JIAYI11
SJMP JIAYI33
JIAYI11:CJNE r4,#8CH,JIAYI22
SJMP JIAYI33
JIAYI22:CJNE R0,#30H,JIAYI_END
JIAYI33:INC R0
INC @R0
CJNE @R0,#06H,JIAYI44
MOV @R0,#0
JIAYI44:DEC R0
JIAYI_END:MOV A,#0CH 开启光标闪烁设置
LCALL LCDWCN
JNB NZBZ,JIAYI88 为“1”闹钟 为“0”时钟
LCALL JPXS
SJMP JIAYI99
JIAYI88:LCALL DISPLAY 显示子程序
JIAYI99: RET
%%%%%%%%%%%%%%%%%%减一%%%%%%%%%%%%%%%%%%%%%%%%
JIANYI: DEC @R0
CJNE @R0,#00H,JIANYI_END
MOV @R0,#9
CJNE R4,#86H,JIANYI55
SJMP JIANYI33
JIANYI55:CJNE r4,#89H,JIANYI11
SJMP JIANYI33
JIANYI11:CJNE r4,#8CH,JIANYI22
SJMP JIANYI33
JIANYI22:CJNE R0,#30H,JIANYI_END
JIANYI33:INC R0
DEC @R0
CJNE @R0,#0FFH,JIANYI44
MOV @R0,#5
JIANYI44:DEC R0
JIANYI_END:MOV A,#0CH 开启光标闪烁设置
LCALL LCDWCN
JNB NZBZ,JIANYI88 为“1”闹钟 为“0”时钟
LCALL JPXS
SJMP JIANYI99
JIANYI88: LCALL DISPLAY 显示子程序
JIANYI99: RET
******************************闹钟开关部分************************
NZBF: JB NZKG,NZBF_END
LCALL DELAY5MS
JB NZKG,NZBF_END
JNB NZKG,$
CPL NZBZ
JB NZBZ,NZBF_LL
MOV A,#01H 显示清屏
LCALL LCDWC
CLR P2.5
LCALL DISPSTART 调用显示初始状态
LCALL DISPLAY 调用显示初始状态
JB BSKGBZ,NZBF_LP |
SJMP NZBF_END |
NZBF_LP:MOV A,#8FH 报时标志显示位置 |
LCALL LCDWC |保护报时标志在清屏是不被误清
MOV A,#25H 显示报时标志 |
LCALL LCDWD |
SJMP NZBF_END |
NZBF_LL:MOV A,#8EH 闹钟标志显示位置
LCALL LCDWC
MOV A,#26H 显示闹钟标志
LCALL LCDWD
NZBF_END:RET
******************************闹钟比较部分************************
NZBJ: JB NZBZ,NZBJ_LL
SJMP NZBJ_END
NZBJ_LL:MOV A,07H
CJNE A,37H,NZBJ_END
MOV A,06H
CJNE A,36H,NZBJ_END
MOV A,04H
CJNE A,34H,NZBJ_END
MOV A,03H
CJNE A,33H,NZBJ_END
SETB P2.5
NZBJ_END:RET
***************报时开关********************
BSKG: JB FANHUI,BSKG_END
LCALL DELAY5MS
JB FANHUI,BSKG_END
JNB FANHUI,$
CPL BSKGBZ
JB BSKGBZ,BSKG_LL
MOV A,#01H 显示清屏
LCALL LCDWC
CLR P2.6
LCALL DISPSTART 调用显示初始状态
LCALL DISPLAY 调用显示
JB NZBZ,BSKG_LP |
SJMP BSKG_END |
BSKG_LP:MOV A,#8EH |
LCALL LCDWC |保护闹钟标志在清屏是不被误清
MOV A,#26H |
LCALL LCDWD |
SJMP BSKG_END |
BSKG_LL:MOV A,#8FH 报时标志显示位置
LCALL LCDWC
MOV A,#25H 显示报时标志
LCALL LCDWD
BSKG_END:RET
*********************报时次数********************
BSCS: JNB BSKGBZ,BSCS_END
JNB BSCSBZ,BSCS_END
MOV A,37H
CJNE A,#01H,BSCS_LL
MOV A,#0AH
SJMP BSCS_LP
BSCS_LL:CJNE A,#02H,BSCS_LP
MOV A,#14H
BSCS_LP:ADD A,36H
RL A
MOV BSCSCC,A
CLR BSCSBZ
BSCS_END: RET
**********************闪烁报时********************************
SSBS: JNB BSKGBZ,SSBS_END
JNB ZDBSBZ,SSBS_END
JNB ZMBSBZ,SSBS_END
CPL P2.6
CPL P2.7
CLR ZMBSBZ
DJNZ BSCSCC,SSBS_END
CLR ZDBSBZ
CLR P2.6
SSBS_END:RET
************************延时子程序(5MS)************************
DELAY5MS:
PUSH PSW
SETB RS0
SETB RS1
MOV R1,#25 延时子程序(5MS)
DL5_PA: MOV R2,#100
DJNZ R2,$
DJNZ R1,DL5_PA
POP PSW
RET
TAB: DB "TIME:",00h
TAB1: DB "DATE:",00h
TAB2: DB "01234567891"
TAB3: DB 0AH,06H,00H,0AH,06H,00H,0AH,03H 用于比较调整时间时的比较
TAB4: DB 0AH,04H,00H,0AH,02H,00H,0AH,0AH,0AH,0AH用于调整日期时的比较
TAB5: DB 00H,03H,02H,03H,03H,03H,03H,03H,03H,03H,03H,03H,03H用于天数十位比较
TAB6: DB 00H,02H,09H,02H,01H,02H,01H,02H,02H,01H,02H,01H,02H用于天数个位比较
END