实时日历时钟温度方案与实现.docx
《实时日历时钟温度方案与实现.docx》由会员分享,可在线阅读,更多相关《实时日历时钟温度方案与实现.docx(40页珍藏版)》请在冰豆网上搜索。
实时日历时钟温度方案与实现
单片机原理及应用课程设计
1.课程设计题目与要求
1.1课程设计内容
利用STC89C52RC单片机设计实现实时日历/时间/温度在LCD1602上的显示
1.2主要设备与器材
PC机一台,HOT51增强型单片机开发板,STC89C52RC单片机一块,LCD1602液晶屏,DS1302时钟芯片,DS18B20温度传感器等,其它器材任选。
1.3设计要求
<1)在LCD1602上显示年月日,星期,时分秒,温度,通过3个独立按键修改时间。
<2)显示格式:
LCD第一行:
年-月-日星期
LCD第二行:
时-分-秒温度
1.4设计人员分工
伍国豪:
整体电路设计,焊接电路
刘青梅、何盈财:
软件设计
2.课设所需软件简介
2.1KeiluVision4的简要介绍
2009年2月发布KeilμVision4,KeilμVision4引入灵活的窗口管理系统,使开发人员能够使用多台监视器,并提供了视觉上的表面对窗口位置的完全控制的任何地方。
新的用户界面可以更好地利用屏幕空间和更有效地组织多个窗口,提供一个整洁,高效的环境来开发应用程序。
新版本支持更多最新的ARM芯片,还添加了一些其他新功能。
1.系统概述
KeilC51软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面。
另外重要的一点,只要看一下编译后生成的汇编代码,就能体会到KeilC51生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。
在开发大型软件时更能体现高级语言的优势。
下面详细介绍KeilC51开发系统各部分功能和使用。
2.KeilC51单片机软件开发系统的整体结构
C51工具包的整体结构,uVision与Ishell分别是C51forWindows和forDos的集成开发环境(IDE>,可以完成编辑、编译、连接、调试、仿真等整个开发流程。
开发人员可用IDE本身或其它编辑器编辑C或汇编源文件。
然后分别由C51及C51编译器编译生成目标文件(.OBJ>。
目标文件可由LIB51创建生成库文件,也可以与库文件一起经L51连接定位生成绝对目标文件(.ABS>。
ABS文件由OH51转换成标准的Hex文件,以供调试器dScope51或tScope51使用进行源代码级调试,也可由仿真器使用直接对目标板进行调试,也可以直接写入程序存贮器如EPROM中。
使用独立的Keil仿真器时,注意事项:
*仿真器标配11.0592MHz的晶振,但用户可以在仿真器上的晶振插孔中换插其他频率的晶振。
*仿真器上的复位按钮只复位仿真芯片,不复位目标系统。
*仿真芯片的31脚
优点:
1.KeilC51生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。
在开发大型软件时更能体现高级语言的优势。
2.与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。
用过汇编语言后再使用C来开发,体会更加深刻。
KeilC51软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面。
如图2.1所示:
图2.1KEIL操作界面
2.2STC-ISP的简要介绍
STC-ISP是一款下载编程烧录,是针对系列单片机而设计的,可下载STC89系列、12C2052系列和12C5410等系列的STC单片机,使用简便,现已被广泛使用。
操作说明如下:
(1>打开STC-ISP,如下图界面,在Type栏目下选中单片机,如STC90C516RC。
如图2.2所示:
图2.2ISP操作界面
(2>查看设备管理器中的,波特率一般保持默认,如果遇到下载问题,可以适当下调一些。
(3>先确认硬件连接正确,点击“打开文件”并在对话框内找到您要下载的文件。
(4>选择所要下载的文件,这样可以使您在每次编译时HEX代码能自动加载到STC-ISP,点击“Download/下载”。
(5>手动按下电源开关便即可把HEX写入到单片机内,如图1.2是写入程序截图。
(6>程序写入完毕,目标板开始运行程序结果。
3.方案分析与确定
3.1方案思路分析
由题目要求,根据设置的年月日的显示全年的年月公历、星期等信息。
由于需要显示去年的日期以及星期等信息,普通的LED数码管显然已经不能胜任,为此,我们可以选择LCD1602液晶显示器完成课设要求。
目前所具备的设备只有一块STC89C52RC的单片机,PC机。
课设要求显示日期、温度等信息,因此,我们需要一块DS1302时钟芯片和一个DS18B20温度传感器,该时钟芯片可以产生年份,月份,日期,星期,时,分,秒的数据,温度传感器可以实时采集当前环境的温度,完全可以完成课程设计的各项要求。
基于以上分析,我们可以利用DS1302产生的各种时钟数据,DS18B20采集当前环境温度,由单片机完成对数据的读取,然后通过单片机将数据写至LCD1602,以显示数据,达到可视化的效果。
如图3.1所示:
图3.1整体设计框架图
3.2方案流程图
根据以上分析,以及使用各种芯片的操作流程,我们可以大致确定课程设计的软件设计方案方案,其大致流程如图3.2所示:
图3.2设计流程图
4.单元芯片电路的设置及总体设计
4.1DS1302芯片引脚功能
DS1302是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。
采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。
DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。
DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后备电源双电源引脚,同时提供了对后备电源进行涓细电流充电的能力。
DS1302的引脚排列,其中Vcc1为后备电源,VCC2为主电源。
在主电源关闭的情况下,也能保持时钟的连续运行。
DS1302由Vcc1或Vcc2两者中的较大者供电。
当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。
当Vcc2小于Vcc1时,DS1302由Vcc1供电。
X1和X2是振荡源,外接32.768kHz晶振。
RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。
RST输入有两种功能:
首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。
当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。
如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。
上电运行时,在Vcc>2.0V之前,RST必须保持低电平。
只有在SCLK为低电平时,才能将RST置为高电平。
I/O为串行数据输入输出端(双向>,后面有详细说明。
SCLK为时钟输入端。
如图4.1所示:
图4.1DS1302引脚定义图
引脚描述:
X1X232.768KHz晶振管脚
GND接地
RST复位脚
I/O数据输入/输出引脚
SCLK串行时钟
Vcc1,Vcc2电源供电管脚4.2DS1302的使用方法
使用DS1302时,要对其引脚和寄存器进行特殊设置,以实现所需功能。
引脚设置后面会提及,这里不做说明,主要讲一下程序的编写。
DS1302的的工作过程中包过读写一个字节数据等过程,下面做相应的解释。
/********************************
功能:
写一个字节
*********************************/
voidwrite_byte(uchardat>
{
ACC=dat。
RST=1。
for(a=8。
a>0。
a-->
{
IO=ACC0。
SCLK=0。
SCLK=1。
ACC=ACC>>1。
}
}/********************************
功能:
读一个字节
*********************************/
ucharread_byte(>
{
RST=1。
for(a=8。
a>0。
a-->
{
ACC7=IO。
SCLK=1。
SCLK=0。
ACC=ACC>>1。
}
return(ACC>。
}
/*************************************************
功能:
向1302芯片写函数,指定写入地址,数据**************************************************/
voidwrite_1302(ucharadd,uchardat>
{
RST=0。
SCLK=0。
RST=1。
write_byte(add>。
write_byte(dat>。
SCLK=1。
RST=0。
}
/**************************************************
功能:
从1302读数据函数,指定读取数据来源地址
***************************************************/
ucharread_1302(ucharadd>//
{
uchartemp。
RST=0。
SCLK=0。
RST=1。
write_byte(add>。
temp=read_byte(>。
SCLK=1。
RST=0。
return(temp>。
}
/*******************************
功能:
1302芯片初始化子函数
********************************/
voidds1302_init(>//1302芯片初始化子函数(2018-01-07,12:
00:
00,week4>
{
RST=0。
SCLK=0。
write_1302(0x8e,0x00>。
//允许写,禁止写保护
write_1302(0x8e,0x80>。
//打开写保护
}
4.3DS18B20芯片引脚功能
DS18B20是DALLAS公司生产的单总线式数字温度传感器,它具有微型化、低功耗、高性能、搞干扰能力强、易配处理器等优点,特别适用于构成多点温度测控系统,可直接将温度转化成串行数字信号<提供9位二进制数字)给单片机处理,且在同一总线上可以挂接多个传感器芯片。
它具有3引脚TO-92小体积封装形式,温度测量范围为-55℃~+125℃,可编程为9位~12位A/D转换精度,测温分辨率可达0.0625℃,被测温度用符号扩展的16位数字量方式串行输出,其工作电源既可在远端引入,也可采用寄生电源方式产生,多个DS18B20可以并联到3根或2根线上,CPU只需一根端口线就能与多个DS18B20通信,占用微处理器的端口较少,可节省大量的引线和逻辑电路。
以上特点使DS18B20非常适用于远距离多点温度检测系统。
引脚定义图如图4.2所示:
图4.2DS18B20引脚定义图
在TO-92和SO-8的封装中引脚有所不同,具体差别请查阅PDF手册,在TO-92封装中引脚分配如下:
1地
2单线运用的数据输入输出引脚
3可选的电源引脚
DS18B20工作过程一般遵循以下协议:
初始化——ROM操作命令——存储器操作命令——处理数据
这个命令读取暂存器的内容。
读取将从字节0开始,一直进行下去,直到第9<字节8,CRC)字节读完。
如果不想读完所有字节,控制器可以在任何时间发出复位命令来中止读取。
4.4DS18B20的使用方法
使用DS1302时,要对其引脚和寄存器进行特殊设置,以实现所需功能。
引脚设置后面会提及,这里不做说明,主要讲一下程序的编写。
DS18B2的工作过程中包过读写一个字节数据等过程,下面做相应的解释。
/*****************************
函数功能:
DS18B20初始化子程序
******************************/
unsignedcharInit_DS18B20(void>
{
unsignedcharx=0。
DQ=0。
//发送复位脉冲
DS18_delay(29>。
//延时<>480ms>
DQ=1。
//拉高数据线
DS18_delay(3>。
//等待<15~60ms>等待存在脉冲
x=DQ。
//获得存在信号(用于判断是否有器件>
DS18_delay(25>。
//等待时间隙结束
return(x>。
//返回存在信号,0=器件存在,1=无器件
}
/*******************************
函数功能:
向DS18B20读一字节数据
********************************/
ReadOneChar(void>
{
unsignedchari=0。
unsignedchardat=0。
for(i=8。
i>0。
i-->
{
DQ=1。
DS18_delay(1>。
DQ=0。
dat>>=1。
//等效dat=dat>>1(dat=dat右移一位后的值>
DQ=1。
if(DQ>
dat|=0x80。
DS18_delay(4>。
}
return(dat>。
}
/*******************************
函数功能:
向DS18B20写一字节数据
********************************/
WriteOneChar(unsignedchardat>
{
unsignedchari=0。
for(i=8。
i>0。
i-->
{
DQ=0。
DQ=dat&0x01。
DS18_delay(5>。
DQ=1。
dat>>=1。
//复合赋值运算,等效dat=dat>>1(dat=dat右移一位后的值>
}
DS18_delay(4>。
}
/**************************
函数功能:
向DS18B20读温度值
***************************/
unsignedintReadTemperature(void>
{
Init_DS18B20(>。
WriteOneChar(0xcc>。
WriteOneChar(0x44>。
DS18_delay(125>。
Init_DS18B20(>。
WriteOneChar(0xcc>。
WriteOneChar(0xbe>。
tempL=ReadOneChar(>。
tempH=ReadOneChar(>。
}
4.5LCD1602引脚功能
1602液晶也叫1602字符型液晶它是一种专门用来显示字母、数字、符号等的型液晶模块它有若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符。
每位之间有一个点距的间隔每行之间也有间隔起到了字符间距和行间距的作用,正因为如此所以他不能显示图形
n1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块<显示字符和数字)。
引脚图如图4.3所示:
图4.3LCD1602引脚图
1602采用标准的16脚接口,其中:
第1脚:
VSS为电源地
第2脚:
VDD接5V电源正极
第3脚:
V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高<对比度过高时会产生“鬼影”,可以通过串联一个电阻来调整亮度)。
第4脚:
RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:
RW为读写信号线,高电平时进行读操作,低电平时进行写操作。
第6脚:
E(或EN>端为使能(enable>端。
第7~14脚:
D0~D7为8位双向数据端。
第15~16脚:
空·116脚背光负极。
4.6LCD1602的使用
write_1602com(ucharcom>//****液晶写入指令函数****
{
rs=0。
rw=0。
P0=com。
delay(1>。
en=1。
delay(1>。
en=0。
}
write_1602dat(uchardat>//***液晶写入数据函数****
{
rs=1。
rw=0。
P0=dat。
delay(1>。
en=1。
delay(1>。
en=0。
}
lcd_init(>//***液晶初始化函数****
{
write_1602com(0x38>。
write_1602com(0x0c>。
write_1602com(0x06>。
write_1602com(0x01>。
write_1602com(yh+1>。
/
for(a=0。
a<14。
a++>
{
write_1602dat(tab1[a]>。
}
write_1602com(er+2>。
for(a=0。
a<8。
a++>
{
write_1602dat(tab2[a]>。
}
}
5.整体电路设计和程序源代码
由上面的分析可以得到实验的电路图如图5.1所示:
图5.1系统原理图
设计源代码如下:
/*************************************************
程序名称:
LCD1602.C
*************************************************/
#include
#include"DS18B20.H"
#defineuintunsignedint
#defineucharunsignedchar
uchara,miao,shi,fen,ri,yue,nian,week,flag,key1n,temp。
//flag用于读取头文件中的温度值,和显示温度值
#defineyh0x80//LCD第一行的初始位置,因为LCD1602字符地址首位D7恒定为1<100000000=80)
#defineer0x80+0x40//LCD第二行初始位置
sbitrs=P2^5。
sbitrw=P2^6。
sbiten=P2^7。
sbitSCLK=P1^6。
/*实时时钟时钟线引脚*/
sbitIO=P3^5。
/*实时时钟数据线引脚*/
sbitRST=P1^7。
/*实时时钟复位线引脚*/
sbitACC0=ACC^0。
sbitACC7=ACC^7。
//校时按键与C51的引脚连接定义
sbitkey1=P3^2。
//设置键
sbitkey2=P3^3。
//加键
sbitkey3=P3^4。
//减键
ucharcodetab1[]={"20--"}。
//年显示的固定字符
ucharcodetab2[]={":
:
"}。
//时间显示的固定字符
//延时函数,后面经常调用
voiddelay(uintxms>//延时函数,有参函数
{
uintx,y。
for(x=xms。
x>0。
x-->
for(y=110。
y>0。
y-->。
}
write_1602com(ucharcom>//****液晶写入指令函数****
{
rs=0。
//数据/指令选择置为指令
rw=0。
//读写选择置为写
P0=com。
//送入数据
delay(1>。
en=1。
//拉高使能端,为制造有效的下降沿做准备
delay(1>。
en=0。
//en由高变低,产生下降沿,液晶执行命令
}
write_1602dat(uchardat>//***液晶写入数据函数****
{
rs=1。
//数据/指令选择置为数据
rw=0。
//读写选择置为写
P0=dat。
//送入数据
delay(1>。
en=1。
//en置高电平,为制造下降沿做准备
delay(1>。
en=0。
//en由高变低,产生下降沿,液晶执行命令
}
lcd_init(>//***液晶初始化函数****
{
write_1602com(0x38>。
//设置液晶工作模式
write_1602com(0x0c>。
//开显示不显示光标
write_1602com(0x06>。
//整屏不移动,光标自动右移
write_1602com(0x01>。
//清显示
write_1602com(yh+1>。
//日历显示
for(a=0。
a<14。
a++>
{
write_1602dat(tab1[a]>。
//向液晶屏写日历显示的固定符号部分
}
write_1602com(er+2>。
//时间显示固定符号写入位置
for(a=0。
a<8。
a++>
{
write_1602dat(tab2[a]>。
//写显示时间固定符号,两个冒号
}
}
/***************DS1302有关子函数********************/
voidwrite_byte(uchardat>//写一个字节
{
ACC=dat。
RST=1。
for(a=8。
a>0。
a-->
{
IO=ACC0。
SCLK=0。
SCLK=1。
ACC=ACC>>1。
}
}
ucharread_byte(>//读一个字节
{
RST=1。
for(a=8。
a>0。
a-->
{
ACC7=IO。
SCLK=1。
SCLK=0。
ACC=ACC>>1。
}
return(ACC>。
}
voidwrite_1302(ucharadd,uchardat>//向1302芯片写函数,指定写入地址
{
RST=0。
SCLK=0。
RST=1。
write_byte(add>。
write_byte(dat>。
SCLK=1。
RST=0。
}
ucharread_1302(ucharadd>//从1302读数据函数,指定读取数据来源地址
{
uchartemp。
RST=0。
SCLK=0。
RST=1。
write_byte(add>。
temp=read_byte(>。
SCLK=1。
RST=0。
return(temp>。
}
ucharBCD_Decimal(ucharbcd>//BCD码转十进制函数