基于单片机的万年历课程设计.docx
《基于单片机的万年历课程设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的万年历课程设计.docx(24页珍藏版)》请在冰点文库上搜索。
![基于单片机的万年历课程设计.docx](https://file1.bingdoc.com/fileroot1/2023-5/5/48ced4b7-dd67-47af-93eb-6005c6fc0264/48ced4b7-dd67-47af-93eb-6005c6fc02641.gif)
基于单片机的万年历课程设计
单片机课程设计任务书
1.课程设计的内容和要求(包括原始数据、技术要求、工作要求等):
一、设计万年历与显示电路
时间和日期是人们所需要的重要数据之一,关系中生活的方方面面。
获得时间和日期的方法,有日历、机械表、数字表等方法。
数字万年历精度高、显示灵活,现在得到了广泛的应用。
本设计就是来制作一个数字万年历
二、主要技术指标与要求:
⑴时间、日期、星期均可显示;
⑵时间出现误差时可调;
⑶万年历掉电后能够继续运行;
⑷可实时显示环境温度。
三.设计思路
(1)万年历可以采用专用的时钟芯片来产生,由芯片产生稳定的时间,单片机读取,处理,然后显示出来。
(2)用键盘实现数据的输入,和显示模式的选择。
(3)显示方案选择:
共阴数码管加专用驱动芯片可实现显示亮度可调、不闪烁的优点,而且软件编程较容易。
(4)温度传感器采用数字温度传感器,可实现更高精度、更简单的硬件电路。
制作起来简单。
2.对课程设计成果的要求〔包括图表、实物等硬件要求〕:
设计电路,安装调试或仿真,分析实验结果,并写出设计说明书。
要求图纸布局合理,符合工程要求,所有的器件的选择要有计算依据。
3.主要参考文献:
[1]李广弟.单片机基础[M].北京:
北京航空航天大学出版社,2001
[2]何立民.单片机高级教程:
应用与设计[M].北京:
北京航空航天大学出版社,2007
[3]陈明义.电工电子技术课程设计指导[M].长沙:
中南大学出版社,2002
[4]零点工作室.精通ProtelDXP2004电路设计[M].北京:
电子工业出版社,2006
[5].
4.课程设计工作进度计划:
序号
起迄日期
工作内容
1
2010-12-20
布置任务,教师讲解设计方法及要求
2
2010-12-21
学生查找阅读资料,并确定方案
3
2010-12-22~2010-12-24
学生设计设计硬件电路并调试通过
4
2010-12-25
学生编写软件程序
5
2010-12-27~2010-12-28
学生写说明书和论文
6
2010-12-29
答辩
7
2010-12-31
答辩
主指导教师
赵宇红
日期:
2010年12月31日
摘要:
随着电子技术的迅速发展,特别是随大规模集成电路出现,给人类生活带来了根本性的改变。
由其是单片机技术的应用产品已经走进了千家万户。
电子万年历的出现给人们的生活带来的诸多方便。
本设计是基于51系列的单片机进行的电子万年历设计,采用八位数码管显示年月日时分秒及温度信息,具有可调整日期和时间功能。
时间、日期调整由三个按键来实现,并可对闹铃开关进行设置。
日历能显示阳历和阴历年、月、日以及星期、时、分、秒。
设计以STC89C52RC单片机为核心,构成单片机控制电路;以DS1302时钟芯片作为万年历信号发生器;以DS18B20作为检测温度的传感器。
关键词:
可调万年历;单片机;时钟芯片DS1302;实时温度显示;数码管显示
1、系统概述及方法论证
1.1 系统概述
本电子万年历采用单片机控制技术和数码管显示方案,可以很好的完成万年历和实时温度显示。
时间、日期调整由三个按键来实现,并可对闹铃开关进行设置。
日历能显示阳历和阴历年、月、日以及星期、时、分、秒。
(1)基本功能
显示年、月、日、时、分、秒。
时钟时间可调节。
时钟掉电继续运行。
(2)扩展功能
多路闹钟。
实时温度显示
遥控调节时间。
电脑自同步时间
1.2系统基本方案选择和论证
1.2.1单片机芯片的选择方案和论证:
方案一:
采用AT89S52,片内ROM全都采用FlashROM;能以3V的超底压工作;同时也与MCS-51系列单片机完全该芯片内部存储器为8KBROM存储空间,同样具有89C51的功能,且具有在线编程可擦除技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,不需要对芯片多次拔插,所以不会对芯片造成损坏。
所以选择采用AT89S52作为主控制系统.
方案二:
采用89C51芯片作为硬件核心,采用FlashROM,内部具有4KBROM存储空间,能于3V的超低压工作,而且与MCS-51系列单片机完全兼容,但是运用于电路设计中时由于不具备ISP在线编程技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,对芯片的多次拔插会对芯片造成一定的损坏。
1.2.2时钟芯片的选择方案和论证:
方案一:
直接采用单片机定时计数器提供秒信号,使用程序实现年、月、日、星期、时、分、秒计数。
采用此种方案虽然减少芯片的使用,节约成本,但是,实现的时间误差较大。
所以不采用此方案。
方案二:
采用DS1302时钟芯片实现时钟,DS1302芯片是一种高性能的时钟芯片,可自动对秒、分、时、日、周、月、年以及闰年补偿的年进行计数,而且精度高,位的RAM做为数据暂存区,工作电压2.5V~5.5V范围内,2.5V时耗电小于300nA.且同组同学已从Maxim申请到了这种芯片,所以本设计采用了这种芯片。
1.2.2测温传感器方式选择:
测温可以采用热敏电阻加上模数转换得到电压,然后将测到的电压送到单片机,由单片机处理得到温度值。
但是这种方法实现起来复杂,且精度难以达到很高,所以本设计没有采用这种方式。
DS18B20是一种数字温度传感器,一根线就可以与单片机IO联接,将测到的温度以数字形式传送到单片机,所以使用简单;它的测温误差为+-0.5度,可以达到较好的精度,在日常的应用中足够。
这种芯片应用广泛,所以本设计也采用了这种测温方式。
1.3电路设计最终方案决定
综上各方案所述,对此次作品的方案选定:
采用AT89S52作为主控制系统;DS1302提供时钟;数字式温度传感器;八位数码管动态扫描作为显示,以DS18B20作为检测温度的传感器。
2、系统的硬件设计与实现
2.1电路设计框图
2.2系统核心控制部分
2.2.1STC89C52RC芯片介绍
STC89C52RC/RD+系列单片机是宏晶科技推出的新一代超强抗干扰/高速/低功耗的单片机,指令代码完全兼容传统8051单片机,12时钟/周期和6时钟/周期可任意选择。
图2.1STC89C52RC引脚功能图
2.2.2STC89C52RC连接电路图
图2.2单片机与外围连接图
2.3DS1302时钟电路
2.3.1DS1302芯片介绍
DS1302是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。
采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。
DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。
DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后背电源双电源引脚,同时提供了对后背电源进行涓细电流充电的能力。
2.3.2DS1302引脚说明
图2.3DS1302引脚封装图
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为时钟输入端。
2.3.3DS1302连接电路图
图2.4DS1302连接图
2.4DS18B20数字温度传感器介绍
2.4.1DS18B20芯片介绍
DS18B20数字温度传感器是美国DALLAS公司生产的可组网数字温度传感器芯片,具有耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。
图2.5DS18B20引脚封装图
2.4.2DS18B20连接电路图
图2.6DS18B20连接图
2.5MAX7219共阴数码管专用驱动芯片
2.5.1MAX7219芯片介绍
MAX7219是一种集成化的串行输入/输出共阴极显示驱动器,它连接微处理器与8位数字的7段数字LED显示,也可以连接条线图显示器或者64个独立的LED。
其上包括一个片上的B型BCD编码器、多路扫描回路,段字驱动器,而且还有一个8*8的静态RAM用来存储每一个数据。
只有一个外部寄存器用来设置各个LED的段电流。
每个数据可以寻址在更新时不需要改写所有的显示。
MAX7219同样允许用户对每一个数据选择编码或者不编码。
整个设备包含一个150μA的低功耗关闭模式,模拟和数字亮度控制,一个扫描限制寄存器允许用户显示1-8位数据,还有一个让所有LED发光的检测模式。
1DIN串行数据输入端口。
在时钟上升沿时数据被载入内部的16位寄存器。
2,3,5-8,10,11DIG0–DIG7八个数据驱动线路置显示器共阴极为低电平。
关闭时7219此管脚输出高电平,7221呈现高阻抗。
4,9GND地线(4脚和9脚必须同时接地)
12LOAD(MAX7219)载入数据。
连续数据的后16位在LOAD端的上升沿时被锁定。
CS(MAX7221)片选端。
该端为低电平时串行数据被载入移位寄存器。
连续数据的后16位在cs端的上升沿时被锁定。
13CLK时钟序列输入端。
最大速率为10MHz.在时钟的上升沿,数据移入内部移位寄存器。
下降沿时,数据从DOUT端输出。
对MAX7221来说,只有当cs端为低电平时时钟输入才有效。
14-17,20-23SEG7段和小数点驱动,为显示器提供电流。
当一个段驱动关闭时,7219的此端呈低电平,7221呈现高阻抗。
18SET通过一个电阻连接到VDD来提高段电流。
19V+正极电压输入,+5V
24DOUT串行数据输出端口,从DIN输入的数据在16.5个时钟周期后在此端有效。
当使用多个MAX7219/MAX7221时用此端方便扩展。
2.5.2MAX7219连接电路图
图2.7MAX7219与数码管连接图
3、系统程序设计
3.1DS1302.h头文件设计
#ifndef_DS1302_H_
#define_DS1302_H_
sbitDS1302_CLK=P2^2;//实时时钟时钟线引脚
sbitDS1302_IO=P2^1;//实时时钟数据线引脚
sbitDS1302_RST=P2^0;//实时时钟复位线引脚
sbitACC0=ACC^0;
sbitACC7=ACC^7;
typedefstruct__SYSTEMTIME__
{
unsignedcharSecond;
unsignedcharMinute;
unsignedcharHour;
unsignedcharWeek;
unsignedcharDay;
unsignedcharMonth;
unsignedcharYear;
unsignedcharDateString[9];
unsignedcharTimeString[9];
}SYSTEMTIME;//定义的时间类型
#defineAM(X)X
#definePM(X)(X+12)//转成24小时制
#defineDS1302_SECOND0x80//秒寄存器
#defineDS1302_MINUTE0x82//分寄存器
#defineDS1302_HOUR0x84
#defineDS1302_WEEK0x8A
#defineDS1302_DAY0x86
#defineDS1302_MONTH0x88
#defineDS1302_YEAR0x8C
#defineDS1302_RAM(X)(0xC0+(X)*2)//用于计算DS1302_RAM地址的宏
voidDS1302InputByte(unsignedchard)//实时时钟写入一字节(内部函数)
{
unsignedchari;
ACC=d;
for(i=8;i>0;i--)
{
DS1302_IO=ACC0;//相当于汇编中的RRC
DS1302_CLK=1;
DS1302_CLK=0;//发一个高跳变到低的脉冲
ACC=ACC>>1;
}
}
unsignedcharDS1302OutputByte(void)//实时时钟读取一字节(内部函数)
{
unsignedchari;
for(i=8;i>0;i--)
{
ACC=ACC>>1;//相当于汇编中的RRC
ACC7=DS1302_IO;
DS1302_CLK=1;
DS1302_CLK=0;//发一个高跳变到低的脉冲
}
return(ACC);
}
voidWrite1302(unsignedcharucAddr,unsignedcharucDa)
//ucAddr:
DS1302地址,ucData:
要写的数据
{
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr);//地址,命令
DS1302InputByte(ucDa);//写1Byte数据
DS1302_CLK=1;
DS1302_RST=0;//RST0->1->0,CLK0->1
}
unsignedcharRead1302(unsignedcharucAddr)//读取DS1302某地址的数据
{
unsignedcharucData;
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;//enable
DS1302InputByte(ucAddr|0x01);//地址,命令
ucData=DS1302OutputByte();//读1Byte数据
DS1302_CLK=1;//RST0->1->0,CLK0->1
DS1302_RST=0;
return(ucData);
}
voidDS1302_SetProtect(bitflag)//是否写保护
{
if(flag)
Write1302(0x8E,0x10);//WP=1,不能写入
else
Write1302(0x8E,0x00);//WP=0,可以写入
}
voidDS1302_SetTime(unsignedcharAddress,unsignedcharValue)//设置时间函数
{
DS1302_SetProtect(0);
Write1302(Address,((Value/10)<<4|(Value%10)));
//高4位为十位,低4位为个位
}
voidDS1302_GetTime(SYSTEMTIME*Time)
{
unsignedcharReadValue;
ReadValue=Read1302(DS1302_SECOND);
Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);//转换成10进制的秒
ReadValue=Read1302(DS1302_MINUTE);
Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_HOUR);
Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_DAY);
Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_WEEK);
Time->Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_MONTH);
Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_YEAR);
Time->Year=((ReadValue&0xf0)>>4)*10+(ReadValue&0x0F);
}
voidInitial_DS1302(void)
{
unsignedcharSecond=Read1302(DS1302_SECOND);
if(Second&0x80)//如果第七为1(表明没有启动),则启动时钟
DS1302_SetTime(DS1302_SECOND,0);
}
#endif
3.2MAX7219.h头文件设计
/***********************
******MAX7219驱动程序****
************************/
#defineDECODE_MODE0x09
#defineINTENSITY0x0A
#defineSCAN_LIMIT0x0B
#defineSHUTDOWN0x0C
#defineDISPLAY_TEST0x0F
unsignedchardispcode[]={0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b,0x01};
sbitDIN=P1^2;
sbitLOAD=P1^1;
sbitCLK=P1^0;
voidsend_max7219(unsignedcharaddr1,unsignedchardata1)
{
unsignedchari,mask;
LOAD=0;
for(i=8;i>0;i--)
{
mask=1<<(i-1);//设置掩码
CLK=0;//CLK置低
if(addr1&mask)//判断并输出一位
DIN=1;//输出"1"
else//或
DIN=0;//"0"
CLK=1;//CLK置高
}
for(i=8;i>0;i--)
{
mask=1<<(i-1);//设置掩码
CLK=0;//CLK置低
if(data1&mask)//判断并输出一位
DIN=1;//输出"1"
else//或
DIN=0;//"0"
CLK=1;//CLK置高
}
LOAD=1;
}
voidinit_max7219(void)
{
send_max7219(SHUTDOWN,0x01);//开启正常工作模式,非关闭模式
send_max7219(DISPLAY_TEST,0x00);//选择正常工作,非现实测试模式
send_max7219(DECODE_MODE,0x00);//全译码模式
send_max7219(SCAN_LIMIT,0x07);//8个数码管全用
send_max7219(INTENSITY,0x05);//初始化亮度
}
/****max7219驱动结束******/
3.3DS18B20.h头文件设计
3.4MAIN.C源程序设计及流程图
sbitkey3=P1^5;
sbitkey2=P1^4;
sbitkey1=P1^3;
unsignedchartime[]={0,0,0,0,0,0,0,0};//用来储存时间
unsignedchardate[]={0,0,0,0,0,0,0,0};//用来储存日期
SYSTEMTIMEtime1;//在ds1302.h文件中已经定义了一个名字为SYSTEMTIME的结构体,在这里我们定义一个变量名
//为time的SYSTEMTIME结构体
voiddelay(unsignedchari)//延时子程序
{
unsignedcharj;
while((i--)!
=0)
{
for(j=123;j>0;j--);
}
}
unsignedcharbutton_time(unsignedcharn,unsignedcharx)
//时钟调整子程序
{//key1是自增
if(key1==0)
{
delay(50);
if(key1==0)
{
n++;
if(n==x)//x为最大值
n=0;
while(key1==0);
}
}
returnn;
}
unsignedcharbutton_date(unsignedcharn,unsignedcharx)
//日期调整子程序
{
if(key1==0)
{
delay(50);
if(key1==0)
{
n++;
if(n==x)
n=1;
while(key1==0);
}
}
returnn;
}
voiddisplay(unsignedcharhour10,unsignedcharhour1,unsignedcharminute10,unsignedcharminute1,unsignedcharsecond10,unsignedcharsecond1)//显示子程序
{