带有温显示和液晶显示器的实时时钟设计_第1页
带有温显示和液晶显示器的实时时钟设计_第2页
带有温显示和液晶显示器的实时时钟设计_第3页
带有温显示和液晶显示器的实时时钟设计_第4页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

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

文档简介

1、河北联合大学综合性课程设计报 告学院名称:专业名称:课设题目:带有温度显示和液晶显示器的实时时钟设计学生姓名:学 号:同组人:指导教师:完成时间:设计目标: 设计基于单片机的具有液晶显示器的实时时钟,能够通过液晶显示器正确显示当前时间,包括年,月,日,星期,时,分,秒。并且能够通过按键对系统的时间进行修改设定;能够显示当前的室温。研究内容: 学习 EDA软件 Proteus 的使用,能够利用Proteus 软件画出电路图并实现仿真。学习电子系统设计步骤,按步骤完成电子系统的概要设计、选型、详细设计,系统测试仿真。设计带有温度显示基于单片机具有液晶显示功能的实时时钟,编写程序,并利用 prote

2、us 软件进行模拟仿真。研究方法: 绘制原理图及电路图,利用软件环境编程调试。实验步骤:1、打开Keil 软件,新建一个工程文件,选择好芯片,并记得在Output 选项中,将Create HEX Fil 选项勾起来。“ Options for Target 1”的2、将编写的程序保存成“.C”的形式3、编译保存好的C 文件,并根据提示修改程序中的错误,直到编译成功为止4、打开proteus 软件,画出实验电路图5、在 89C51 中,载入原来已生成的HEX 文档6、按下运行键,对Proteus 进行软件仿真,观察运行结果原理结果及分析一、设计方案原理与设计特点分析电子钟总的设计模块:温度采集模

3、块按键处理模块89C51CPU控制模块DS1302 时钟LCD显示模块采集模块各个模块电路原理分析:1、DS1302 时钟采集模块:1.1 电路原理图:1.2DS1302 分析:首先DS1302 是DALLAS公司推出的涓流充电时钟芯片。内含有一个实时时钟/日历和31 字节静态RAM通过简单的串行接口与单片机进行通信实时时钟/日历电路提供秒分时日日期月年的信息每月的天数和闰年的天数可自动调整时钟操作。DS1302 芯片广脚介绍: X1 、X2 为 32.768KHz 晶振管脚。 GND 为地。 RST 复位脚。 I/O 数据输入 /输出引脚。 SCLK 串行时钟。 Vcc1,Vcc2 电源供电

4、管脚。与单片机连接的信号线为:DS1302_SCLK接P16。实时时钟时钟线引脚DS1302_IO 接 P17。实时时钟数据线引脚DS1302_RST 接 P15。实时时钟复位线引脚特别注意DS1302 芯片在读取或写入数据时,都是一位一位传送的,并且每传送一位, SCLK 信号线要有一个负跳变。即单片机对SCLK 咬先送高电平,再送低电平。数据时通过 IO 进行传送的。1.3 数据处理子程序流程图是否调用时间获取子否程序 DS1302_GetTime是调用 Read1302 函数,读取各个时间参数,并存放于ReadValue 变量中对 ReadValue 数据进行转换,转换成十进制数,并赋给

5、 Time 指针中。调用年份转换成可供lcd 显示的字段子程序 DateToStr时间转换成可供lcd 显示的字段子程序 TimeToStr结束因为DS1302 芯片在读取或写入数据时,都是一位一位传送的,并且每传送一位,SCLK 信号线要有一个负跳变。所以在对DS1302 具体某地址进行一字节数据的写入或读取时,都要调用实时时钟写入一字节(内部函数 ) DS1302InputByte和实时时钟读取一字节( 内部函数 )DS1302OutputByte 两个函数。2、按键处理模块2.1 按键连线图从左到右依次是:进位键,数字加,数字减,退出Mode 模式键2.2 按键扫描子程序流程图:Mode

