1、目 录1 前言1 2功能描述与总体方案22.1 功能描述22.2 系统组成23 硬件设计.33.1 时钟电路33.2 复位电路33.3 DS1302 时钟电路.43.4 DS18B20 温度计电路.43.5 按键电路53.6 显示电路.63.7 闹铃模块电路 .74 软件设计 .84.1 主函数流程图84.2 18B20 温度计流程图.94.3 按键电路流程图.105 结语116 参考文献.127 附录.131 - 1 -前言单片微型计算机是随着超大规模集成电路技术的发展而诞生的,由于它具有体积小、功能强、性价比高等特点,所以广泛应用于电子仪表、家用电器、节能装置、军事装置、机器人、工业控制等
2、诸多领域,使产品小型化、智能化,既提高了产品的功能和质量,又降低了成本,简化了设计。本文主要介绍由单片机控制的带有温度显示的电子钟的设计。随着人们生活水平的日益提高,人们对生活的要求越来越高,原有的事物已经不能满足人们的生活需求了,一些带有新功能的事物已经在慢慢的取代旧事物。就像电子钟一样,人们用电子钟不仅仅只是看时间了,人们还需要看温度了。越来越多的新功能更贴近人们的生活了,所以也越来越受人们所喜欢。带有温度的的电子钟可以使人们随时都可以了解温度的变化。本文介绍了设计的框架结构和组成模块以及各模块的原理,介绍了各部分硬件设计和各部分软件设计以及软件流程图。该设计是以 AT89C51 单片机为
3、控制核心的集多种功能于一体的数字钟。该数字钟实现了具有时间显示功能;具有温度显示功能。硬件设计分为单片机控制模块、按键模块、温度模块、时钟模块、显示模块等几个部分。功能描述与总体方案2.1 功能描述根据主要功能要求,该设计利用 51 单片机实现了电子时钟、温度的显示以及设置闹铃等功能。具体可分为一下几种:(1)显示当前的时间,24 时制的时、分、秒;(2)可调节时间;- 2 -(3)显示当前屋内温度;2.2 系统组成用主芯片为 AT89C51 的单片机控制实现,为了满足单片机系统的实时控制的需求,采用实时钟芯片 DS1302,使用按键进行时间的调整和定时,温度传感器使用DS18B20。显示时间
4、和温度使用 LCD1602 显示。主程序如图 2.1,一给单片机上电,单片机就初始化。单片机接收并处理来自 DS18B20 传过来的数据在液晶上显示当时的室内温度,液晶还显示当前的时间,日期。当需要设置闹钟或调整时间时,又检测按键是否按下,以便对时间进行修正、设置闹钟时间,最后进入循环。AT89C51单 片 机DS18B20按 键时 钟 芯 片DS1302LCD1602显 示图 2.1 主程序框图硬件设计- 3 -3.1 时钟电路系统的时钟电路设计是采用的内部方式,即利用芯片内部的振荡电路。51 单片机内部有一个用于构成振荡器的高增益反相放大器。引脚 XTAL1 和 XTAL2 分别是此放大器
5、的输入端和输出端。这个放大器与作为反馈元件的片外晶体谐振器一起构成一个自激振荡器。外接晶体谐振器以及电容 C1 和 C2 构成并联谐振电路,接在放大器的反馈回路中。图 3.1 时钟电路图3.2 复位电路复位是由外部的复位电路来实现的。片内复位电路是复位引脚 RST 通常采用上电自动复位和按键手动复位两种方式,此电路系统采用的是按键手动复位电路,高电平时复位,如图 3.2 所示。- 4 -图 3.2 复位电路图3.3 DS1302 时钟电路DS1302 内含一个实时时钟 /日历和 31 字节静态 RAM,可以通过串行接口与单片机进行通信。实时时钟/日历电路提供秒、分、时、日、星期、月、年的信息,
6、每个月的天数和闰年的天数可自动调整,时钟操作可通过 AM/PM 标志位决定采用 24或 12 小时时间格式。DS1302 与单片机之间能简单地采用同步串行的方式进行通信,仅需三根 I/O 线:复位( RST) 、I/O 数据线、串行时钟( SCLK) 。DS1302 时钟电路如图 3.3 所示。图 3.3 DS1302 时钟电路3.4 DS18B20 温度计电路DS18B20 温度传感器的内部存储器包括一个高速暂存 RAM 和一个非易失性的- 5 -可电擦除的 E2PPRAM,后者存放高温度和低温度触发器 TH、T 和结构寄存器。暂存存储器包含了 8 个连续字节,前两个字节是测得的温度信息,第
7、一个字节的内容是温度的低八位,第二个字节是温度的高八位。第三个和第四个字节是 TH、TL 的易失性拷贝,第五个字节是结构寄存器的易失性拷贝,这三个字节的内容在每一次上电复位时被刷新。第六、七、八个字节用于内部计算.DS18B20 它具有 3 引脚TO92 小体积封装形式,温度测量范围为55125,可编程为 9 位12位 A/D 转换精度,测温分辨率可达 0.0625,被测温度用符号扩展的 16 位数字量方式串行输出,其工作电源既可在远端引入,也可采用寄生电源方式产生,多个DS18B20 可以并联到 3 根或 2 根线上,CPU 只需一根端口线就能与多个 DS18B20通信,占用微处理器的端口较
8、少,可节省大量的引线和逻辑电路。以上特点使DS18B20 非常适用于远距离多点温度检测系统。电路图如图 3.4 所示。图 3.4 DS18B20 温度计电路3.5 按键电路独立按键用来用作调节时钟以及闹铃。按键均采用低电平有效连接方式。几个按键可以对时钟进行设置调节,并调节设置闹铃,当时间与设置的时间一致是闹铃- 6 -报警,即蜂鸣器响。键盘接口是单片机应用系统中最常用的接口之一,键盘的类型很多,常用的有独立式键盘和矩阵式键盘,因为本设计需要的键盘比较少,所以采用独立式的应用中,需要解决键盘消抖的问题,一般使用的是软件消抖的方法。图 3.5 按键电路图3.6 显示电路显示器是单片机常用的功能单
9、元之一,显示器的主要功能是为单片机系统使用者提供必要的单片机工作信息,或者提供工作状态的提示信息,显示器的工作是由单片机通过显示接口驱动的。本设计采用的是 LCD1602 显示电路图如图 3.6 所示。1602 液晶显示器以其微功耗、体积小、显示内容丰富、超薄轻巧的诸多优点,在袖珍式仪表和低功耗应用系统中得到越来越广泛的应用。1602 采用标准的 16 脚接口,其中 VSS 为地电源,VDD 接 5V 正电源,V0 为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影” ,可通过一10K 的电位器调整对比度。 RS 为寄存器选择,高电平时选择数据寄存器
10、、低电平时选择指令寄存器。RW 为读写信号线,高电平时进行读操作,低电平时进行写操作。当 RS 和 RW 共同为低电平时可以写入指令或者显示地址,当 RS 为低电平 RW为高电平时可以读忙信号,当 RS 为高电平 RW 为低电平时可以写入数据。E 端为使- 7 -能端,当 E 端由高电平跳变成低电平时,液晶模块执行命令。液晶显示部分,我们选用 LCD1602C,其接法和普通的 1602 接法一样。 1 脚接地,2 脚接电源,3 脚接一个电位器以调节液晶显示器的亮度,16 脚接地, 15 脚接背光电源。在调试的时候,有时液晶不亮,多半是因为遗漏背光电源,也有可能是虚焊导致。图 3.6 显示电路3
11、.7 闹铃模块电路闹铃模块主要就是一个蜂鸣器,其作用是当到达设定的时间到时发出蜂鸣声报警。用一个 PNP 型三极管和蜂鸣器连接主要是给蜂鸣器一个驱动,让蜂鸣器为高电平有效,即 P07 口高电平时蜂鸣器发声报警。- 8 -图 3.7 闹铃模块电路软件设计4.1 主函数流程初 始 化 LCD1602、 DS1302、DS18B20、 定 时 器键 盘 扫 描开 始结 束读 DS18B20的 温 度 值 和DS1302寄 存 器 的 值将 读 出 的 值 显 示 到LCD1602上图 4.1 主函数流程图- 9 -4.2 18B20 温度计流程开 始初 始 化 DS18B20跳 过 读 序 列 号启
12、 动 温 度 转 换延 时初 始 化 DS18B20跳 过 读 序 列 号读 取 温 度 值结 束图 4.2 18B20 温度计流程- 10 -4.3 按键电路流程图 开始键盘扫描加健 功能健 减健相应的按键操作结束图 4.3 按键电路流程图 结语本次实训在老师的指导和同学的帮助下顺利完成。本次设计的是一个带温度显示的电子时钟。在本次试验中,感觉到自己单片机知识非常欠缺,编程方面很多知识不懂,在同学的帮助下,并借鉴了其他同学的部分程序,经过调试后在- 11 -单片机上显示出最终结果,一个小型的带温度显示的万年历就做出来了。通过本次设计,了解了时钟芯片、温度传感器的一些基本原理及用途,并学习了单
13、片机中一些基本指令的运用,明白了写程序的困难及软件思维和逻辑思维能力的重要性,提高了自己思考问题的严谨性,并且体会到了团队合作的重要性,增强了解决困难的能力。在此感谢老师在本次课程设计中的指导,使得本次设计顺利的完成。参考文献1 万光毅. 严义. 单片机实验与实践教程(一) M, 北京航空航天大学出版社;2 夏继强 . 沈德金. 单片机实验与实践教程(二)M ,北京航空航天大学出版社;3 李广弟 . 朱月秀. 王秀山. 单片机基础(修订本)M,北京航空航天大学出版社;4 徐爱钧. 彭秀华. 单片机高级语言 C51 应用程序设计M,2000 年版;5 马家辰 . MCS-51 单片机原理及其接口
14、技术M,哈尔滨工业大学出版社,1997 年版;6 瓮嘉民. 单片机应用开发技术基于 PROTEUS 仿真和 C 语言编程M,中国电力出版社,2009 年版;7李强. 51 系列单片机应用软件编程技术M,北京航空航天大学出版社,2009 年版。附录- 12 -#include#include“DS18B20_3.H“#define uint unsigned int#define uchar unsigned charuchar a,miao,shi,fen,ri,yue,nian,week,flag,key1n,temp;/flag 用于读取头文件中的温度值,和显示温度值#define yh
15、0x80 /LCD 第一行的初始位置, 因为 LCD1602 字符地址首位 D7 恒定为1(100000000=80)#define er 0x80+0x40 /LCD 第二行初始位置(因为第二行第一个字符位置地址是 0x40)/液晶屏的与 C51 之间的引脚连接定义(显示数据线接 C51 的 P0 口)sbit rs=P20;sbit en=P22;sbit rw=P21; /如果硬件上 rw 接地,就不用写这句和后面的 rw=0 了sbit led=P26; /LCD 背光开关/DS1302 时钟芯片与 C51 之间的引脚连接定义sbit IO=P11;sbit SCLK=P10;sbit
16、 RST=P12;- 13 -sbit ACC0=ACC0;sbit ACC7=ACC7;/*ACC 累加器=AACC.0=E0H ACC.0 就是 ACC 的第 0 位。Acc 可以位寻址。*/校时按键与 C51 的引脚连接定义sbit key1=P15; /设置键sbit key2=P16; /加键sbit key3=P17; /减键sbit buzzer=P13;/蜂鸣器,通过三极管 9012 驱动,端口低电平响/*/uchar code tab1=“20 - - “; /年显示的固定字符uchar code tab2=“ : : “;/时间显示的固定字符- 14 -/延时函数,后面经常
17、调用void delay(uint xms)/延时函数,有参函数uint x,y;for(x=xms;x0;x-)for(y=110;y0;y-);/*液晶写入指令函数与写入数据函数,以后可调用*/*在这个程序中,液晶写入有关函数会在 DS1302 的函数中调用,所以液晶程序要放在前面 */write_1602com(uchar com)/*液晶写入指令函数*rs=0;/数据/指令选择置为指令rw=0; /读写选择置为写P0=com;/送入数据delay(1);en=1;/拉高使能端,为制造有效的下降沿做准备delay(1);en=0;/en 由高变低,产生下降沿,液晶执行命令- 15 -wr
18、ite_1602dat(uchar dat)/*液晶写入数据函数*rs=1;/数据/指令选择置为数据rw=0; /读写选择置为写P0=dat;/送入数据delay(1);en=1; /en 置高电平,为制造下降沿做准备delay(1);en=0; /en 由高变低,产生下降沿,液晶执行命令lcd_init()/*液晶初始化函数 *write_1602com(0x38);/设置液晶工作模式,意思:16*2 行显示,5*7 点阵,8 位数据write_1602com(0x0c);/开显示不显示光标write_1602com(0x06);/整屏不移动,光标自动右移write_1602com(0x01
19、);/清显示write_1602com(yh+1);/日历显示固定符号从第一行第 1 个位置之后开始显示- 16 -for(a=0;a0;a-)- 17 -IO=ACC0;SCLK=0;SCLK=1;ACC=ACC1;uchar read_byte()/读一个字节RST=1;for(a=8;a0;a-)ACC7=IO;SCLK=1;SCLK=0;ACC=ACC1;return (ACC);/-void write_1302(uchar add,uchar dat)/向 1302 芯片写函数,指定写入地址,数据- 18 -RST=0;SCLK=0;RST=1;write_byte(add);wr
20、ite_byte(dat);SCLK=1;RST=0;uchar read_1302(uchar add)/从 1302 读数据函数,指定读取数据来源地址uchar temp;RST=0;SCLK=0;RST=1;write_byte(add);temp=read_byte();SCLK=1;RST=0;return(temp);- 19 -uchar BCD_Decimal(uchar bcd)/BCD 码转十进制函数,输入 BCD,返回十进制uchar Decimal;Decimal=bcd4;return(Decimal=Decimal*10+(bcd/-void ds1302_init
21、() /1302 芯片初始化子函数 (2010-01-07,12:00:00,week4)RST=0;SCLK=0;write_1302(0x8e,0x00); /允许写,禁止写保护 /write_1302(0x80,0x00); /向 DS1302 内写秒寄存器 80H 写入初始秒数据 00/write_1302(0x82,0x00);/向 DS1302 内写分寄存器 82H 写入初始分数据 00/write_1302(0x84,0x12);/向 DS1302 内写小时寄存器 84H 写入初始小时数据 12/write_1302(0x8a,0x04);/向 DS1302 内写周寄存器 8aH
22、 写入初始周数据 4/write_1302(0x86,0x07);/向 DS1302 内写日期寄存器 86H 写入初始日期数据 07/write_1302(0x88,0x01);/向 DS1302 内写月份寄存器 88H 写入初始月份数据 01/write_1302(0x8c,0x10);/向 DS1302 内写年份寄存器 8cH 写入初始年份数据 10write_1302(0x8e,0x80); /打开写保护- 20 -/-/温度显示子函数void write_temp(uchar add,uchar dat)/向 LCD 写温度数据,并指定显示位置uchar gw,sw;gw=dat%10
23、;/取得个位数字sw=dat/10;/取得十位数字write_1602com(er+add);/er 是头文件规定的值 0x80+0x40write_1602dat(0x30+sw);/数字+30 得到该数字的 LCD1602 显示码write_1602dat(0x30+gw);/数字+30 得到该数字的 LCD1602 显示码write_1602dat(0xdf);/显示温度的小圆圈符号,0xdf 是液晶屏字符库的该符号地址码write_1602dat(0x43); /显示“C“符号,0x43 是液晶屏字符库里大写 C 的地址码/-/时分秒显示子函数void write_sfm(uchar
24、add,uchar dat)/向 LCD 写时分秒,有显示位置加、现示数据,两个参数uchar gw,sw;gw=dat%10;/取得个位数字sw=dat/10;/取得十位数字write_1602com(er+add);/er 是头文件规定的值 0x80+0x40- 21 -write_1602dat(0x30+sw);/数字+30 得到该数字的 LCD1602 显示码write_1602dat(0x30+gw);/数字+30 得到该数字的 LCD1602 显示码/-/年月日显示子函数void write_nyr(uchar add,uchar dat)/向 LCD 写年月日,有显示位置加数、
25、显示数据,两个参数uchar gw,sw;gw=dat%10;/取得个位数字sw=dat/10;/取得十位数字write_1602com(yh+add);/设定显示位置为第一个位置 +addwrite_1602dat(0x30+sw);/数字+30 得到该数字的 LCD1602 显示码write_1602dat(0x30+gw);/数字+30 得到该数字的 LCD1602 显示码/-void write_week(uchar week)/写星期函数- 22 -write_1602com(yh+0x0c);/星期字符的显示位置switch(week)case 1:write_1602dat(M)
26、;/星期数为 1 时,显示write_1602dat(O);write_1602dat(N);break;case 2:write_1602dat(T);/星期数据为 2 时显示write_1602dat(U);write_1602dat(E);break;case 3:write_1602dat(W);/星期数据为 3 时显示write_1602dat(E);write_1602dat(D);break;case 4:write_1602dat(T);/星期数据为 4 是显示write_1602dat(H);write_1602dat(U);- 23 -break;case 5:write_
27、1602dat(F);/星期数据为 5 时显示write_1602dat(R);write_1602dat(I);break;case 6:write_1602dat(S);/星期数据为 6 时显示write_1602dat(T);write_1602dat(A);break;case 7:write_1602dat(S);/星期数据为 7 时显示write_1602dat(U);write_1602dat(N);break;/*键盘扫描有关函数*void keyscan()- 24 -if(key1=0)/-key1 为功能键(设置键)-delay(9);/延时,用于消抖动if(key1=0
28、)/延时后再次确认按键按下buzzer=0;/蜂鸣器短响一次delay(20);buzzer=1;while(!key1);key1n+;if(key1n=9)key1n=1;/设置按键共有秒、分、时、星期、日、月、年、返回,8 个功能循环switch(key1n)case 1: TR0=0;/关闭定时器/TR1=0;write_1602com(er+0x09);/设置按键按动一次,秒位置显示光标write_1602com(0x0f);/设置光标为闪烁temp=(miao)/10*16+(miao)%10;/秒数据写入 DS1302write_1302(0x8e,0x00);write_130
29、2(0x80,0x80|temp);/miao- 25 -write_1302(0x8e,0x80);break;case 2: write_1602com(er+6);/按 2 次 fen 位置显示光标/write_1602com(0x0f);break;case 3: write_1602com(er+3);/按动 3 次,shi/write_1602com(0x0f);break;case 4: write_1602com(yh+0x0e);/按动 4 次,week/write_1602com(0x0f);break;case 5: write_1602com(yh+0x0a);/按动
30、5 次,ri/write_1602com(0x0f);break;case 6: write_1602com(yh+0x07);/按动 6 次,yue/write_1602com(0x0f);break;case 7: write_1602com(yh+0x04);/按动 7 次,nian/write_1602com(0x0f);break;case 8:- 26 -write_1602com(0x0c);/按动到第 8 次,设置光标不闪烁TR0=1;/打开定时器temp=(miao)/10*16+(miao)%10;write_1302(0x8e,0x00);write_1302(0x80,
31、0x00|temp);/miao 数据写入 DS1302write_1302(0x8e,0x80);break;/-加键 key2-if(key1n!=0)/当 key1 按下以下。再按以下键才有效(按键次数不等于零)if(key2=0) /上调键delay(10);if(key2=0)buzzer=0;/蜂鸣器短响一次delay(20);- 27 -buzzer=1;while(!key2);switch(key1n)case 1:miao+;/设置键按动 1 次,调秒if(miao=60)miao=0;/秒超过 59,再加 1,就归零write_sfm(0x08,miao);/令 LCD
32、在正确位置显示“加“ 设定好的秒数temp=(miao)/10*16+(miao)%10;/十进制转换成 DS1302 要求的 DCB 码write_1302(0x8e,0x00); /允许写,禁止写保护 write_1302(0x80,temp); /向 DS1302 内写秒寄存器 80H 写入调整后的秒数据 BCD码write_1302(0x8e,0x80); /打开写保护write_1602com(er+0x09);/write_1602com(0x0b);break;case 2:fen+;if(fen=60)fen=0;write_sfm(0x05,fen);/令 LCD 在正确位置
33、显示“加“ 设定好的分数据temp=(fen)/10*16+(fen)%10;/十进制转换成 DS1302 要求的 DCB 码write_1302(0x8e,0x00);/允许写,禁止写保护 - 28 -write_1302(0x82,temp);/向 DS1302 内写分寄存器 82H 写入调整后的分数据 BCD码write_1302(0x8e,0x80);/打开写保护write_1602com(er+6);/break;case 3:shi+;if(shi=24)shi=0;write_sfm(2,shi);/令 LCD 在正确的位置显示 “加“设定好的小时数据temp=(shi)/10*
34、16+(shi)%10;/十进制转换成 DS1302 要求的 DCB 码write_1302(0x8e,0x00);/允许写,禁止写保护 write_1302(0x84,temp);/向 DS1302 内写小时寄存器 84H 写入调整后的小时数据BCD 码write_1302(0x8e,0x80);/打开写保护write_1602com(er+3);/break;case 4:week+;if(week=8)week=1;write_1602com(yh+0x0C);/指定加 后的周数据显示位置write_week(week);/指定周数据显示内容temp=(week)/10*16+(week)%10;/十进制转换成 DS1302 要求的 DCB 码