基于单片机的电子日历钟设计.docx
《基于单片机的电子日历钟设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的电子日历钟设计.docx(35页珍藏版)》请在冰点文库上搜索。
基于单片机的电子日历钟设计
电子日历设计
摘要
用单片机控制时间的读取并显示在液晶屏幕上面,并可通过按键实现对时间的修改。
文中详细论述了电子日历钟设计原理、使用的各芯片的介绍,阐明了本实例所使用的设计方案、详细的电路图以及电子程序。
关键词:
电子日历钟单片机DS1302LCD1602
目录
摘要................................................2
1前言.................................................5
1.1设计任务.............................................5
1.2 本设计的应用意义.....................................5
2总体设计方案.............................................5
2.1 设计原理及相关说明................................5
2.2 总体设计框图...............................................5
2.3 电子日历钟电路图......................................5
2.4 电子日历钟程序......................................5
3芯片设计及对其的调用..........................................6
3.1 DS1302实时时钟电路....................................6
3.1.1DS1302的结构及工作原理............................6
3.1.2引脚功能及结构...................................6
3.1.3DS1302的控制字节...................................6
3.1.4数据输入输出(I/O)...................................6
3.1.5DS1302的寄存器...................................7
3.2 LCD1602字符型液晶模块....................................7
3.2.1LCD1602模块介绍...................................7
3.2.2LCD1602的一些参数及操作指令..........................
4系统调试...............................................12
4.1 硬件电路调试.........................................12
4.2 软件程序调试.........................................12
4.3 综合调试.............................................12
参考文献.......................................................14
\
1前言
1.1设计任务
本设计实现一个小巧的电子日历钟,可以利用DS1302读取日期及时间并传至89C51,使之显示于LCD1602液晶显示屏上。
设有四个按键,可以进入设置菜单对电子日历钟进行时间设置。
开机时可以显示制作单位以及制作者名称。
1.2本设计的应用意义
此电子日历钟小巧便捷利于携带,界面清爽,一目了然,方便的使您知晓当前时间,并可对时间做出修改,实在是居家旅行日常生活之必备用品!
2总体设计方案
2.1 设计原理及相关说明
设计原理:
利用DS1302实时时钟电路芯片来读取系统中的日期以及时间信息,并利用P1.6端口将相关信息传送至AT89C51主芯片之中,利用P2端口使之显示于LCD1602液晶显示屏上,四个按键分别置于P1口的0、1、2、3端口可以对时间进行控制修改。
详细请参阅第三节的芯片介绍。
相关说明:
点击确定按键可以进入LCD屏上方显示的主菜单,点击返回按键可以退出菜单,在时间修改菜单中点击修改“小时”按键可以修改时间中的小时数,点击修改“分钟”按键可以修改时间中的分钟数。
2.2总体设计框图
电子日历钟设计框图如图2.1所示:
图2.1电子日历钟设计框图
2.3电子日历钟电路图
电子日历钟电路图请见附件A
2.3电子日历钟程序
电子日历钟程序清单请见附件B
//SMC1602.h
#ifndef__SMC1602_H__
#define__SMC1602_H__
#definevdInitialize()vWriteCMD(0x01);vWriteCMD(0x38);vWriteCMD(0x0C);//初始化//vWriteCMD(0x01);清屏
//vWriteCMD(0x38);显示模式设置:
8位2行5x7点阵
//vWriteCMD(0x0C);(0x0C)文字不动,光标自动右移
//vWriteCMD(0x0F);显示器开、光标开、闪烁开
voidvWriteCMD(unsignedcharucCommand);//把1个命令写入LCD。
voidvWriteData(unsignedcharucData);//把1个数据写入LCD。
voidvShowOneChar(unsignedcharucChar);//在当前光标处显示1个字符。
voidvShowChar(unsignedcharucaChar[]);//在当前光标处显示1个字符串
#endif
//KeyProcess.h
#ifndef__KEYPROCESS_H__
#define__KEYPROCESS_H__
voidvKeyProcess(unsignedcharucKeyCode);
#endif
//KeyScan.h
#ifndef__KEYSCAN_H__
#define__KEYSCAN_H__
unsignedcharucKeyScan();//键盘扫描程序
#endif
#include
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<端口设置宏定义>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#defineLCDRSP3_5//寄存器选择信号:
//0--数据寄存器;
//1--指令寄存器。
#defineLCDRWP3_6//读写信号:
//1--读LCD;
//0--写LCD。
#defineLCDEP3_7//片选信号,当输入下降沿信号时,
//执行指令或传送数据。
#defineLCDPORTP0//LCD数据接口。
//*******************************延时函数
voidvDelay()
{
unsignedintuiCount;
for(uiCount=0;uiCount<250;uiCount++);
}
//***************************把1个命令写入LCD
voidvWriteCMD(unsignedcharucCommand)
{
vDelay();//先延时。
LCDE=1;//然后把LCD改为写入命令状态。
LCDRS=0;
LCDRW=0;
LCDPORT=ucCommand;//再输出命令。
LCDE=0;//最后执行命令。
}
//***************************把1个数据写入LCD
voidvWriteData(unsignedcharucData)
{
vDelay();//先延时。
LCDE=1;//然后把LCD改为写入数据状态。
LCDRS=1;
LCDRW=0;
LCDPORT=ucData;//再输出数据。
LCDE=0;//最后显示数据。
}
//***********************把1个字符显示到当前光标处
voidvShowOneChar(unsignedcharucChar)
{
switch(ucChar)
{
case'':
vWriteData(0x20);break;
case'!
':
vWriteData(0x21);break;
case'"':
vWriteData(0x22);break;
case'#':
vWriteData(0x23);break;
case'$':
vWriteData(0x24);break;
case'%':
vWriteData(0x25);break;
case'&':
vWriteData(0x26);break;
case'>':
vWriteData(0x27);break;
case'(':
vWriteData(0x28);break;
case')':
vWriteData(0x29);break;
case'*':
vWriteData(0x2A);break;
case'+':
vWriteData(0x2B);break;
case'-':
vWriteData(0x2D);break;
case'.':
vWriteData(0x2E);break;
case'/':
vWriteData(0x2F);break;
case'=':
vWriteData(0x3D);break;
case'<':
vWriteData(0x3E);break;
case'?
':
vWriteData(0x3F);break;
case'^':
vWriteData(0x5E);break;
case':
':
vWriteData(0x3A);break;
case'0':
vWriteData(0x30);break;
case'1':
vWriteData(0x31);break;
case'2':
vWriteData(0x32);break;
case'3':
vWriteData(0x33);break;
case'4':
vWriteData(0x34);break;
case'5':
vWriteData(0x35);break;
case'6':
vWriteData(0x36);break;
case'7':
vWriteData(0x37);break;
case'8':
vWriteData(0x38);break;
case'9':
vWriteData(0x39);break;
case'A':
vWriteData(0x41);break;
case'B':
vWriteData(0x42);break;
case'C':
vWriteData(0x43);break;
case'D':
vWriteData(0x44);break;
case'E':
vWriteData(0x45);break;
case'F':
vWriteData(0x46);break;
case'G':
vWriteData(0x47);break;
case'H':
vWriteData(0x48);break;
case'I':
vWriteData(0x49);break;
case'J':
vWriteData(0x4A);break;
case'K':
vWriteData(0x4B);break;
case'L':
vWriteData(0x4C);break;
case'M':
vWriteData(0x4D);break;
case'N':
vWriteData(0x4E);break;
case'O':
vWriteData(0x4F);break;
case'P':
vWriteData(0x50);break;
case'Q':
vWriteData(0x51);break;
case'R':
vWriteData(0x52);break;
case'S':
vWriteData(0x53);break;
case'T':
vWriteData(0x54);break;
case'U':
vWriteData(0x55);break;
case'V':
vWriteData(0x56);break;
case'W':
vWriteData(0x57);break;
case'X':
vWriteData(0x58);break;
case'Y':
vWriteData(0x59);break;
case'Z':
vWriteData(0x5A);break;
case'a':
vWriteData(0x61);break;
case'b':
vWriteData(0x62);break;
case'c':
vWriteData(0x63);break;
case'd':
vWriteData(0x64);break;
case'e':
vWriteData(0x65);break;
case'f':
vWriteData(0x66);break;
case'g':
vWriteData(0x67);break;
case'h':
vWriteData(0x68);break;
case'i':
vWriteData(0x69);break;
case'j':
vWriteData(0x6A);break;
case'k':
vWriteData(0x6B);break;
case'l':
vWriteData(0x6C);break;
case'm':
vWriteData(0x6D);break;
case'n':
vWriteData(0x6E);break;
case'o':
vWriteData(0x6F);break;
case'p':
vWriteData(0x70);break;
case'q':
vWriteData(0x71);break;
case'r':
vWriteData(0x72);break;
case's':
vWriteData(0x73);break;
case't':
vWriteData(0x74);break;
case'u':
vWriteData(0x75);break;
case'v':
vWriteData(0x76);break;
case'w':
vWriteData(0x77);break;
case'x':
vWriteData(0x78);break;
case'y':
vWriteData(0x79);break;
case'z':
vWriteData(0x7A);break;
default:
break;
}
}
//*********************把1个字符串显示到当前光标处
voidvShowChar(unsignedcharucaChar[])
{
unsignedcharucCount;
for(ucCount=0;;ucCount++)
{
vShowOneChar(ucaChar[ucCount]);
if(ucaChar[ucCount+1]=='\0')
break;
}
}
#defineDSIOP1_2//实时时钟数据线引脚
#defineDSCLKP1_1//实时时钟时钟线引脚
#defineDSRSTP1_0//实时时钟复位线引脚
#defineDS_SECOND0x80//DS1302数据地址。
#defineDS_MINUTE0x82
#defineDS_HOUR0x84
#defineDS_WEEK0x8A
#defineDS_DAY0x86
#defineDS_MONTH0x88
#defineDS_YEAR0x8C
//********************************全局变量
sbitACC0=ACC^0;
sbitACC7=ACC^7;
typedefstructTIME//定义的时间类型
{
unsignedcharucSecond;
unsignedcharucMinute;
unsignedcharucHour;
unsignedcharucWeek;
unsignedcharucDay;
unsignedcharucMonth;
unsignedcharucYear;
unsignedcharucaDateString[9];
unsignedcharucaTimeString[9];
}TIME;
//*********************实时时钟写入一字节(内部函数)
voidvWriteByte(unsignedcharucByte)
{
unsignedcharucCount;
ACC=ucByte;
for(ucCount=8;ucCount>0;ucCount--)
{
DSIO=ACC0;//把累加器第0位赋给DSIO口。
DSCLK=1;//DSCLK下降沿,写入数据。
DSCLK=0;
ACC=ACC>>1;//把累加器里的数据右移一位。
}
}
//**********************实时时钟读入一字节(内部函数)
unsignedcharucReadByte(void)
{
unsignedcharucCount;
for(ucCount=8;ucCount>0;ucCount--)
{
ACC=ACC>>1;//把累加器右移一位。
ACC7=DSIO;//把DSIO的数据传给累加器最高位。
DSCLK=1;//DSCLK下降沿读出数据。
DSCLK=0;
}
returnACC;
}
//*************************向实时时钟写入一字节
voidvDSWriteDirect(unsignedcharucAddr,unsignedcharucData)//ucAddr:
DS1302地址,ucData:
要写的数据
{
DSRST=0;
DSCLK=0;
DSRST=1;
vWriteByte(ucAddr);//地址,命令
vWriteByte(ucData);//写1Byte数据
DSCLK=1;
DSRST=0;
}
//**************************读取DS1302某地址的数据
unsignedcharvDSReadDirect(unsignedcharucAddr)
{
unsignedcharucData;
DSRST=0;
DSCLK=0;
DSRST=1;
vWriteByte(ucAddr|0x01);//地址,命令
ucData=ucReadByte();//读1Byte数据
DSCLK=1;
DSRST=0;
returnucData;
}
//*******************************是否写保护
voidvDSSetProtect(bitbFlag)
{
if(bFlag)
vDSWriteDirect(0x8E,0x10);
else
vDSWriteDirect(0x8E,0x00);
}
//******************************设置实时时钟时间
voidvDSSetTime(unsignedcharucAddress,unsignedcharucValue)
{
vDSSetProtect(0);//取消保护。
vDSWriteDirect(ucAddress,((ucValue/10)<<4|(ucValue%10)));//吧ucValue转换成BCD码,然后写入。
}
//*******************************读取实时时钟时间
voidvDSGetTime(TIME*stTime)//把读取的BCD码转换成2进制数然后存入时间数组。
{
unsignedcharucReadValue;
ucReadValue=vDSReadDirect(DS_SECOND);//秒
stTime->ucSecond=((ucReadValue&0x70)>>4)*10+(ucReadValue&0x0F);
ucReadValue=vDSReadDirect(DS_MINUTE);//分
stTime->ucMinute=((ucReadValue&0x70)>>4)*10+(ucReadValue&0x0F);
ucReadValue=vDSReadDirect(DS_HOUR);//小时
stTime->ucHour=((ucReadValue&0x70)>>4)*10+(ucReadValue&0x0F);
ucRe