6、 键是否按下将进位按键键次数存放于变量 mode_num 中mode_n否否否否mode_nmode_nuum=1?um=2 ?m=3 ?是是是是是否否mode_num=7 ?是是移动光标,并返回mode_numode_nm=4?um=5?mode_num=6?2.3 加减键处理子程序流程图判断是否为修改否模式是判断是否为加一转减一键程序否键是判断 num=1?否判断 num=2 ?判断 num=3否是是是修改year 值,修 改 mouth修改 day 值,并返回值,并返回并返回否?否判断 num=5?判断 num=4 ?判断 num=6是是是修改秒值,并返修改分值,并返修改小时值,并回回返

7、回减 1 子程序与加1 子程序区别只在于修改数值处理不一样,其他都一样。3、LCD 显示模块3.1LCD 显示模块电路原理图3.2LCD1602 芯片以及连线分析液晶显示器是一种功耗极低的被动式显示器件,1602 广脚介绍: D0 D7 数据传送引脚, VSS 为接地线, VDD为电源线, VEE 为 LCD 驱动电压调节,由此可以调节显示亮度。 RS 为寄存器选择信号,高电平选择数据寄存器,低电平选择指令寄存器。RW 为读写控制信号,高电平读,低电平写。 EN 使能信号,读状态下高电平有效,写状态下下降沿有效。RS 连接 P20。寄存器选择信号RW 连接 P21。读写控制信号线EN 连接 P

8、22。使能信号线3.3LCD 初始化程序流程图:写指令0x38 ,显示模式设置写指令,显示光标写指令,光标移动清屏在初始化过程中,要反复调用到write_com 函数,此函数实现向lcd 写入命令的功能。要特别注意写命令和写数据的RS、RW 、 EN 时序问题4、温度采集显示模块4.1 温度采集显示模块的原理图:4.2DS18B20 芯片以及连线分析DSl820 数字温度计提供9 位( 二进制 )温度读数,指示器件的温度、信息经过单线接口送入 DSl820 或从 DSl820 送出。因此从主机CPU 到 DSl820 仅需一条线 (和地线 ) , DSl820的电源可以由数据线本身提供而不需要

9、外部电源。DS18B20 广脚说明: VCC 为电源线, DQ 为数据线, GND 为地线。数据线 DQ 与单片机 P1.0 相连接。4.3 温度采集显示模块子程序流程图:直接向18b20 发送温度变换命令读取温度寄存器的温度值读低八位读高八位进行读取数据处理,得出温度存放于变量temp 中在此程序中,要特别注意初始化,写和读取数据时的时序处理。首先,初始化中,主机总线先发送一复位脉冲(最短为480us 的低电平信号),接着刻释放总线并进入接收状态。 DSl8b20 在检测到总线的上升沿之后,等待15-60us,接着DS18b20 发出存在脉冲(低电平 持续 60-240 us)。写数据时序:

10、当主机总线先从高拉至低电平时,就产生写时间隙。读书序:主机总线先从高拉至低电平时,总线只须保持低电平l7ts 之后,再将总线拉高,产生读时间隙。5、总原理图以及主程序流程图:5.1 总的原理图:5.2 主程序流程图:初始化 lcd初始化内部定时器初始化 DS1302从 DS1302 读取日期和时间移动光标并显示日期移动光标并显示时间移动光标并显示温度重复进行按键扫描二、 Proteus仿真结果:三、实验数据计算处理,性能分析1、数据计算处理:1.1 计算星期数的算法days=(today.day+1+2*today.month+3*(today.month+1)/5+today.year+to

11、day.year/4-today.year/100+today.year/400)%7 ,由年月日计算星期,用以显示星期数1.2 加减键对时间日期改变处理算法对于年月日,时分秒来说,每个变量的最大值和最小值都不一样,所以当年月份时分秒改变时,进行处理的算法也不一样,年没有最大值,所以不用采取“封顶”措施,每次年加一处理时,直接自加,而对于月份来说,月份是不能超过13 的,所以当月份自加到13 时要重新置1,具体处理见程序,在每个语句后,我都有分析注释出来。1.3 时分秒进位算法当秒,分达到 60 时,向分进位,且秒数置零,从新开始计数。当时达到24 时,也一样处理。1.4 年月日进位算法因为每

