电子万年历设计与调试设计说明书 精品Word下载.docx
《电子万年历设计与调试设计说明书 精品Word下载.docx》由会员分享,可在线阅读,更多相关《电子万年历设计与调试设计说明书 精品Word下载.docx(35页珍藏版)》请在冰点文库上搜索。
DS12C887对于少于31天的月份,其日期能够在月末自动调整,带有闰年的月份可以自动补偿。
该器件可配置为24小时或12小时格式。
精确的温度补偿电路用于监视的VCC状态。
一旦检测到主电源失效,器件可自动切换到备用电源。
支持Intel和Motorola模式。
主要特点是:
∙
RTC计算秒、分、时、星期、日、月、年信息,具有润年补偿,有效期至2099年;
∙用二进制或BCD表示时间;
∙具有AM、PM标示的12小时模式或24小时模式;
∙可选择Intel或Motorola总线时序;
∙内部包含128字节存储单元,其中114字节供用户自由使用;
∙三路中断可分别通过软件屏蔽与检测;
∙闹钟可设置为每秒一次至每星期一次;
∙可编程的方波输出信号;
∙自动电源失效检测和切换电路。
方案2DS1302是一种可编程的串行实时时钟芯片,内部具有实时时钟、日历和用户可用RAM,可计算2100年之前的秒、分、时、日、月、周、年,且对月末日期、闰年天数可自动调整,RAM容量为31×
8bit,以SPI串行总线方式向单片机传送单字节或多字节的实时时间数据,当主电源断电时备用电源可继续保持时钟连续运行。
第2章仿真电路设计
2.1控制系统框图
根据控制系统要求设计的电子万年历控制系统由单片机STC89S52RC构成的最小系统,由独立按键构成的按键扫描电路、由LCD1602构成的显示电路,由DS1302构成的时间控制电路以及由DS18B20构成的温度采集电路等,控制系统框图如图2-1所示。
图2-1控制系统框图
2.2仿真电路设计
设计的电子万年历仿真图如图2-2所示,其中单片机最小系统由单片机、时钟电路、复位电路和电源组成,按键扫描电路由选择、调整和确定三个独立按键构成,温度采集电路由单总线温度传感器DS18B20和上拉电阻组成,时钟控制电路由时间I²
C总线协议的时钟芯片DS1302和晶振构成,液晶显示电路由LCD1602液晶和排阻以并行连接方式与单片机相连,滑动变阻器用来调节液晶显示亮度。
图2-2电子万年历仿真图
2.3主要元器件清单
电子万年历元器件清单如表2-1所示:
表2-1电子万年历元器件清单
序号
元器件名称
规格型号
数量
标号
备注
1
单片机
STC89S52RC
U1
DIP封装
2
液晶
LM016L
LCD1
并行接口
3
按键
四脚
4
功能控制
晶振
12MHz
X1
时钟电路
5
32768Hz
X2
时钟控制
6
电容
30pF
C1C2
瓷片,时钟电路
10uf
C3
电解,复位电路
7
电阻
10k
R1
复位
4.7k
R2
上拉
8
温度传感器
DS18B20
U2
温度采集
9
时钟控制芯片
DS1302
U3
时间控制
10
排阻
1K
RP1
上拉电阻
第3章软件程序设计
电子万年历程序采用自下而上的模块化编程方式,根据控制任务要求,将程序划分为主程序、液晶显示模块、温度采集模块、时间控制模块和按键扫描模块5个模块,其结构如图3-1所示:
图3-1程序结构图
3.1液晶显示模块
液晶显示模块完成日期、时间和温度显示,主要有初始化函数、写命令函数、写数据函数和液晶显示函数4部分组成。
(1)液晶写命令函数
液晶写命令操作时序图如图3-2所示,由此设计的流程图如图3-3所示:
图3-2液晶写命令操作时序图
(2)液晶写数据函数
液晶写数据操作时序图如图3-4所示,由此设计的流程图如图3-5所示:
图3-4液晶写数据操作时序图
图3-3写命令流程图图3-5写数据流程图
(3)液晶初始化函数
液晶初始化函数流程图如图3-6所示:
:
图3-6
液晶显示函数流程图如图3-7所示:
图3-7
液晶显示模块程序清单如下:
/********头文件及宏定义*******/
#include<
reg52.h>
#defineucharunsignedchar
/********变量声明及定义*******/
sbitRS=P2^2;
sbitRW=P2^3;
sbitE=P2^4;
ucharlcd1[]={"
D:
--W:
"
};
ucharlcd2[]={"
T:
:
T:
/***********延时函数**********/
voiddelay()
{
ucharx;
for(x=100;
x>
0;
x--);
}
/******液晶写命令控制函数*****/
voidlcd_(uchar)
RS=0;
//命令
RW=0;
//写操作
E=1;
//使能有效
P0=;
//送命令
E=0;
//使能无效
delay();
//延时
RW=1;
//复位
RS=1;
/******液晶写数据控制函数*****/
voidlcd_dat(uchardat)
//数据
P0=dat;
//送数据
//延时
/******液晶初始化控制函数*****/
voidlcd_init()
lcd_(0x38);
//模式设置
lcd_(0x0c);
//显示设置
lcd_(0x01);
//清屏
lcd_(0x06);
//输入模式
/*******液晶显示控制函数******/
voiddisp_lcd()
uchari;
lcd_(0x80);
//第一行地址
for(i=0;
i<
16;
i++)
lcd_dat(lcd1[i]);
lcd_(0xc0);
//第二行地址
lcd_dat(lcd2[i]);
3.2温度控制模块
温度控制模块包括DS18B20初始化函数、写字节函数、读字节函数、温度控制函数4个部分。
(1)初始化函数
DS18B20初始化时序图如图3-8所示,流程图如图3-9所示。
图3-8
图3-9初始化流程图
(2)写字节函数
DS18B20写字节函数时序图如图3-10所示,流程图如图3-11所示。
图3-10写字节时序图
图3-11写字节流程图
(2)读字节函数
DS18B20读字节函数时序图如图3-12所示,流程图如图3-13所示。
图3-12写数据时序图
图3-13写数据流程图
(4)温度控制函数
温度控制函数流程图如图3-14所示。
温度控制程序头文件如下:
#ifndef_DS18B20_H_
#define_DS18B20_H_
voidtemperate();
#endif
温度控制程序清单如下:
/******头文件及宏定义******/
reg51.h>
/******变量声明及定义*******/
uchart,value[]={0x00,0x00};
bits;
sbitDQ=P1^7;
externucharlcd2[];
/******延时控制函数*****/
voiddel(uchart)//7us
for(i=t;
i>
i--);
/****18B20初始化控制函数***/
ucharinit_18b20()
ucharstatus;
DQ=1;
DQ=0;
del(100);
//700us
del(5);
//35us
status=DQ;
del(25);
//175us
del(30);
//210us
returnstatus;
/******读18B20控制函数*****/
ucharrd_18b20()
uchari,dat=0;
8;
{
DQ=1;
DQ=0;
dat>
>
=1;
if(DQ==1)
dat|=0x80;
del(5);
}
returndat;
/******写18B20控制函数*****/
voidwr_18b20(uchardat)
del
(1);
//7us
DQ=dat&
0x01;
//35us
/********温度控制函数*******/
voidtemperate()
init_18b20();
wr_18b20(0xcc);
wr_18b20(0x44);
wr_18b20(0xbe);
value[0]=rd_18b20();
value[1]=rd_18b20();
if((value[1]&
0xf8)==0xf8)
{
s=1;
value[0]=~value[0]+1;
if(value[0]==0x00)
value[1]=~value[1]+1;
else
value[1]=~value[1];
}
else
s=0;
t=(value[0]>
4)|(value[1]<
<
4);
if(s==1)
lcd2[13]='
-'
;
lcd2[13]=t/100+'
0'
lcd2[14]=t%100/10+'
lcd2[15]=t%10+'
3.3时间控制模块
时间控制模块包括读字节函数、写字节函数、读数据函数、写数据函数和初始化函数5部分组成。
(1)读字节函数
读字节操作时序图如图3-14所示,读字节函数流程图如图3-15所示:
图3-14读字节操作时序图
图3-15读字节函数流程图
写字节操作时序图如图3-16所示,读字节函数流程图如图3-17所示:
图3-16写字节操作时序图
(3)读数据函数
读数据函数流程图如图3-18所示:
(4)写数据函数
写数据函数流程图如图3-19所示:
图1-7图1-8图1-9
(5)初始化函数
初始化函数流程图如图3-20所示:
时间控制模块头文件如下:
#ifndef_1302_H_
#define_1302_H_
voidset_1302(ucharwei,ucharbeet);
voidtime();
时间控制模块程序清单如下:
#defineuintunsignedint
sbitCLK=P1^0;
sbitSDA=P1^1;
sbitRST=P1^2;
uchar*week[]={"
***"
"
SUN"
MON"
"
TUS"
WEN"
THU"
FRI"
SAT"
uchardatetime[7];
externbitflag;
externucharlcd1[],lcd2[];
/******1302写数据控制函数*****/
voidwr_1302(uchardat)
SDA=dat&
0X01;
CLK=1;
CLK=0;
}
/******1302读数据控制函数*****/
ucharrd_1302()
uchari,b,t;
b>
t=SDA;
b|=t<
7;
returnb/16*10+b%16;
/******读数据控制函数*****/
ucharrd_dat(ucharaddr)
uchardat;
RST=0;
CLK=0;
RST=1;
wr_1302(addr);
dat=rd_1302();
CLK=1;
/******写数据控制函数*****/
voidwr_dat(ucharadd,uchardat)
wr_1302(add);
wr_1302(dat);
/******时间数据写入控制函数*****/
voidset_1302(ucharwei,ucharbeet)
wr_dat(0x8e,0x00);
wr_dat(wei,beet);
wr_dat(0x8e,0x80);
/********时间控制函数*******/
voidtime()
if(flag==0)
for(i=0;
datetime[i]=rd_dat(0x81+2*i);
lcd1[13]=*(week[datetime[5]]);
lcd1[14]=*(week[datetime[5]]+1);
lcd1[15]=*(week[datetime[5]]+2);
lcd1[8]=datetime[3]/10+'
lcd1[9]=datetime[3]%10+'
lcd1[5]=datetime[4]/10+'
lcd1[6]=datetime[4]%10+'
lcd1[2]=datetime[6]/10+'
lcd1[3]=datetime[6]%10+'
lcd2[8]=datetime[0]/10+'
lcd2[9]=datetime[0]%10+'
lcd2[5]=datetime[1]/10+'
lcd2[6]=datetime[1]%10+'
lcd2[2]=datetime[2]/10+'
lcd2[3]=datetime[2]%10+'
}
3.4按键扫描模块
按键扫描模块包含延时消抖函数、按键处理函数、选择按键函数、调节按键函数和确定按键函数5个部分。
(1)按键处理函数
按键处理函数程序流程图如图3-22所示:
图3-22按键处理函数程序流程图
(2)选择按键函数
选择按键函数程序流程图如图3-23所示:
(3)确定按键函数
确定按键函数程序流程图如图3-24所示:
图3-23图3-24
(4)调节按键函数
调节按键函数程序流程图如图3-25所示:
图3-25
按键处理模块头文件如下:
#ifndef_KEY_H_
#define_KEY_H_
voidkey();
按键处理模块程序清单如下:
#include"
1302.h"
uchark,set,shi,fen,miao,day,month,w,year;
bitflag;
externucharlcd1[],lcd2[],*week[];
/***********按键消抖函数**********/
voiddel()
uchari,j;
10;
for(j=0;
j<
250;
j++);
/*********选择按键控制函数********/
voidkey_xuan()
flag=1;
set++;
if(set==7)
set=0;
/*********调节按键控制函数********/
voidkey_tiao()
if(set==0)
year++;
if(year==100)
year=0;
lcd1[2]=year/10+'
lcd1[3]=year%10+'
if(set==1)
month++;
if(month==13)
month=1;
lcd1[5]=month/10+'
lcd1[6]=month%10+'
if(set==2)
day++;
if(((month==0)||(month==2)||(month==4)||(month==6)
||(month==7)||(month==9)||(month==11))&
&
(day==32))
day=1;
if(((month==3)||(month==5)||(month==8)||(month==10))&
(day==31))
if(((year%4==0)&
(month==2))&
(day==30))
if(((year%4!
=0)&
(day==29))
lcd1[8]=day/10+'
lcd1[9]=day%10+'
if(set==3)
w++;
if(w==8)
w=1;
lcd1[13]=*(week[w]);
lcd1[14]=*(week[w]+1);
lcd1[15]=*(week[w]+2);