数字钟实验报告--多功能计时电路的设计 本文关键词:多功能,计时,电路,实验,报告
数字钟实验报告--多功能计时电路的设计 本文简介:南京理工大学电类综合实验报告题目:多功能计时电路的设计--数字钟姓名:马冯生学号:114116001203学院:材料学院专业:材料加工工程指导:电子技术中心完成时间:2015年3月24日目录一、引言二、实验目的三、实验设计要求四、实验原理及框图五、单元电路设计及其电路六、实验中遇到的问题及解决方法七
数字钟实验报告--多功能计时电路的设计 本文内容:
南京理工大学
电类综合实验报告
题目:多功能计时电路的设计--数字钟
姓名:马冯生
学号:114116001203
学院:材料学院
专业:材料加工工程
指导:电子技术中心
完成时间:2015年3月24日
目
录
一、引言
二、实验目的
三、实验设计要求
四、实验原理及框图
五、单元电路设计及其电路
六、实验中遇到的问题及解决方法
七、心得体会
八、元器件清单
一.
引言
随着数字技术在仪表和通信系统中的广泛应用,数字钟已经应用到生活的方方面面,而数字钟的功能也随着人们要求的提高在不断的增加,同时在数字技术的快速发展下,功能也越来越强大。
数字钟能够比传统的时钟更加精确的进行计时,并且能够实现多种显示。在调节方面,能够内嵌许多诸如报时、万年历、彩铃等计时以外的功能。
本设计在介绍数字钟工作原理的基础上,运用数字集成技术,来设计实现一个多功能数字钟。
二.
实验目的
1、通过实验掌握十进制加法计数、译码、显示电路的工作过程。
2、通过实验深入掌握电路的分频原理和数字信号的测量方法。
3、熟悉集成电路构成的计数、译码、显示器件的外部功能及其使用方法。
三.实验设计要求
1、秒信号发生电路:为计时器提供信号。
2、及时电路:完成0分00秒-9分59秒的计时功能。
3、清零电路:具有开机自动清零功能;在任何时候,按动清零开关,可进行计时器手动清零。
4、译码显示电路:显示计时电路产生的数字信息。
5、系统级联调试:将以上电路进行级联完成等计时器的所有功能。
四.实验原理及框图
图1
三位计时器示意图
数字钟示意图如图1所示,计时电路完成计时功能,并将计时结果传送至显示电路,进而实现显示功能。原理框图如图2所示,主要由计时电路、秒信号发生电路、清零电路和译码电路组成。计时电路在秒信号的作用下,产生0:00~9:59的循环计时,清零电路控制计时电路的清零端,实现时钟的清零,最终将计时电路的输出送至译码显示电路,实现时钟的显示。
图2
数字钟的原理框图
五.单元电路设计及其电路
1、
秒信号发生电路
图3
秒信号发生电路
秒信号发生电路为计时电路提供驱动信号,电路原理如图3所示。为提供较为精确的秒信号,本设计中振荡电路采用215Hz的石英晶体管为主体的晶振电路,并作为电路的秒信号源。由于震荡电路产生的源信号为215Hz,而秒的基准信号频率为1Hz,则需要对215Hz信号进行分频,得到1Hz信号,分频器采用CD4060和74LS74来实现,CD4060为14位二进制串行计数器,各脚管功能如表1所示,功能如表2所示。虽然CD4060内部有14级由T触发器构成的二分频器,但实际输出端只有10个:Q4~Q10、Q12~Q14、Q1~Q13以及Q13并不引出。为晶振电路的引出端,需接外部石英晶体。Cr为复零端,为高电平或正脉冲时振荡器停振。从输出功能看,CD4060能得到10中不同的分频系数,最小为24=16分频,最大为214=16384分频,即将215Hz送入该芯片,最大分频输出端Q14输出信号频率为2Hz。
表1
CD4060管脚功能
由于CD4060最多完成14级二分频,所以还需要再加一级分频,才能把4060输出的2Hz信号变成秒信号。外接二分频器可采用D触发器(74LS74)构成的二分频电路,74LS74管脚功能如表3所示,该芯片上有上片和下片两个D触发器,2Hz信号经过二分频电路得到1Hz的秒脉冲信号,即将D触发器的同相位输出Q端与触发信号连接在一起,复位端和控制端接电源,使该两端口无效,则Q端的输出信号即为1Hz的秒脉冲信号。
时钟输入端
CP0
时钟输出端
反相时钟输出端
Q4~Q10,Q12~Q14
计数器输出端
表2
CD4060功能表
输入
功能
CR
X
1
清零
↓
0
计数
↑
0
保持
表3
74LS74管脚功能
管脚号
引脚代码
引脚功能
管脚号
引脚代码
引脚功能
1
1
复位信号
8
2
反相位输出
2
1D
触发信号
9
2Q
同相位输出
3
1CP
时钟信号
10
2
控制
4
1
控制
11
2CP
时钟信号
5
1Q
同相位输出
12
2D
触发信号
6
1
反相位输出
13
2
复位信号
7
GND
地
14
VCC
电源
2、计时电路
该电路是本实验中的关键部分,有分计数器、秒十位计数器、秒个位计数器构成,电路均使用CD4518BCD码计数器来实现。CD4518管教如图45所示,该计数器为双十进制同步加法计数器,片子内部封装两个相同且独立的十进制计数器,每个计数器中都含有四位二进制的技术单元,每个计数器含有两个时钟输入端“CP”和“EN”,简称双时钟,可以根据使用要求来选择不同的始终输入,两者所不同在于“CP”端对始终的上升沿有效,“EN”读研对时钟的下降沿有效。该计数器功能表如表4所示。
表4
CD4518功能表
功能
输入
输出
Cr
CP
EN
QD
QC
QB
QA
清零
X
X
X
0
0
0
0
计数
0
↑
1
BCD码加法计数
保持
0
X
0
保持
计数
0
0
↓
BCD码加法计数
保持
0
1
X
保持
计时整体电路如图5所示,分位计数器和秒个位计数器均是从0~9循环计数(模10计数),可采用CD4518直接实现十进制计数功能;秒十位计数器为六进制计数器,需要将CD4518的模10计数变换为一个从0~5的模六计数:当4518计数到6时,将Qc,Qb引到与门74LS21的输入端,此时74LS21输出一个高电压送回至4518的Cr端,实现复位(4518回0),由于4518的Cr端为异步复位,因此4518余姚计数到6时才引出复位信号,并且6状态非常短暂,显示器并不显示,所以实际效果还是0~5显示。74LS21为四输入与门,片子内部封装两个相同且独立的四输入与门,该电路中只用到1个与门的2个输入,因此需要将该与门的其他两个输入端接5V电源+极,不可悬空不接。
搭建电路时,首先将所有芯片电源端(Vcc和GND端)分别连接至5V电源+、-极;对于秒个位计数器,将秒信号发生电路输出的秒信号(1Hz信号)送入秒个位计数器的2CP端,同时2EN端接5V电源+极,2Cr端接5V电源-极(注意:当清零电路搭建完成后,需将清零电路的输出替换2Cr端的5V电源-极),秒个位计数器即可完成0~9循环计数过程中唯一的下降沿,将此下降沿送至秒十位计数器的2EN端,即可实现秒十位计数器加1,实现进位),同时2CP端接5V电源+极,秒十位计数器即可在进位信号的驱动下完成0~5循环计数。对于分位计数器,将秒十位计数器的输出2Qc端送入分位计数器的2EN端,完成秒十位到分位的进位(当秒十位计数器从5跳至0时,2Qc端得到0~5循环计数过程中唯一的下降沿,将此下降沿送至分位计数器的2EN端,即可实现分位计数器加1实现进位),同时2CP端接5V电源+极,2Cr端接5V电源-极(注意:当清零电路搭建完成后,需将清零电路的输出替换2Cr端的5V电源-极),分位计数器即可完成0~9循环计数。
所用器件:CD4518(计数器)3片、74LS21(与门)1片。
图5
计时电路
3、清零电路
该电路具有开机清零和手动清零功能。电路原理如图6所示,将图5计时电路的秒个位和分位的清零端即CD4518的管脚15(高电压有效)原来的接5V电源-极导线拔开,将非门输出送至2Cr端,而秒十位CD4518的清零端原来接74LS21的输出,需要将此输出和图6中非门送入一个或门,再将或门输出送至秒十位CD4518的清零端,才能同时实现秒十位计数器的清零功能和模6计数功能。电路管脚连接如图7所示,对于清零电路,电路正常工作是开关打开,刚开机时,由于电容上的电压不能突变,电容两端初始为低电压,经过一个非门输出高电压,送到CD4518的2Cr端,整个计时电路清零,进而实现电路开机时清零,当电容充满电以后,非门的输入端为高电压,非门输出低电压,2Cr端无效,CD4518实现正常计数,电路正常工作。
按下开关后,电容、电阻组成一个回路,电容放电,当电容储存电量放完后,电容两端为低电压,即非门的输入端为低电压,非门输出高电压,送到CD4518的2Cr端,整个计时电路清零,进而实现电路手动清零。
所用器件:CD4069(非门)1片、74LS32(或门)1片,1kΩ电阻2个、10μF电容1个、开关1个。
图7
清零电路管脚连接图
4、
译码显示电路
译码显示电路采用三片CD4511显示译码器和三个七段共阴数码管,分位、秒十位和秒个位个采用一片CD4511和一个数码管。CD4511的作用是将计数器QA~QD输出的二进制代码译成特定的输出信号以供显示器按代码的原意显示成数字,译码器采用CD4511七段字型译码器。由a~g各个输出段信号,以控制点亮LED数码管的字型段,CD4511的输入端ABCD依次接计数器的QA~QD,及8421(BCD)码输出,CD4511有三个使能管脚。
电路从0:00~0:59循环计时,译码电路分别进行译码,采用共阴极七段LED数码管进行循环显示。CD4511的输入接到相应计数器的输出,而它的输出端与数码管的相应端相连,数码管通过300的电阻接地。
所用器件:CD4511(译码器)3片、300Ω电阻3个、LED数码显示管3个。
图9
译码显示电路
5、
校分电路
图10
校分电路原理图
如图10所示,校分电路能在开关闭合的情况下,实现分个位以0.5秒每个数的速度进行计数。同时,秒个位和十位并不走动。从而实现对于分个位显示器的校准。其原理为:正常计数时时开关打在“1”电平,下面的与非门被选通,上面的与非门被封锁,秒进位产生的脉冲送至分计数器的时钟端;当开关打在“0”电平时,上面的与非门被选通,下面的与非门被封锁,校分信号送至分计数器的时钟端。校分信号可由4060分频信号得到,一般选为2Hz。
6、总体电路连接图
将以上四个模块按照信号顺序连接,即可得到总体电路如图11所示。
图11总体电路
六、实验中遇到的问题及解决办法
(1)
一开始我的电路根本就不亮,经过检查发现由于原件位置摆放时的粗心导致的,经过重新放置,电路能够点亮。
(2)
其次,电路亮了之后发现秒个位的显示器右下角的红点点亮了,经过原理的论证,很快发现是由于左边的引脚走线时不小心摆放到了该引脚的线路上,导致这个引脚也接受到了信号,从而点亮,重新排布后,显示器回复正常。
(3)
之后,电路并不能正常的实现计数功能,只是每次导通后变换数字,经过线路的检查发现并无问题,通过助教的指导,学会使用二极管检查脉冲信号的通断,发现并无问题,然后使用万能表对线路实现了逐步排查,最后发现原来有个原件是换的,换过之后正常工作。
(4)
之后在校分电路的制作中还算顺利,只是在接通校分电路开关后,分个位在跳动的同时,秒十位也在跳动,结果发现是秒十位到分个位的那根信号线没拔,改正后,功能顺利实现。到此,实验顺利完成。
七、心得体会
本次设计对于动手能力的要求很强,但是同时对于原理的了解也是必要的。第一天老师布置完实验任务后,我就回去看数电书上相关的知识,也在网上查阅了这个电路的相应资料,大致了解了整个数字时钟原理和各个功能模块作用以及要用到的各个芯片的引脚和功能。果然由于对于原理的理解,在排线过程中起到了一定的作用。
这次试验中也让我知道了许多做电路实验的注意点和方法,对我今后做更复杂的实验奠定了基础。首先元件的布局要合理,并且元件之间的连线要做到尽量少交叉,连线要清晰;不同功能的元件或者端口之间可以用不同的颜色的线加以区分,特别是地线和电源线最好用黑线和红线连接,并且其它连线不要用这两种颜色,这样会给检查电路错误带来很大的方便。整个实验的电路比较复杂,但都是建立在简单的单一功能基础上的,因此每一部分的电路是下一步的基础,一定要做到每一部分线路正确,然后再开始下一部分电路的连接。最后,我体会很深的一点是一定要学会使用万用表,这对于检查错误很有效。就在我最后电路运行时,我遇到了很大的问题,用了几乎一下午检查连线,最后才发现了问题所在。
之后完成后还帮助同学的电路进行了检查,在助人为乐的同时,也增加了自己解决问题的能力。
总的来说,这次实验锻炼了我的动手能力、培养了我发现问题后解决问题的能力,同时也让我学会了把理论用于实践,这对于我今后的发展有很重要的意义。
八、元器件清单
元器件清单
元件名称
数量
元件名称
数量
215HZ晶振
1个
CD4069
1片
300电阻
3个
CD4518
3片
1K电阻
2个
CD4511
3片
22M电阻
1个
74LS74
1片
10pF电容
1个
74LS21
1片
20pF电容
1个
74LS32
1片
10uF电容
1个
数码管
3个
CD4060
1片
15
/
15
篇2:基于16F887单片机数字钟课设设计报告
基于16F887单片机数字钟课设设计报告word格式 本文关键词:单片机,格式,报告,设计,数字钟
基于16F887单片机数字钟课设设计报告word格式 本文简介:第44页共44页xxxxxx《基于PIC16F887单片机的数字钟》课程设计报告学生姓名:_学号:_____专业班级:____________指导教师:___________*年*月*日目录1.功能介绍31.1PIC16F887介绍31.2DS1307介绍31.3TC74介绍31.4LM1602L介
基于16F887单片机数字钟课设设计报告word格式 本文内容:
第
44
页
共
44
页
xxxxxx
《基于PIC16F887单片机的数字钟》
课程设计报告
学生姓名:
_
学
号:
_____
专业班级:
__________
__
指导教师:
___
________*年*月*日
目
录
1.功能介绍3
1.1
PIC16F887介绍3
1.2
DS1307介绍3
1.3
TC74介绍3
1.4
LM1602L介绍3
1.5蜂鸣器介绍3
2.硬件原理框图4
3.模块介绍4
3.1
单片机最小系统模块4
3.2时间和温度通讯模块5
3.3
按键模块5
3.4
蜂鸣器和液晶显示器模块5
4.软件框图7
5.软件功能介绍7
5.1
端口﹑LCD和IIC初始化及端口若上拉7
5.2
显示预显示的数字和字母8
5.3
根据闹钟按键判断9
5.4
写入初值到时钟芯片9
5.5
时间加减设置10
5.6
显示时间﹑读和显示温度﹑显示字母星期11
6.个人心得体会12
6.1
关于PIC课设12
6.2
课设过程遇到的问题及解决措施12
6.3
我的建议14
附录1:数字钟的全部C程序15
附录2:Proteus完整仿真图44
1.功能介绍
1.1
PIC16F887介绍
PIC16F887单片机共有40个引脚,其中有33个端口引脚,7个电源﹑地和复位引脚。外部晶振设为4MHz,引脚1接复位按键。此数字钟用到单片机的B端口中断功能,端口若上拉,电平变化下降沿中断。
1.2
DS1307介绍
DS1307时钟芯片是实时时钟芯片,它提供秒﹑分﹑时﹑日﹑月﹑年和星期等数据,有备用电源,主电源掉电备用,时钟晶振是32.768kHz。其控制寄存器的地址为07,其值0b11010000,代表允许其7脚输出每秒1Hz的方波。其秒﹑分﹑时﹑日﹑月﹑年和星期分别存在地址为00﹑01﹑02﹑04﹑05﹑06﹑03中。其与单片机的通讯为IIC通讯。
1.3
TC74介绍
温度传感器TC74是感测周围温度值。TC74芯片的默认值为0b1001101(实验板上芯片调试时的地址为0b1001000,此为仿真时用的地址)。单片机首先向TC74改善地址,地址在字节的高7位,最低位为0表示为写。接着单片机向TC74发送第二个数据,即读温度命令字RTR,即8位0;然后重新开始,单片机再向TC74发送地址,但此时的最低位为1,表示接下来是要读TC74的温度值。最后单片机接收TC74发出的温度值。TC74与单片机的通讯也为IIC通讯。
1.4
LM1602L介绍
字符型LM016L液晶显示器。要求用4位数据线通讯,传送命令也传送地址。其初始化的格式是固定的,不能更改的,初始化见后面所示。输入到液晶显示器的是所示字符的ASCII码,液晶才能正确显示。
1.5蜂鸣器介绍
蜂鸣器是用来设置闹钟用的。当设定闹钟的时间到时,蜂鸣器响,按键按下,停止响。按键模块是用来进行年月日﹑秒分时和星期加减及设定闹钟用的。采用的是电平变化的中断模式。
2.硬件原理框图
220V
变压器变压
CUP模块
液晶显示
按键输入
DS1307和TC74
市电220V电压经变压器变压供CPU使用的低压。DS1307和TC74经CPU显示在液晶上。按键控制DS1307的时间加减和闹钟设置,实现闹钟功能。先在液晶上定位要显示数据的位置,然后将要显示的字符的ASCII码输入到液晶,即可正确数据。
3.模块介绍
3.1
单片机最小系统模块
此单片机的外部晶振为4MHz,引脚1接有高电平和复位按钮。端口B口用来进行电平变化中断,端口RC3和RC4用来进行IIC通讯,RC1用来输出高电平给蜂鸣器。端口D端口用来输出命令和数据给液晶显示器。
3.2时间和温度通讯模块
DS1307时间芯片可根据输入的数据自动走时。单片机不断地访问DS1307芯片,将访问得到的数据显示在液晶显示器上。其中芯片上读出来的星期是数字星期(01即代表星期一),软件部分将数字星期转换成字母星期(如Wed为星期三)。单片机也访问TC74温度传感器,要得到的数据显示在液晶上。温度传感器小数后面有一位,但是设计时只显示到个位,不显示小数点后面的数字。
3.3
按键模块
按键S1是用来定位时间加减用的,来回按7下,分别对秒分时,星期和日月年。S2可以对时间进行加运算即每按一下,相应的时间加1;S3可以时间进行减运算即每按一下,相应的时间减1;S4是闹钟按键,按第一下,进入闹钟设置模式,此时再按S2或S3可以对时间进行设定。按第二下时,CPU进入比较模式,即把DS1307的时间和设定保存好的时间进行比较,等待设定的时间到时,蜂鸣器开始响。当按第三下时,蜂鸣器停止响,相应的变量清零,从重新开始。
3.4
蜂鸣器和液晶显示器模块
当定时时间到,RC1输出高电平,二极管导通,蜂鸣器开始响。当RC1输出低电平时,二极管截止,蜂鸣器停止响。液晶显示器用来显示时间,星期和温度,首先要进行显示时间定位,即写入命令。然后进行显示数据输入,即定稿数据。VEE和VSS都拉低,VDD拉高电平。RS为0时,写命令,为1时写数据;R/为1时表示读,0时表示写;E数据使能端,下降沿送入有效。RD0~RD3,数据输入端,使用液晶显示器端口的高4位。
4.软件框图
端口﹑LCD和IIC初始化及端口若上拉
显示预显示的数字和字母
延迟2秒
写入初值到时钟芯片
显示时间﹑读和显示温度﹑显示字母星期
时间加减设置
闹钟设置和进行比较
蜂鸣器响
C=0或2
C=1
C=2
S4第三次按下
蜂鸣器不响
C=3
根据闹钟按键判断
该功能在中断程序段中
5.软件功能介绍
5.1
端口﹑LCD和IIC初始化及端口若上拉
//初始化端口
void
CSH(void)
{TRISB=0b11111111;
//端口B全为输入
TRISC=0b00011000;
//端口C中RC3和RC4为输入,其余为输出
ANSELH=0b00000000;
//选择I/O口
ANSEL=0;
//选择I/O口
OPTION=0b00000000;
//允许若上拉,下降沿中断
WPUB=0b11111111;
//B口若上拉
TRISA4=1;
//A口第5引脚为输入
TRISD=0b00000000;//控制LCD1604,全为输出
IOCB=0b00001111;
//允许电平变化中断
INTCON=0b11001000;
//允许全局中断,B口电平变化中断
FMQ=0;
//蜂鸣器不响
LCD_CSH();
//LCD初始化
IIC_CSH();
//IIC初始化
}
此为对端口﹑LCD和IIC的初始化,上面均有详细的说明,在此不做过多的重复。
LCD的初始化,上电时需要延时15ms及以上,此为延时20ms,其C程序见附录。
IIC的初始化,初始化过程实际上是对几个相关的寄存器设置的过程,其C程序见附录。
5.2
显示预显示的数字和字母
const
char
MENU0[2][17]={
{“010900628
“},{“linyixing
“}};
//完全按照数组中的字符显示整屏
void
DISP_MENU(const
charA)
{
char
i,j;
for
(i=0;i>4;//取高4位
LCD_WRITE_4(R2,FLAG);//先写高4位
R2=R1
//高4位清0,取低4位
LCD_WRITE_4(R2,FLAG);//再送低4位
DELAY_US(10);//延时100us
}
//写R1的低4位,FLAG为寄存器选择,1为命令,0为数据
void
LCD_WRITE_4(char
R1,char
FLAG)
{LCD_RW=0;NOP();//写模式
LCD_RS=FLAG;NOP();
//寄存器选择
PORTD
NOP();//RD高4位先清0
LCD_E=1;NOP();//使能
PORTD
|=R1;NOP();//送4位
LCD_E=0;NOP();//数据送入有效
LCD_RS=0;NOP();
PORTD
//RD高4位清0
}
此程序的功能的把给定的字符显示到LCD液晶显示器上,字符串有两行,分行显示。先是对要显示的位置进行定位,如第一行第0位。然后将一个字符的高低4位分别送入显示,显示时送入的是ASCII码。
5.3
根据闹钟按键判断
此为根据c=0,1,2来判断的。为0或2时,显示的是时钟芯片的时间,其中为2时,时钟有在比较时间;为1时显示的时闹钟设定的时间。c为3
时蜂鸣器不响。其C程序详见附录。
5.4
写入初值到时钟芯片
LCD_WRITE(0b00000001,COM);
//清屏
WRITE_DS1307(0x07,0x10);//写控制字到LCD
WRITE_DS1307(0x00,0x00);//0秒
WRITE_DS1307(0x01,0x00);//00分
WRITE_DS1307(0x02,0x11);
//11h
WRITE_DS1307(0x03,0x03);//星期3
WRITE_DS1307(0x04,0x08);//8日
WRITE_DS1307(0x05,0x05);//5月
WRITE_DS1307(0x06,0x12);//12年
//写ds1307,地址为address,数为data
void
WRITE_DS1307(char
ADDRESS,char
da)
{
START_BIT;
IIC_SEND(ADDR);
IIC_SEND(ADDRESS);
IIC_SEND(da);
STOP_BIT;
}
//发送数R并等待发送完成,收到从机的应答信号,中断用
void
IIC_SEND_interrupt(char
R)
{SSPBUF=R;//发送
SSPIF=0;
while
(RW==1);//在主动模式下,判断发送是否完成
while
(SSPIF==0);//等待发送完成
while
(ACKSTAT==1);//等待从机发送应答信号
NOP();
NOP();
}
写入初值到时钟芯片时,要用到IIC通讯,即IIC发送。先送时钟地址,再送要写入数据的地址,再送入数据。此可对时钟芯片的年月日,秒分时和星期进行设定初值。
5.5
时间加减设置
//校正时候实现“加”功能子程序
void
INC(void)
{
if(a==7)
//年部分校正
{
AAAA[6]+=1;
//如果a==7,则数组[6]自动加1
if((AAAA[6]
AAAA[6]=AAAA[6]+0x10;
//数组[6]元素的低四位大于9时,则低四位清零而高四位进1位
}
if(AAAA[6]>0x99)
AAAA[6]=AAAA[6]//如果数组[6]元素值大于0x99,则整个数都清零
if(c==0)
WRITE_DS1307_interrupt(0x06,AAAA[6]);//将经过修改的数组元素写入
if(c==1)
{
LCD_WRITE_interrupt(LINE1+4,COM);
DISP_HEX_interrupt(AAAA[6]);
}
}
}
此功能从DS1307中读出时间数据,然后对数据进行加减运算,再把修改后的时间写入到时钟芯片中,即可实现对时间的加减运算。由于程序篇幅较长,在此只列出部分加的C程序,其余加C程序及减C程序详见附录。
5.6
显示时间﹑读和显示温度﹑显示字母星期
READ_DS1307(0x00,0x07);
//读时钟芯片
(设置闹钟时间是没有这一行指令)
DISP_TIME(*AAAA);
//实时显示时间
(具体C程序见附录)
R1=READ_T();
//读温度传感器的值
DISP_T(R1);
//显示温度值
DISP_XINGQI(AAAA[3]);
//显示字母星期
//显示字母星期
void
DISP_XINGQI(char
b)
{
if(b==1)
//如果b=1,则显示Mon
{
LCD_WRITE(LINE1+13,COM);//第二行第13位
LCD_WRITE(
M,DAT);
LCD_WRITE(
o,DAT);
LCD_WRITE(
n,DAT);//13、14、15分别显示M、o、n
}
else
if(b==2)
//如果b=2,则显示Tue
{
LCD_WRITE(LINE1+13,COM);//同上
LCD_WRITE(
T,DAT);
LCD_WRITE(
u,DAT);
LCD_WRITE(
e,DAT);//同上
}
}
其完整程序详见附录,在此只给出其中的一部分。
//读TC74的温度值
signed
char
READ_T(void)
{
signed
char
R2;
SEN=1;//开始条件
while
(SEN==1);//检测开始条件是否完成?
IIC_SEND(TC74_ADD
__CONFIG(0x20F1);//调试用
__CONFIG(0x3FFF);
#defineLCD_ERD6//LCD
E
读写使能控制
#defineLCD_RWRD5//LCD
读(1)/写(0)控制线
#define
LINE10b10000000
#define
LINE20b11000000
#defineLCD_RSRD4//LCD
寄存器选择
数据(1)指令(0)
//RD4-RD7分别接DB4-DB7,RD7为忙标志
#define
COM0//在LCD_WRITE()中的第2参数为0表示写命令
#define
DAT1//在LCD_WRITE()中的第2参数为1表示写数据
#define
TC74_ADD
0b1001101
//TC74的7位地址
#define
RTR0b00000000
//TC74的读温度命令
#define
ADDR
0b11010000
//时钟芯片的地址
#define
YEAR_P
LINE1+2
//年的显示位置
#define
HOUR_P
LINE2+2
//时的显示位置
#define
KEY_DEC
RB2
#define
KEY_INC
RB1
#define
FMQ
RC1
//产生起始位,检测完成起始位?
#define
START_BIT
/
SEN=1;/
while(SEN==1)
//停止位,检查至停止位结束
#define
STOP_BIT
/
PEN=1;
/
while(PEN==1)
//发送重复开始,确定重复开始已完成?
#define
RE_START_BIT
/
RSEN=1;/
while(RSEN==1)
//接收使能模式,确定接收使能?
#define
RECEIVE_ENABLE_BIT/
RCEN=1;/
while(RCEN==1)
//自动应答,检查是否完成应答?
#define
ACK_BIT/
ACKDT=0;/
ACKEN=1;/
while(ACKEN==1)
//不应答,检查是否完成无应答?
#define
NOT_ACK_BIT/
ACKDT=1;/
ACKEN=1;/
while(ACKEN==1)
bank1
char
DD[16];//一行LCD显示数据暂存
bank1
char
AAAA[7];
//存放时钟芯片读出来的数据
bank1
char
CCCC[7];
//存放闹钟设定的时间
void
CSH(void);//初始化
void
LCD_CSH(void);//LCD初始化
void
LCD_BUSY(void);//检测LCD是否忙
char
LCD_READ(void);//读LCD,忙检测用
void
LCD_WRITE(char,char);//LCD写1字节,命令或数据
void
LCD_WRITE_4(char,char);//LCD写半字节
void
DISP_C(char);//在指定行中显示字符,字符在数组DD中
void
DISP_MENU(const
char);//由常数数组显示整屏字符
signed
char
READ_T(void);
//读温度传感器的温度值
void
IIC_CSH(void);
//IIC的初始化
void
IIC_SEND(char);
//IIC的发送与接收
void
DISP_T(char);
//显示温度值
void
BCD(char);
//BCD码转换
void
DELAY_US(char);
//延迟程序,10uS级
void
DELAY(unsigned
int);
//延迟程序,mS级
void
DELAY_I(unsigned
int);
//中断用的延迟程序,mS级
void
DISP_TIME(char);
//显示时钟的时间
void
DISP_HEX(char);
//将一个字节分两个字节显示
void
READ_DS1307(char,char);
//读时钟芯片
void
WRITE_DS1307(char,char);
//向时钟芯片写入值
void
interrupt
ISR(void);
//按键中断程序
void
DISP_XINGQI(char);
//星期转换,显示字母星期
void
INC(void);
//按键加1
void
DEC(void);
//按键减1
void
IIC_SEND_interrupt(char);
//中断用IIC发送和接收
void
WRITE_DS1307_interrupt(char,char);
//中断用写时钟芯片
//void
READ_DS1307_interrupt(char,char);
void
LCD_WRITE_interrupt(char,char);
//中断用写LCD
void
DISP_HEX_interrupt(char);
//中断用将一个字节显示成两个字节
//整屏界面,每行16个字符,最后加一个结束符
const
char
MENU0[2][17]={
{“010900628
“},{“linyixing
“}};
//定义常数
const
char
LINE[2]={LINE1,LINE2};
//定义数组和变量
char
SW,GW,a=0,c=0,d,i;
//主程序
main(void)
{
signed
char
R1;
//DELAY(100);
CSH();
//端口,LCD和IIC初始化
DISP_MENU(*MENU0);//显示整屏
DELAY(2000);
//延迟2秒,看清显示是什么
LCD_WRITE(0b00000001,COM);
//清屏
WRITE_DS1307(0x07,0x10);//写控制字到LCD
WRITE_DS1307(0x00,0x00);//0秒
WRITE_DS1307(0x01,0x00);//00分
WRITE_DS1307(0x02,0x11);
//11h
WRITE_DS1307(0x03,0x03);//星期3
WRITE_DS1307(0x04,0x08);//8日
WRITE_DS1307(0x05,0x05);//5月
WRITE_DS1307(0x06,0x12);//12年
while(1)
{
if((c==0)||(c==2))
//当C=0或C=2时执行
{
READ_DS1307(0x00,0x07);
//读时钟芯片
DISP_TIME(*AAAA);
//实时显示时间
R1=READ_T();
//读温度传感器的的值
DISP_T(R1);
//显示温度值
DISP_XINGQI(AAAA[3]);
//显示字母星期
}
if(c==1)
//C=1时执行
{
DISP_TIME(*AAAA);
//显示闹钟修改的时间
R1=READ_T();
//同上
DISP_T(R1);
//同上
DISP_XINGQI(AAAA[3]);
//同上
}
if((CCCC[2]==AAAA[2])
//当设定的时间到时,蜂鸣器响
};
}
//显示字母星期
void
DISP_XINGQI(char
b)
{
if(b==1)
//如果b=1,则显示Mon
{
LCD_WRITE(LINE1+13,COM);//第二行第13位
LCD_WRITE(
M,DAT);
LCD_WRITE(
o,DAT);
LCD_WRITE(
n,DAT);//13、14、15分别显示M、o、n
}
else
if(b==2)
//如果b=2,则显示Tue
{
LCD_WRITE(LINE1+13,COM);//同上
LCD_WRITE(
T,DAT);
LCD_WRITE(
u,DAT);
LCD_WRITE(
e,DAT);//同上
}
else
if(b==3)
//如果b=3,则显示Wed
{
LCD_WRITE(LINE1+13,COM);//同上
LCD_WRITE(
W,DAT);
LCD_WRITE(
e,DAT);
LCD_WRITE(
d,DAT);//同上
}
else
if(b==4)
//如果b=4,则显示Thu
{
LCD_WRITE(LINE1+13,COM);//同上
LCD_WRITE(
T,DAT);
LCD_WRITE(
h,DAT);
LCD_WRITE(
u,DAT);//同上
}
else
if(b==5)
//如果b=5,则显示Fri
{
LCD_WRITE(LINE1+13,COM);//同上
LCD_WRITE(
F,DAT);
LCD_WRITE(
r,DAT);
LCD_WRITE(
i,DAT);//同上
}
else
if(b==6)
//如果b=6,则显示Sat
{
LCD_WRITE(LINE1+13,COM);//同上
LCD_WRITE(
S,DAT);
LCD_WRITE(
a,DAT);
LCD_WRITE(
t,DAT);//同上
}
else
if(b==7)
//如果b=7,则显示Sun
{
LCD_WRITE(LINE1+13,COM);//同上
LCD_WRITE(
S,DAT);
LCD_WRITE(
u,DAT);
LCD_WRITE(
n,DAT);//同上
}
}
//中断子程序
void
interrupt
ISR(void)
{
DELAY_I(30);
//按键去抖
RBIF=0;
//标志位清零
if(RB3==0)
//闹钟键按下
{
a=0;c+=1;d+=1;
}
if(RB0==0
if(a==8)
a=1;
}
if(RB1==0}
if(RB2==0}
if(c==1)
//闹钟键按下
{
if(RB0==0)
//闹钟键按下的定位
{
a++;
if(a==8)
a=1;
}
if(RB1==0)
//同上
{INC();}
if(RB2==0)//同上
{DEC();}
for(i=0;i9)
{AAAA[6]=AAAA[6]
AAAA[6]=AAAA[6]+0x10;
//数组[6]元素的低四位大于9时,则低四位清零而高四位进1位
}
if(AAAA[6]>0x99)
AAAA[6]=AAAA[6]//如果数组[6]元素值大于0x99,则整个数都清零
if(c==0)
WRITE_DS1307_interrupt(0x06,AAAA[6]);//将经过修改的数组元素写入
if(c==1)
{
LCD_WRITE_interrupt(LINE1+4,COM);
DISP_HEX_interrupt(AAAA[6]);
}
}
//月部分校正
if(a==6)
{
AAAA[5]+=1;
if((AAAA[5]
AAAA[5]=AAAA[5]+0x10;
//数组[5]元素的低四位大于9时,则低四位清零而高四位进1位
}
if(AAAA[5]>0x12)
{
AAAA[5]=AAAA[5]
AAAA[5]=AAAA[5]+0x01;//如果数组[5]元素值大于0x12,则整个数都清零再加1
}
if(c==0)
WRITE_DS1307_interrupt(0x05,AAAA[5]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE1+7,COM);
DISP_HEX_interrupt(AAAA[5]);
}
}
//日部分校正
if(a==5)
{
AAAA[4]+=1;
if((AAAA[4]
AAAA[4]=AAAA[4]+0x10;//数组[4]元素的低四位大于9时,则低四位清零而高四位进1位
}
if(AAAA[4]>0x31)
{
AAAA[4]=AAAA[4]
AAAA[4]=AAAA[4]+0x01;//如果数组[4]元素值大于0x31,则整个数都清零再加1
}
if(c==0)
WRITE_DS1307_interrupt(0x04,AAAA[4]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE1+10,COM);
DISP_HEX_interrupt(AAAA[4]);
}
}
//星期部分校正
if(a==4)
{
AAAA[3]+=1;
if(AAAA[3]>7)
AAAA[3]=1;
//如果数组[3]的元素大于7时,则复位到1
if(c==0)
WRITE_DS1307_interrupt(0x03,AAAA[3]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE1+13,COM);
DISP_HEX_interrupt(AAAA[3]);
}
}
//时部分校正
if(a==3)
{
AAAA[2]+=1;
if((AAAA[2]
AAAA[2]=AAAA[2]+0x10;//数组[2]元素的低四位大于9时,则低四位清零而高四位进1位
}
if(AAAA[2]>0x23)
{
AAAA[2]=AAAA[2]//如果数组[2]元素值大于0x24,则整个数都清零
}
if(c==0)
WRITE_DS1307_interrupt(0x02,AAAA[2]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE2+2,COM);
DISP_HEX_interrupt(AAAA[2]);
}
}
//分部分校正
if(a==2)
{
AAAA[1]+=1;
if((AAAA[1]
AAAA[1]=AAAA[1]+0x10;//数组[1]元素的低四位大于9时,则低四位清零而高四位进1位
}
if(AAAA[1]>0x59)
AAAA[1]=AAAA[1]
//如果数组[1]元素值大于0x59,则整个数都清零
if(c==0)
WRITE_DS1307_interrupt(0x01,AAAA[1]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE2+5,COM);
DISP_HEX_interrupt(AAAA[1]);
}
}
//秒部分校正
if(a==1)
{
AAAA[0]+=1;
if((AAAA[0]
AAAA[0]=AAAA[0]+0x10;//数组[0]元素的低四位大于9时,则低四位清零而高四位进1位
}
if(AAAA[0]>0x59)
AAAA[0]=AAAA[0]
//如果数组[0]元素值大于0x59,则整个数都清零
if(c==0)
WRITE_DS1307_interrupt(0x00,AAAA[0]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE2+8,COM);
DISP_HEX_interrupt(AAAA[0]);
}
}
}
//校正时候实现“减”功能子程序
void
DEC(void)
{
if(a==7)
//年部分校正
{
AAAA[6]-=1;
//如果a==0,则数组[6]自动减1
if((AAAA[6]
AAAA[6]=AAAA[6]+0x09;//数组[6]元素的低四位大于9时,则低四位清零且改为0x09,而高四位则自动减1
}
if(((AAAA[6]
AAAA[6]=AAAA[6]+0x99;//如果数组[6]元素高四位大于9时,则整个数值清零再改为0x99
}
if(c==0)
WRITE_DS1307_interrupt(0x06,AAAA[6]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE1+4,COM);
DISP_HEX_interrupt(AAAA[6]);
}
}
//月部分校正
if(a==6)
{
AAAA[5]-=1;
if((AAAA[5]
AAAA[5]=AAAA[5]+0x09;
//数组[5]元素的低四位大于9时,则低四位清零且改为0x09,而高四位则自动减1
}
if(AAAA[5]==0x00)
AAAA[5]=AAAA[5]+0x12;//如果数组[5]元素等于0时,则整个数值改为0x12
if(c==0)
WRITE_DS1307_interrupt(0x05,AAAA[5]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE1+7,COM);
DISP_HEX_interrupt(AAAA[5]);
}
}
//日部分校正
if(a==5)
{
AAAA[4]-=1;
if((AAAA[4]
AAAA[4]=AAAA[4]+0x09;
//数组[4]元素的低四位大于9时,则低四位清零且改为0x09,而高四位则自动减1
}
if(AAAA[4]==0x00)
AAAA[4]=AAAA[4]+0x31;//如果数组[4]元素等于0时,则整个数值改为0x31
if(c==0)
WRITE_DS1307_interrupt(0x04,AAAA[4]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE1+10,COM);
DISP_HEX_interrupt(AAAA[4]);
}
}
//星期部分校正
if(a==4)
{
AAAA[3]-=1;
if(AAAA[3]<1)
AAAA[3]=7;//如果数组[3]的元素小于1时,则复位到7
if(c==0)
WRITE_DS1307_interrupt(0x03,AAAA[3]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE1+13,COM);
DISP_HEX_interrupt(AAAA[3]);
}
}
//时部分校正
if(a==3)
{
AAAA[2]-=