12、个月份的天数都不同,所以事先先设定一数组:dayofmonth=31,28,31,30,31,30,31,31,30,31,30,31用以判定 12 个月的最大值,接着判断天数,当超过本月最大天数时,月份加一,且天数要置1 。月份判断比较简单,只要超过12,年份就加 1,月份置 1。2、性能分析:首先, lcd 能够正确的显示1302 芯片上面的时间和日期。其次,可以通过五个按键: K1, K2、K3 、K4 和K5 键对电子钟进行时间和日期的调整。按 K1 键进行校时 ,可以分别对时及分进行单独校时,使其校正到标准时间,校时时用K2键进行调整,需要校正哪一位哪一位就闪烁。按K3 键是对闪烁位

13、进行加一的操作。按K4键是对闪烁位进行减一的操作。按K5 键,就可以退出调整模式。但是,时间和日期显示正确,但温度显示错误。温度不能正常显示的主要原因是DS18b20 的数据传输不正确。五、实验结论以及体会实验结论:1、在该电子钟的设计中修改定时或调整时间时采用了闪烁,在编程上,首先进行了初始化定义了程序的入口地址以及中断的入口地址,在主程序的开始定义了一组固定单元用来存储计数的秒,分,时以及定时时间的序号等。其次,时,分 ,秒显示用了软件译码(查表 )的方式 ,再用了一段固定的程序段进行进制转化。最后,用查询方式对按键进行判断,若有键按下 ,则进行软件延时消抖 ,避免了抖动引起的干扰 ,执行

14、相应的定时 ,选时或调时程序段。对当前时间或定时时间修改后又返回到最初的显示程序段,如此循环下去。2、在硬件上,选用DS1302, LCD1602 相结合,首先DS1302 内含有一个实时时钟/日历和 31 字节静态RAM 通过简单的串行接口与单片机进行通信实时时钟/日历电路提供秒分时日日期月年的信息每月的天数和闰年的天数可自动调整时钟操作,这样读取数据简单。其次,选用 LCD1602 进行显示时,数据位串行输入,接口连线少,低功耗,显示清晰。并且本实验的电子钟即要实现时间的现实,还要实现日期的现实,所以若是运用数码管进行显示的话,就算运用动态显示,所占用的IO 口多,并且所需的数码管个数多,

15、硬件复杂。3、 proteus 是一个非常好用的仿真软件,其具有强大的电路原理图绘制功能,且可以实现模拟电路仿真、数字电路仿真、单片机及其外围电路组成的系统仿真、键盘、LCD 系统仿真等多种功能;和keil 联合使用时可以检测所编写的程序的正确与否。将keil和proteus 联合起来使用是实现电子设计制作的初步阶段,可避免在实际的硬件操作中因为电路原理图或向单片机烧录的程序有误而造成的难以修改的为题。实验心得:1、通过本次实验,因为之前接触到的电子系统设计不多,所以一开始,感觉难以入手,就算上网载了很多程序,也看不懂。后来请求同学的帮助,了解了要对各种芯片编写程序时首先应找到该芯片的数据手册

16、,根据数据手册上的说明、时序要求及流程图编写对应程序。2、其次,再次巩固了KeilC51 工程文件的建立,程序编写以及编译的掌握程度。最重要的是,因为只是水平有限,要自己编写C 程序很难,但在此实验中,最大的收获莫过于看懂别人的程序,分析之后,自己拼凑编写以实现不同的功能。并且掌握了52C 程序的编写过程。3、掌握了Proteus 的使用方法,从实际操作中认识到Proteus 在仿真方面的优越性,激发了自己学习Proteus 的兴趣;4、因为自己要修改程序,所以单单花费在程序分析的时间就很多,为了更好的理解程序,我把每句主要程序的后面都注释了该语句的意思,详情可以见程序清单,发现注释语义的工作

