基于52单片机的万年历显示(采用实时芯片DS1302芯片+LCD1602液晶显示)
仿真图:
项目名称:Real_TimerLM016LLCD1VSSVDDVEERSRWEC122pF+5VC222pFD0D1D2D3D4D5D6D7RP11234567891011121314+5VX11912MHzU1XTAL1P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RD39383736353433322122232425262728101112131415161712345678910K+5V18XTAL2C320uF1k9RST+5V+5V1.5V1.5V293031PSENALEEAAT89C52R1RV110kU22X1VCC1VCC281+5VX23X2RSTSCLKI/O57612345678P1.0/T2P1.1/T2EXP1.2P1.3P1.4P1.5P1.6P1.732768DS1302说明:用ds1302和lcd1602显示实时时钟 x x x x x x 程序: LCD1602的H文件: /************************************************************ -- THE LCD1602 DISPLAY LIB --
COPYRIGHT (C) 2014 BY LLH
-- ALL RIGHTS RESERVED --
ATTENTION:延时不能过长,否则无法与DS1302同步(最好小于1ms) *************************************************************/ #ifndef __LCD1602_DIS_H__ #define __LCD1602_DIS_H__
#define uint unsigned int #define uchar unsigned char
sbit lcd_rs=P2^0; sbit lcd_rw=P2^1; sbit lcd_en=P2^2;
/**********延时子程序************/ void delay(uint z) {
uint x,y; for(x=z;x>0;x--) }
for(y=65;y>0;y--);
//60刚好和DS1302同步
/***********写命令子程序**********/ void write_com(uchar com) { lcd_rs=0; lcd_rw=0; P0=com; delay(1); lcd_en=1; delay(1); lcd_en=0; }
/***********写数据子程序**********/ void write_data(uchar date) { lcd_rs=1; lcd_rw=0; P0=date; delay(1); lcd_en=1; delay(1); lcd_en=0; }
/**********初始化子程序************/ void init_LCD1602() {
lcd_en=0; write_com(0x38); //显示模式设置:16*2显示,5*7点阵,8位数据接口 write_com(0x0c); //开显示,不显示光标 write_com(0x06); //指针、光标自动加一,整屏不移动
write_com(0x80); //初始位置设置 }
/*********显示子程序***********/ void display(uchar *str) {
while(*str!='\\0') { write_data(*str); str++; } }
#endif
DS1302的H文件:
/****************************************************************** -- THE DS1302 REAL_TIME LIB --
COPYRIGHT (C) 2014 BY LLH
-- ALL RIGHTS RESERVED --
ATTENTION:不能使用(i=0;i<8;i++),否则,液晶无法显示确 切的时间(???);星期的显示多了一天(???)
********************************************************************/ #ifndef __DS1302_REAL_TIME_H__ #define __DS1302_REAL_TIME_H__
#define uint unsigned int #define uchar unsigned char
sbit DS1302_RST=P1^5; sbit DS1302_SCLK=P1^6; sbit DS1302_IO=P1^7; sbit ACC0=ACC^0; sbit ACC7=ACC^7;
typedef struct {
uchar second; uchar minute; uchar hour; uchar week;
uchar day; uchar month; uchar year; uchar date_str[11]; uchar time_str[9]; }date_time;
/**************写数据定义*****************/ #define DS1302_SECOND 0x80 #define DS1302_MINUTE 0x82 #define DS1302_HOUR 0x84 #define DS1302_WEEK 0x8A #define DS1302_DAY 0x86 #define DS1302_MONTH 0x88 #define DS1302_YEAR 0x8C #define ST 0x00
/*************单字节写数据子程序**************/ void single_byte_write(uchar date) {
uchar i; ACC=date;
for(i=8;i>0;i--) //不能使用(i=0;i<8;i++),否则,液晶只显示00000 { DS1302_IO=ACC0; DS1302_SCLK=1; DS1302_SCLK=0; ACC=ACC>>1; } }
/*************单字节读数据子程序**************/ uchar single_byte_read( ) {
uchar i; for(i=8;i>0;i--) { ACC=ACC>>1; ACC7=DS1302_IO; DS1302_SCLK=1; DS1302_SCLK=0; } return ACC;
}
/**************控制字的写入****************/ void write_command(uchar addr,uchar dat) {
DS1302_SCLK=0; DS1302_RST=0; DS1302_RST=1; single_byte_write(addr); single_byte_write(dat); DS1302_SCLK=1; DS1302_RST=0; }
/**************读取芯片内部的数据****************/ uchar read_data(uchar address) { uchar r_data;
DS1302_SCLK=0; DS1302_RST=0; DS1302_RST=1;
single_byte_write(address|0x01);//若没加(或0x01)ds1302和lcd1602都无法正常显示(?) r_data=single_byte_read(); DS1302_SCLK=1; DS1302_RST=0; return r_data; }
/************初始化子程序************/ void init_DS1302() {
uchar temp; temp=read_data(DS1302_SECOND); if(temp&0x80) { write_command(0x8e,0x00); //启动读写 write_command(0x84,0x00); //设置24小时模式 write_command(DS1302_SECOND,ST); //写入当前时间数据 } }