17、量也是非常大的。写实验报告时,每个模块的流程图都是自己画的,用 WORD 文档画图真的很麻烦,而且不是很美观。因为时间比较仓促,流程图写的条理性不够,不过相信以后多多练习,就可以做得更好。5、在这次实验中我遇到了很多故障,不过通过各种渠道(比如网络,请教同学,老师等等)解决了一些故障,虽然没有全部解决,但能在短短一周内通过此次作业,实现电子钟的功能,还是有点成就感的。在解决这些问题的过程中发现网络确实是一个很好的学习平台,利用前人的经验可以提高自己的解决实际问题的能力。通过这一个多礼拜的学习实践,使我对所学的知识进行了系统的复习和巩固,在以前学习中不够清晰的概念得到了更好的理解。相信通过不断的

18、学习,能使自己扬长补短。六、程序清单1、主程序#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit DQ=P30 。unsigned int temp 。unsigned char ly_dis4=0,0,0,0。unsigned char tl=0,th=0 。sbit ACC0 = ACC0 。sbit ACC7 = ACC7 。sbit t=P10 。/进入调时按键sbit jia=P11 。 /加一按键sbit jian=P12 。

19、 /减一按键sbit m=P13 。 / 退出调时按键sbit BEEP=P20 。/ 蜂鸣器sbit jtod=P14 。 /矩阵按键转独立按键,该脚置 0sbit T_CLK= P16。 /* 实时时钟时钟线引脚 */sbit T_IO = P35。 /* 实时时钟数据线引脚*/sbit T_RST = P17 。 /* 实时时钟复位线引脚*/sbit E=P27 。/1602 使能引脚sbit RW=P26 。/1602 读写引脚sbit RS=P25 。/1602 数据 /命令选择引脚ucharcodehanzi8=0x04,0x0f,0x12,0x0f,0x0a,0x1f,0x02,

20、0x02,0x0f,0x09,0x0f,0x09,0x0f,0x09,0x13,0x11,0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x00 。void v_W1302(uchar ucAddr, uchar ucDa) 。uchar uc_R1302(uchar) 。uchar dectobcd(uchar bcd) 。uchar bcdtodec(uchar) 。void beep() 。void delay(uchar x)uchar i 。while(x-)for(i=0 。 i<110 。 i+) 。/* * 名称 : enable(uchar de

21、l)* 功能 : 1602 命令函数* 输入 : 输入的命令值* 输出:无* */void enable(uchar del)RS=0。RW=0。P0 = del 。E=1。delay(3) 。E=0。/* * 名称 : write(uchar del)* 功能 : 1602 写数据函数* 输入 : 需要写入 1602 的数据* 输出:无* */void write(uchar del)RS=1。RW=0。P0 = del 。E=1。delay(3) 。E=0。/* * * 名称 : L1602_init()* 功能 : 1602 初始化,请参考1602 的资料* 输入 :无DQ=0。 /给脉

22、冲信号* 输出 : 无dat>>=1 。*DQ = 1 。 / 给脉冲信号*/if(DQ)void L1602_init(void)dat|=0x80 。mdelay(5) 。enable(0x01)。enable(0x38)。return(dat) 。enable(0x06)。enable(0x0c)。void mWrite(unsigned char dat)/ 写字节E=0。unsigned char i=0 。for (i=8 。 i>0 。 i-)DQ=0。/分别为 0-9,不显示,负号DQ = dat&0x01 。mdelay(5) 。/带小数点显示DQ

23、= 1 。dat>>=1 。voidmdelay(unsignedinti)/ 如 果i是unsigend char 类型,则会出现错误结果while(i-) 。void mInit(void)/初始化/unsigned char flag=0 。DQ = 0。/单片机将DQ 拉低mdelay(100) 。/ 精 确延 时大于 480us 小于 960usDQ = 1。/拉高总线mdelay(30) 。/flag=DQ 。/ 稍做延时后如果 flag=0 则初始化成功flag=1 则初始化失败/mdelay(20) 。unsigned char Read(void)/ 读字节uns

24、igned char i=0 。unsigned char dat = 0。for (i=8 。 i>0 。 i-)/ 装入自定义字符(汉字)void writch()uchar i,j 。enable(0x40) 。for(i=0 。 i<8 。 i+)for(j=0 。 j<8 。j+)write(hanziij)。/* 名 称 : L1602_char(uchar hang,uchar lie,char sign)* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示 "b" ,调用该函数如下L1602_char(1,5,'b

25、9;)* 输入 : 行,列,需要输入1602 的数据*输出:无*/voidL1602_char(ucharhang,ucharlie,charsign)void timechange()uchar a,num=1 。uchar year,mon,day,hour,min,sec。/ 进入调时循环while(num)uchar a。if(t=0)if(hang = 1) a = 0x80。delay(5) 。if(hang = 2) a = 0xc0。if(t=0)a = a + lie - 1 。enable(a)。num+ 。write(sign) 。beep()。while(!t)。/*/

26、 退出调时按键m*if(m=0)*名 称:L1602_string(ucharhang,uchardelay(5) 。lie,uchar *p)if(m=0)* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下num=0 。enable(0x0f) 。a=uc_R1302(0x81)|0x80 。ef。 ")L1602_string(1,5,"abcdv_W1302(0x8e,0)v_W1302(0x80,a)。* 输入 : 行,列,需要输入1602 的数据*输出:无*/void L1602_stri

27、ng(uchar hang,uchar lie,uchar*p)/ 调时到年以后退出调时if(num=7)num=0 。/num=1 调秒if(num=1)enable(0xc0+9) 。uchar a。if(jia=0)if(hang = 1) a = 0x80。delay(5) 。if(hang = 2) a = 0xc0。if(jia=0)a = a + lie - 1 。/秒加一enable(a)。while(1)while(!jia)。sec=bcdtodec(uc_R1302(0x81)&0x7f)。if(*p = '0') breakwrite(*p) 。

28、sec+。if(sec>59)p+。sec=0。L1602_char(2, 9, sec/10%10+48)L1602_char(2, 10, sec%10 + 48)。/时钟调节/v_W1302(0x80,dectobcd(sec)|0x80)if(jian=0)。/if(min=-1)min=59 。L1602_char(2, 6,min / 10 % 10 +秒减一48)。delay(5) 。if(jian=0)L1602_char(2, 7, min % 10 + 48) 。v_W1302(0x82,dectobcd(min) 。while(!jian) 。sec=bcdtode

29、c(uc_R1302(0x81) 。if(num=3)/sec-。调小时if(sec=-1)sec=59。enable(0xc0+3) 。L1602_char(2, 9, sec/10%10+48)L1602_char(2, 10, sec%10 + 48)v_W1302(0x80,dectobcd(sec)|0x80) 。if(num=2)调分钟。/if(jia=0)delay(5) 。if(jia=0)hour = bcdtodec(uc_R1302(0x85) 。hour+ 。while(!jia) 。if(hour>23)hour=0 。L1602_char(2, 3, hour

30、 / 10 % 10 +enable(0xc0+6) 。48)。if(jia=0)L1602_char(2,4,hour%10+delay(5) 。48)。if(jia=0)min = bcdtodec(uc_R1302(0x83)。v_W1302(0x84,dectobcd(hour)if(jian=0)。48)。min+ 。while(!jia) 。if(min>59)min=0 。L1602_char(2, 6, min / 10 % 10 +L1602_char(2, 7, min % 10 + 48) 。v_W1302(0x82,dectobcd(min) 。if(jian=0

31、)delay(5) 。if(jian=0)while(!jian) 。hour = bcdtodec(uc_R1302(0x85) 。hour- 。if(hour=-1)hour=23 。L1602_char(2, 3, hour / 10 % 10 +48)。delay(5) 。L1602_char(2,4,hour%10+if(jian=0)48)。min = bcdtodec(uc_R1302(0x83)min- 。while(!jian) 。v_W1302(0x84,dectobcd(hour)if(num=4)。/调日期mon=0 。L1602_char(1, 8,mon / 10

32、% 10 +enable(0x80+11) 。48)。if(jia=0)L1602_char(1, 9, mon % 10 + 48)。delay(5) 。if(jia=0)hour = bcdtodec(uc_R1302(0x87) 。day+ 。while(!jia) 。if(day>31)day=0。L1602_char(1, 11, day / 10 % 10 +48)。v_W1302(0x88,dectobcd(mon) 。if(jian=0)delay(5) 。if(jian=0)while(!jian) 。mon = bcdtodec(uc_R1302(0x89) 。mon

33、- 。L1602_char(1,12,day%10+if(mon=-1)48)。v_W1302(0x86,dectobcd(day)。mon=12 。L1602_char(1, 8, mon/10%10+48)。if(jian=0)L1602_char(1, 9, mon % 10 + 48)。delay(5) 。if(jian=0)while(!jian) 。day=bcdtodec(uc_R1302(0x87)。v_W1302(0x88,dectobcd(mon)if(num=6)。day-。/ 调年份if(day=-1)day=31。enable(0x80+5) 。L1602_char(

34、1,11,day/10%10+48)。if(jia=0)L1602_char(1,12,day%10+48)v_W1302(0x86,dectobcd(day)if(num=5)/调月份enable(0x80+8) 。if(jia=0)。delay(5) 。if(jia=0)year = bcdtodec(uc_R1302(0x8d) 。year+ 。while(!jia) 。if(year>20)year=0。L1602_char(1, 5, year / 10 % 10 +delay(5) 。48)。if(jia=0)L1602_char(1,6,year%10+48)。mon =

35、bcdtodec(uc_R1302(0x89)。v_W1302(0x8c,dectobcd(year)。mon+ 。while(!jia)。if(jian=0)if(mon>12)delay(5) 。if(jian=0)while(!jian) 。year = bcdtodec(uc_R1302(0x8d) 。year-。if(year=-1)year=20。L1602_char(1, 5, year / 10 % 10 +48)。L1602_char(1,6,year%10+48)。v_W1302(0x8c,dectobcd(year) 。if(num=0)/关闭光标闪烁enable(

36、0x0c)。v_W1302(0x80,uc_R1302(0x81)&0x7f)。/开启 1302 记时/* 名称 : v_RTInputByte ()* 功能 : 往 DS1302 写入 1Byte 数据* 输入 : ucDa 写入的数据* 输出:无* */ void v_RTInputByte(uchar ucDa) uchar i。ACC = ucDa 。T_RST = 1 。for(i=8 。 i>0。 i-)T_IO = ACC0 。T_CLK = 1 。T_CLK = 0 。ACC=ACC>>1 。/* * 名称 : uc_RTOutputByte ()*

37、功能 : 从 DS1302 读取 1Byte 数据*输入:无* 返回值 : ACC*/uchar uc_RTOutputByte(void)uchar i。T_RST = 1 。for(i=8 。 i>0。 i-)ACC = ACC >>1 。ACC7 = T_IO 。T_CLK = 1 。T_CLK = 0 。return(ACC) 。/* 名称:v_W1302(uchar ucAddr, ucharucDa)* 功能 : 往 DS1302 写入数据* 输入 : ucAddr: DS1302 地址 , ucDa: 要写的数据* 返回值: 无*/void v_W1302(uchar ucAddr, uchar ucDa)T_RST = 0 。T_CLK = 0 。T_RST = 1 。v_RTInputByte(ucAddr) 。/ 写地址_nop_() 。_nop_() 。v_RTInputByte(ucDa) 。/写1Byte 数据T_CLK = 1 。T_RST = 0 。/* 名称 : uc_R1302(

温馨提示

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

评论

0/150

提交评论