DS1302实时时钟模块,1602显示
以DS1302实时时钟芯片和液晶显示屏CD1602为基础设计的电子钟

实验目的:1、能够以DS1302实时时钟芯片和液晶显示屏CD1602为基础设计一款电子钟2、熟悉DS1302芯片的工作过程3、熟悉CD1602芯片的工作过程4、可以进行必要的扩展,如用第三DS18B20新品进行温度采集和显示5、熟悉掌握51的c程序的编写6、掌握用Proteus进行系统设计仿真验证实验仪器、仪表目录1、DS1302实时时钟芯片1片2、LCD1602液晶显示屏1个,3、80C52芯片1片5、DS18B20芯片一片6、晶振、电容、电阻、开关各若干等7、proteus仿真软件8、Keil C51、PC机实验设计任务以DS1302实时时钟芯片和液晶显示屏LCD1602为基础设计一个电子钟,要求:时间和日期可调整,按键采用3个按键;至少在Proteus上调试通过。
扩展:闹钟和重要日期提醒功能(增加蜂鸣器),闹铃音乐功能实验步骤1、打开Keil软件,新建一个工程文件,选择好芯片,并记得在“Options for Target 1”的Output 选项中,将Create HEX Fil选项勾起来。
2、将编写的程序保存成“.C”的形式3、编译保存好的C文件,并根据提示修改程序中的错误,直到编译成功为止4、打开proteus软件,画出实验电路图5、在89C52中,载入原来已生成的HEX文档6、按下运行键,对Proteus进行软件仿真,观察运行结果原理、结果及分析一、设计方案原理与设计特点分析电子钟总的设计模块:各个模块电路原理分析:1、DS1302时钟采集模块:1.1电路原理图:1.2 DS1302分析:首先DS1302是DALLAS公司推出的涓流充电时钟芯片。
内含有一个实时时钟/日历和31字节静态RAM通过简单的串行接口与单片机进行通信实时时钟/日历电路提供秒分时日日期月年的信息每月的天数和闰年的天数可自动调整时钟操作。
DS1302芯片广脚介绍:X1、X2为32.768KHz晶振管脚。
GND 为地。
51单片机,DS1302时钟,1602显示,可调时钟剖析

基于proteus的51单片机仿真实例八十一、实时时钟芯片DS1302应用实例1、DS1302引脚排列:如下图引脚说明:1)Vcc1:后备电源,VCC2:主电源。
在主电源关闭的情况下,也能保持时钟的连续运行。
DS1302由Vcc1或Vcc2两者中的较大者供电。
当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。
当Vcc2小于Vcc1时,DS1302由Vcc1供电。
2)X1、X2:振荡源,外接32.768kHz 晶振。
3)RST:复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。
RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。
当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。
如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。
上电运行时,在Vcc>2.0V之前,RST必须保持低电平。
只有在SCLK为低电平时,才能将RST置为高电平。
4)I/O为串行数据输入输出端(双向)。
5)SCLK为时钟输入端。
2、DS1302的控制字节DS1302 的控制字如下图所示。
控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。
3、数据输入输出(I/O)在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。
同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。
DS1302的寄存器DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式,其日历、时间寄存器及其控制字见数据手册。
DS1302时钟+DS18B20用LCD1602显示(系统很简单)

DS1302时钟+DS18B20用LCD1602显示(系统很简单)看仔细点啊貌似很多这样的图但可不一样喔最小系统是用AT89s52搭建的!记得回去自己用prot ues和Keil仿真一下,这样有利于进一步了解!故未将仿真好的代码上传,如果真的需要的话可以和我联系!程序代码:#include <>#include <>据端口8A8C0F0F0F0F0F0F0F2007/07/228c07/07/25期: 3. 时间: 23:59:55Write1302(0x88,0x07);Write1302(0x86,0x25);Write1302(0x8a,0x07);Write1302(0x84,0x23);Write1302(0x82,0x59);Write1302(0x80,0x55);Write1302(0x8e,0x80); {;}}}void outkey() //跳出调整模式,返回默认显示{ uchar Second;if(out==0||wireless_1==1){ mdelay(8);count=0;hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_month=0,hide_year=0;Second=Read1302(DS1302_SECOND);Write1302(0x8e,0x00); //写入允许Write1302(0x80,Second&0x7f);Write1302(0x8E,0x80); //禁止写入done=0;while(out==0);while(wireless_1==1);}}////////////////////////////////////////////////////////////////////////////////////////// //////////////////void Upkey()//升序按键{Up=1;if(Up==0||wireless_2==1){mdelay(8);switch(count){case 1:temp="Read1302"(DS1302_ SECOND); //读取秒数temp="temp"+1; //秒数加1up_flag=1; //数据调整后更新标志if((temp&0x7f)>0x59) //超过59秒,清零temp="0";break;case 2:temp="Read1302"(DS1302_ MINUTE); //读取分数temp="temp"+1; //分数加1up_flag=1;if(temp>0x59) //超过59分,清零temp="0";break;case 3:temp="Read1302"(DS1302_ HOUR); //读取小时数temp="temp"+1; //小时数加1up_flag=1;if(temp>0x23) //超过23小时,清零temp="0";break;case 4:temp="Read1302"(DS1302_ WEEK); //读取星期数temp="temp"+1; //星期数加1up_flag=1;if(temp>0x7)temp="1";break;case 5:temp="Read1302"(DS1302_ DAY); //读取日数temp="temp"+1; //日数加1up_flag=1;if(temp>0x31)temp="1";break;case 6:temp="Read1302"(DS1302_ MONTH); //读取月数temp="temp"+1; //月数加1up_flag=1;if(temp>0x12)temp="1";break;case 7:temp="Read1302"(DS1302_ YEAR); //读取年数temp="temp"+1; //年数加1up_flag=1;if(temp>0x85)temp="0";break;default:break;}while(Up==0);while(wireless_2==1);}}////////////////////////////////////////////////////////////////////////////////////////// //////////////////void Downkey()//降序按键{Down=1;if(Down==0||wireless_3==1){mdelay(8);switch(count){case 1:temp="Read1302"(DS1302_ SECOND); //读取秒数temp="temp-1"; //秒数减1down_flag=1; //数据调整后更新标志if(temp==0x7f) //小于0秒,返回59秒temp="0x59";break;case 2:temp="Read1302"(DS1302_ MINUTE); //读取分数temp="temp-1"; //分数减1down_flag=1;if(temp==-1)temp="0x59"; //小于0秒,返回59秒break;case 3:temp="Read1302"(DS1302_ HOUR); //读取小时数temp="temp-1"; //小时数减1down_flag=1;if(temp==-1)temp="0x23";break;case 4:temp="Read1302"(DS1302_ WEEK); //读取星期数temp="temp-1"; //星期数减1down_flag=1;if(temp==0)temp="0x7";;break;case 5:temp="Read1302"(DS1302_ DAY); //读取日数temp="temp-1"; //日数减1down_flag=1;if(temp==0)temp="31";break;case 6:temp="Read1302"(DS1302_ MONTH); //读取月数temp="temp-1"; //月数减1down_flag=1;if(temp==0)temp="12";break;case 7:temp="Read1302"(DS1302_ YEAR); //读取年数temp="temp-1"; //年数减1down_flag=1;if(temp==-1)temp="0x85";break;default:break;}while(Down==0);while(wireless_3==1);}}void Setkey()//模式选择按键{Set=1;if(Set==0||wireless_4==1){mdelay(8);count="count"+1; //Setkey按一次,count就加1 done="1"; //进入调整模式while(Set==0);while(wireless_4==1);}}void keydone()//按键功能执行{ uchar Second;if(flag==0) //关闭时钟,停止计时{ Write1302(0x8e,0x00); //写入允许temp="Read1302"(0x80);Write1302(0x80,temp|0x80);Write1302(0x8e,0x80); //禁止写入flag="1";}Setkey(); //扫描模式切换按键 switch(count){case 1:do //count=1,调整秒{outkey(); //扫描跳出按钮 Upkey(); //扫描加按钮Downkey(); //扫描减按钮if(up_flag==1||down_flag==1) //数据更新,重新写入新的数据{Write1302(0x8e,0x00); //写入允许Write1302(0x80,temp|0x80); //写入新的秒数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}hide_sec++; //位闪计数if(hide_sec>3)hide_sec=0;show_time(); //液晶显示数据 }while(count==2);break;case 2:do //count=2,调整分{hide_sec=0;outkey();Upkey();Downkey();if(temp>0x60)temp="0";if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x82,temp); //写入新的分数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}hide_min++;if(hide_min>3)hide_min=0;show_time();}while(count==3);break;case 3:do //count=3,调整小时{hide_min=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x84,temp); //写入新的小时数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}hide_hour++;if(hide_hour>3)hide_hour=0;show_time();}while(count==4);break;case 4:do //count=4,调整星期{hide_hour=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x8a,temp); //写入新的星期数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}hide_week++;if(hide_week>3)hide_week=0;show_time();}while(count==5);break;case 5:do //count=5,调整日{hide_week=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x86,temp); //写入新的日数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}hide_day++;if(hide_day>3)hide_day=0;show_time();}while(count==6);break;case 6:do //count=6,调整月{hide_day=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x88,temp); //写入新的月数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}hide_month++;if(hide_month>3)hide_month=0;show_time();}while(count==7);break;case 7:do //count=7,调整年{hide_month=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x8c,temp); //写入新的年数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}hide_year++;if(hide_year>3)hide_year=0;show_time();}while(count==8);break;case 8: count="0";hide_year=0; //count8, 跳出调整模式,返回默认显示状态Second="Read1302"(DS1302_SECOND);Write1302(0x8e,0x00); //写入允许Write1302(0x80,Second&0x7f);Write1302(0x8E,0x80); //禁止写入 done="0";break; //count=7,开启中断,标志位置0并退出default:break;}}void show_time() //液晶显示程序{DS1302_GetTime(&CurrentTime); //获取时钟芯片的时间数据TimeToStr(&CurrentTime); //时间数据转换液晶字符DateToStr(&CurrentTime); //日期数据转换液晶字符ReadTemp(); //开启温度采集程序temp_to_str(); //温度数据转换成液晶字符GotoXY(12,1); //液晶字符显示位置Print(TempBuffer); //显示温度GotoXY(0,1);Print; //显示时间GotoXY(0,0);Print; //显示日期GotoXY(15,0);Print(week_value); //显示星期GotoXY(11,0);Print("Week"); //在液晶上显示字母 weekDelay1ms(400); //扫描延时}main(){flag="1";//时钟停止标志LCD_Initial(); //液晶初始化Init_DS18B20( ) ; / /DS18B20初始化Initial_DS1302(); //时钟芯片初始化up_flag=0;down_flag=0;done=0; / /进入默认液晶显示wireless_1=0;wireless_2=0;wireless_3=0;wireless_4=0;while(1){while(done==1)keydone();//进入调整模式while(done==0){show_tim e(); //液晶显示数据flag="0" ;Setkey();//扫描各功能键}}}。
以DS1302实时时钟芯片和液晶显示屏CD1602为基础设计的电子钟

电子系统设计实验报告实验目的:1、能够以DS1302实时时钟芯片和液晶显示屏CD1602为基础设计一款电子钟2、熟悉DS1302芯片的工作过程3、熟悉CD1602芯片的工作过程4、可以进行必要的扩展,如用第三DS18B20新品进行温度采集和显示5、熟悉掌握51的c程序的编写6、掌握用Proteus进行系统设计仿真验证实验仪器、仪表目录1、DS1302实时时钟芯片1片2、LCD1602液晶显示屏1个,3、80C52芯片1片5、DS18B20芯片一片6、晶振、电容、电阻、开关各若干等7、proteus仿真软件8、Keil C51、PC机实验设计任务以DS1302实时时钟芯片和液晶显示屏LCD1602为基础设计一个电子钟,要求:时间和日期可调整,按键采用3个按键;至少在Proteus上调试通过。
扩展:闹钟和重要日期提醒功能(增加蜂鸣器),闹铃音乐功能实验步骤1、打开Keil软件,新建一个工程文件,选择好芯片,并记得在“Options for Target 1”的Output 选项中,将Create HEX Fil选项勾起来。
2、将编写的程序保存成“.C”的形式3、编译保存好的C文件,并根据提示修改程序中的错误,直到编译成功为止4、打开proteus软件,画出实验电路图5、在89C52中,载入原来已生成的HEX文档6、按下运行键,对Proteus进行软件仿真,观察运行结果原理、结果及分析一、设计方案原理与设计特点分析电子钟总的设计模块:各个模块电路原理分析:1、DS1302时钟采集模块:1.1电路原理图:1.2 DS1302分析:首先DS1302是DALLAS公司推出的涓流充电时钟芯片。
内含有一个实时时钟/日历和31字节静态RAM通过简单的串行接口与单片机进行通信实时时钟/日历电路提供秒分时日日期月年的信息每月的天数和闰年的天数可自动调整时钟操作。
DS1302芯片广脚介绍:X1、X2为32.768KHz晶振管脚。
基于51单片机DS1302LCD1602数字时钟显示

#include <intrins.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]="I LIKE MCU!";
sbit RS=P2^0;
dispaly_string(0x00,lcd_buffer1);
dispaly_string(0x40,lcd_buffer2);
}
}
delay(5);
}
void write_a_byte_tods1302(uchar x)
{
uchar i;
for(i=0;i<8;i++)
{
IO=x&0x01;
sclk=1;
sclk=0;
x=x>>1;
}
}
uchar get_a_byte_fromds1302()
{
uchar i,b=0x00;
for(i=0;i<8;i++)
uchar lcd_buffer2[]={"TIME 00:00:00 "};
uchar datetime[7];
void delay(uchar ms)
{
uchar i;
while(ms--)
for(i=0;i<120;i++);
}
//忙检测
uchar busy()
{
uchar test;
RW=1;
{
DS1302时钟+1602显示+独立键盘控制

temp>>=1; //右移一位
}
SCLK=1;
CE=0;
SDA=0;
return temp; //返回
}
void DS1302_Write(uchar address,uchar dat)
{
uchar i;
CE=0;
}
}
if(date==3) //星期三
{
for(num=8;num<11;num++)
{
LCD_writedat(table3[num]);
delay1ms(2);
}
}
if(date==4) //星期四
uchar year=1,month=1,day=1,hour=1,min=1,sec=1;
uchar K1num=0;
//声明延时函数毫秒级
void delay1ms(uint ms);
/*******************************************************************************************
DS1302_Write(0x8c,year); //年
DS1302_Write(0x8e,0x80); //写保护开
}
void DS1302_initR()
{
sec=DS1302_Read(0x81); //读秒数据
min=DS1302_Read(0x83); //读分钟数据
/***********************************/
/* 延时程序 */
时钟DS1302在液晶1602显示程序

#include <reg52.h>#define uchar unsigned char#define uint unsigned intuchar code table[]="ziye334"; uchar code table1[]="0123456789"; uchar code table2[]="DAY-";sbit rs=P2^5;sbit rw=P2^6;sbit en=P2^7;sbit rst=P1^7;sbit io=P3^5;sbit clk=P1^6;sbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit key1=P1^0;sbit key2=P1^1;sbit key3=P1^2;sbit key4=P1^3;sbit key5=P1^4;uchar num;uchar t_sec,sec1,sec2;uchar t_min,min1,min2;uchar t_hr,hr1,hr2;uchar t_mon,mon1,mon2; uchar t_date,date1,date2; uchar t_year,year1,year2; uchar t_day,day1,flag;void input_1byte(uchar TD) {uchar i;ACC=TD;for(i=8;i>0;i--){io=ACC0;clk=1;clk=0;ACC=ACC>>1;}}uchar output_1byte(void) {uchar i;for(i=8;i>0;i--){ACC=ACC>>1;ACC7=io;clk=1;clk=0;}return(ACC);}void write_ds1302(uchar add,uchar dat) {rst=0;clk=0;rst=1;input_1byte(add);input_1byte(dat);clk=1;rst=0;}uchar read_ds1302(uchar add){uchar inf;rst=0;clk=0;input_1byte(add);inf=output_1byte();clk=1;rst=0;return(inf);}void delay(uchar z) //延时{uint x,y;for(x=110;x>0;x--)for(y=z;z>0;z--);}void write_com(uchar com) //写指令{rs=0;rw=0;en=0;P0=com;delay(5);en=1;delay(5);}void write_date(uchar date) //写数据{rs=1;rw=0;en=0;P0=date;delay(5);en=1;delay(5);en=0;}void init_lcd(){en=0;write_com(0x38); //显示write_com(0x0c); //光标不显示write_com(0x06); //指针加1,整屏不移动write_com(0x01); //清屏write_com(0x80);}void init_1302(){write_ds1302(0x8e,0x00);//关闭写保护write_ds1302(0x90,0xaa); //定义充电write_ds1302(0x80,0x30); //秒write_ds1302(0x82,0x59);//分write_ds1302(0x84,0x23);//时write_ds1302(0x86,0x31);//日write_ds1302(0x88,0x12);//月write_ds1302(0x8a,0x04);//星期write_ds1302(0x8c,0x11);//年write_ds1302(0x8e,0x80);//打开写保护}void display(){t_sec=read_ds1302(0x81);sec1=t_sec&0x0f;sec2=(t_sec>>4);t_min=read_ds1302(0x83);min1=t_min&0x0f;min2=(t_min>>4);t_hr=read_ds1302(0x85); hr1=t_hr&0x0f;hr2=(t_hr>>4);t_date=read_ds1302(0x87); date1=t_date&0x0f;date2=(t_date>>4);t_mon=read_ds1302(0x89); mon1=t_mon&0x0f;mon2=(t_mon>>4);t_day=read_ds1302(0x8b); day1=t_day&0x0f;t_year=read_ds1302(0x8d); year1=t_year&0x0f;year2=(t_year>>4);write_com(0x80+0x4e);write_date(table1[sec2]); write_com(0x80+0x4f); write_date(table1[sec1]); write_com(0x80+0x4d); write_date(':');write_com(0x80+0x4c); write_date(table1[min1]); write_com(0x80+0x4b); write_date(table1[min2]); write_com(0x80+0x4a); write_date(':');write_com(0x80+0x49); write_date(table1[hr1]); write_com(0x80+0x48); write_date(table1[hr2]);write_com(0x80+0x0f); write_date(table1[date1]); write_com(0x80+0x0e); write_date(table1[date2]);write_com(0x80+0x0d);write_date('/');write_com(0x80+0x0c);write_date(table1[mon1]);write_com(0x80+0x0b);write_date(table1[mon2]);write_com(0x80+0x0a);write_date('/');write_com(0x80+0x09);write_date(table1[year1]);write_com(0x80+0x08);write_date(table1[year2]);write_com(0x80+0x40+5);write_date(table1[day1]); }void main(){init_lcd();delay(5);init_1302();delay(5);for(num=0;num<7;num++) {write_date(table[num]);delay(10);}write_com(0x80+0x41);for(num=0;num<4;num++) {write_date(table2[num]);delay(10);}while(1){if(flag==0){display();}}}。
avrMEGA16单片机控制DS1302时钟芯片1602液晶显示

avr MEGA16单片机控制DS1302时钟芯片1602液晶显示/*程序名(program name) : 时钟芯片控制程序;概述 : 基于本程序的开发板是本人自主研发的YF-A1 AVR MEGA16单片机芯片开发板,信号辅助硬件工具有一部8通道的24兆赫兹的逻辑分析仪和一部万用表,通俗的讲,此程序就是开发板的操作系统,以MEGA16A为中央控制芯片,来控制DS1302时钟芯片,使其时间数据显示在1602液晶屏上;我用业余时间大概写了三天左右....得以完善,这次我写的比较顺利,错误只有两点,一是将写好的程序下载入芯片后,时间不走,错误在于写错了时序,用逻辑分析仪捕捉信号后,修正,KO! 二是时间可以走,但是跑秒区并非从0走到59,问题在于显示时,直接显示BCD码,并未将BCD码转换为十进制数,修正后OK!此程序还用到了定时器模块,定时每100毫秒读一次时间数据,并显示在液晶屏上;心得: 此次又突破了以往的程序量,这是我写的目前最大的一个程序,由于AVR芯片IO口控制比较复杂,所以程序语句比较多,但是此程序还有精简的空间,IO口的初始化很重要!finish time: 2014年3月7日13:16:14 作者: 肖邦;QQ: 14-545-07665 ;TEL: SORRY 保密;地址: 新疆昌吉回族自治州昌吉市;梦想: 将托尼*斯塔克成为现实;*/#include ;#include ;//此头文件用于中断服务,本程序中可以省略; typedef unsigned char uint8;typedef unsigned int uint16;void init_io(void) //====初始化所有io口;{DDRA=0XFF;PORTA=0XFF;DDRB=0XFF;PORTB=0X00;DDRC=0XFF;PORTC=0X00;DDRD=0XFF;PORTD=0X00;}//================IO口的位操作================== void rs(uint8 a) //指令/数据位/ ===========DS1302时钟位;{if(a) { PORTB|=1;>;=1;}}uint8 ds_read(void) // DS1302读取函数;{uint8 j=0,temp=0;DDRB&=~(1;>;=1;if((PINB&0X10)==0X10)//如果PB4口读到1;{temp|=0x80;//装载数据;}rs(1); //下降沿有效;delay2(); //时钟脉宽延时;rs(0);}DDRB|=1<<4; // rw引脚输出状态;PORTB|=1<<4; //rw引脚输出1;rs(0);rw(0);return (temp);}void w_1302(uint8 addr,uint8 dat) //写一个地址,写一个数据;{ds_write(addr);ds_write(dat);}void ds_wp(uint8 j) //j==1:不能够写入数据,j==0:可以写入数据;{reset_1302(); //初始化时钟,数据,片选线;ds(1);w_1302(0x8e,j?0x80:0); //三目运算;ds(0);void set_time(uint8 * dat) //设置时间;{uint8 r=0 ,t=0, ad=0x80;for(r=0;r<7;r++) //BCD码的转换.{t=dat[r]%10;dat[r]=dat[r]/10;dat[r]=(dat[r]*16)+t;}ds_wp(0);//可以写入数据;for(r=0;r<7;r++){reset_1302(); //初始化1302;ds(1); //传输使能开;ds_write(ad); //写入"写"操作地址; ds_write(dat[r]);//写入时间数据;ds(0);ad+=2;//地址加2;}ds_wp(1);//禁止写入数据;void read_time(uint8 * dat){uint8 j=0,addr=0x81 ;for(j=0;j<7;j++){reset_1302();ds(1); //传输使能开;ds_write(addr); //发送读取地址; dat[j]=ds_read(); //接收读到的数据; ds(0); //传输使能关;addr+=2; //读取地址加2;}}void timer0(void) //定时器模块函数; {TCNT0=22; //每5毫秒溢出一次;TCCR0=0X04; //256分频;}int main(void){uint8 j=0;uint8 sj[]={20,23,13,7,3,5,14}; init_io(); //初始化所有io口;init_lcd(); //初始化1602液晶屏; play(0x82,'2');delay1(3,2);play(0x83,'0');delay1(3,2);play(0x86,'-');delay1(3,2);play(0x89,'-');delay1(3,2);play(0x8d,'(');delay1(3,2);play(0x8f,')');delay1(3,2);play(0xc4,':');delay1(3,2);play(0xc7,':');delay1(3,2);buzz(); //蜂鸣器叫;delay1(3,2);set_time(sj); //设置时间;timer0(); //运行定时器;while(1){if(TIFR&0X01) //定时器溢出了;{j++;TCNT0=22;TIFR|=0X01;//溢出位置一清零;}if(j==20){j=0;read_time(sj);play(0xc9,sj[0]%16+'0'); //秒个位; play(0xc8,sj[0]/16+'0'); //秒十位;play(0xc6,sj[1]%16+'0'); //分个位; play(0xc5,sj[1]/16+'0'); //分十位; play(0xc3,sj[2]%16+'0'); //时个位; play(0xc2,sj[2]/16+'0'); //时十位;play(0x8b,sj[3]%16+'0'); //号个位; play(0x8a,sj[3]/16+'0'); //号十位; play(0x88,sj[4]%16+'0'); //月个位; play(0x87,sj[4]/16+'0'); //月十位;play(0x8e,sj[5]+'0'); //星期;play(0x85,sj[6]%16+'0'); //秒个位; play(0x84,sj[6]/16+'0'); //秒十位;}}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/******************* 说明:**************************将实时时钟数据通过LCD1602 显示基于51 单片机**************************************************/#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int uchar dis_time_buf[16]={0};//LCD1602 引脚定义// 采用8 位并行方式,DB0~DB7 连接至LCDDATA0~LCDDATA7sbit RS=P2A0;sbit RW=P2A1;sbit CS=P2A2;#define LCDDATA P0//DS1302 引脚定义sbit RST=P1A3;sbit IO=P1A2;sbit SCK=P1A1;//DS1302 地址定义#define ds1302_sec_add 0x80 // 秒数据地址#define ds1302_min_add 0x82 // 分数据地址#define ds1302_hr_add 0x84 // 时数据地址#define ds1302_date_add 0x86 // 日数据地址#define ds1302_month_add 0x88 // 月数据地址#define ds1302_day_add 0x8a // 星期数据地址#define ds1302_year_add 0x8c // 年数据地址#define ds1302_control_add 0x8e // 控制数据地址#define ds1302_charger_add 0x90#define ds1302_clkburst_add 0xbe// 初始时间定义uchar time_buf[8] = {0x20,0x10,0x06,0x01,0x23,0x59,0x55,0x02};// 初始时间2010年6月1号23 点59 分55 秒星期二// 功能:延时 1 毫秒// 入口参数:x// 出口参数:无//说明:当晶振为12M时,j<112 ;当晶振为11.0592M时,j<122void Delay_xms(uint x){uint i,j;for(i=0;i<x;i++)for(j=0;j<112;j++);// 功能:12us 延时//STC89C52为1T单片机,即1个时钟/机器周期,速度为AT89C52的12倍void Delay_xus(uint t){for(;t>0;t--){_nop_();}}//控制LCD写时序void LCD_en_write(void){CS=1;Delay_xus(20);CS=0;Delay_xus(20);}// 写指令函数void Write_Instruction(uchar command){RS=0;RW=0;CS=1;LCDDATA=command;LCD_en_write();// 写入指令数据}// 写数据函数void Write_Data(uchar Wdata){RS=1;RW=0;CS=1;LCDDATA=Wdata;LCD_en_write();// 写入数据}// 字符显示初始地址设置void LCD_SET_XY(uchar X,uchar Y){uchar address;if(Y==0) address=0x80+X;//Y=0, 表示在第一行显示,地址基数为0x80elseaddress=0xc0+X;//Y 非 0 时,表时在第二行显示,地址基数为 0xC0 Write_Instruction(address);// 写指令,设置显示初始地址}//在第X 行Y 列开始显示 Wdata 所对应的单个字符 void LCD_write_char(uchar X,uchar Y,uchar Wdata){LCD_SET_XY(X,Y)写 地址Write_Data(Wdata);// 写入当前字符并显示}// 清屏函数 void LCD_clear(void){Write_Instruction(0x01); Delay_xms(5);}// 显示屏初始化函数 void LCD_init(void){Write_Instruction(0x38); // 8bit interface,2line,5*7dotsDelay_xms(5);Write_Instruction(0x38); Delay_xms(5);Write_Instruction(0x38);Write_Instruction(0x08); //关显示,不显光标,光标不闪烁 Write_Instruction(0x01); //清屏 Delay_xms(5);//Write_Instruction(0x05); //Write_Instruction(0x06);//Write_Instruction(0x07);Delay_xms(5); // 写一字符,整屏右移 // 写一字符,整屏显示不移动// 写一字符,整屏左移//Write_Instruction(0x0B); Write_Instruction(0x0C);//Write_Instruction(0x0D); //Write_Instruction(0x0E); //Write_Instruction(0x0F); } //DS1302 初始化函数 void ds1302_init(void){Write_Instruction(0x04); // 写一字符,整屏显示不移动 // 关闭显示(不显示字符,只有背光亮) // 开显示,光标、闪烁都关闭// 开显示,不显示光标,但光标闪烁 // 开显示,显示光标,但光标不闪烁}//向DS1302写入一字节数据void ds1302_write_byte(uchar addr, uchar d){uchar i; RST=1;// 启动 DS1302 总线// 写入目标地址: addraddr = addr & 0xFE; // 最低位置零,寄存器 0 位为 0 时写,为 1 时读 for (i = 0; i < 8; i ++) {if (addr & 0x01) {IO=1;}else {IO=0;}SCK=1; //产生时钟 SCK=0;addr = addr >> 1;}// 写入数据: dfor (i = 0; i < 8; i ++) {if (d & 0x01) {IO=1;}else {IO=0;}SCK=1; // 产生时钟 SCK=0; d = d >> 1;}RST=O;〃停止 DS1302 总线}//从DS1302读出一字节数据uchar ds1302_read_byte(uchar addr) {uchar i,temp; RST=1;// 启动 DS1302 总线// 写入目标地址: addr addr = addr | 0x01;// 最低位置高,寄存器 0 位为 0 时写,为 1 时读for (i = 0; i < 8; i ++) {RST=0; SCK=0;//RST 脚置低 //SCK 脚置低if (addr & 0x01) { IO=1;}else { IO=0;}SCK=1;SCK=0;addr = addr >> 1;}// 输出数据:tempfor (i = 0; i < 8; i ++) { temp = temp >> 1; if (IO) {temp |= 0x80;}else {temp &= 0x7F; }SCK=1;SCK=0;}RST=0;//停止DS1302 总线return temp;}//向DS302写入时钟数据void ds1302_write_time(void) {ds1302_write_byte(ds1302_control_add,0x00); // 关闭写保护ds1302_write_byte(ds1302_sec_add,0x80); // 暂停时钟//ds1302_write_byte(ds1302_charger_add,0xa9); // 涓流充电ds1302_write_byte(ds1302_year_add,time_buf[1]); // 年ds1302_write_byte(ds1302_month_add,time_buf[2]); //月ds1302_write_byte(ds1302_date_add,time_buf[3]); // 日ds1302_write_byte(ds1302_hr_add,time_buf[4]); // 时ds1302_write_byte(ds1302_min_add,time_buf[5]); // 分ds1302_write_byte(ds1302_sec_add,time_buf[6]); // 秒ds1302_write_byte(ds1302_day_add,time_buf[7]); // 周ds1302_write_byte(ds1302_control_add,0x80); //打开写保护}//从DS302读出时钟数据void ds1302_read_time(void){time_buf[1]=ds1302_read_byte(ds1302_year_add); // 年time_buf[2]=ds1302_read_byte(ds1302_month_add); // 月time_buf[3]=ds1302_read_byte(ds1302_date_add); // 日time_buf[4]=ds1302_read_byte(ds1302_hr_add); // 时time_buf[5]=ds1302_read_byte(ds1302_min_add); // 分time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7f;// 秒,屏蔽秒的第7 位,避免超出59time_buf[7]=ds1302_read_byte(ds1302_day_add); // 周}void Display(void){LCD_write_char(3,0,dis_time_buf[0]+'0');LCD_write_char(4,0,dis_time_buf[1]+'0');LCD_write_char(5,0,dis_time_buf[2]+'0');LCD_write_char(6,0,dis_time_buf[3]+'0');LCD_write_char(7,0,'/');LCD_write_char(8,0,dis_time_buf[4]+'0');LCD_write_char(9,0,dis_time_buf[5]+'0');LCD_write_char(10,0,'/');LCD_write_char(11,0,dis_time_buf[6]+'0');LCD_write_char(12,0,dis_time_buf[7]+'0');LCD_write_char(15,0,dis_time_buf[14]+'0'); // 第 2 行显示LCD_write_char(3,1,dis_time_buf[8]+'0');LCD_write_char(4,1,dis_time_buf[9]+'0');LCD_write_char(5,1,':');LCD_write_char(6,1,dis_time_buf[10]+'0');LCD_write_char(7,1,dis_time_buf[11]+'0');LCD_write_char(8,1,':');LCD_write_char(9,1,dis_time_buf[12]+'0');LCD_write_char(10,1,dis_time_buf[13]+'0');}// 定时器中断函数void Timer2() interrupt 5// 定时器 2 是 5 号中断{static uchar t;TF2=0;t++;if(t==4) // 间隔200ms(50ms*4) 读取一次时间{t=0;ds1302_read_time(); // 读取时间dis_time_buf[0]=(time_buf[0]>>4); // 年dis_time_buf[1]=(time_buf[0]&0x0f);dis_time_buf[2]=(time_buf[1]>>4);dis_time_buf[3]=(time_buf[1]&0x0f);dis_time_buf[4]=(time_buf[2]>>4); // 月dis_time_buf[5]=(time_buf[2]&0x0f);dis_time_buf[6]=(time_buf[3]>>4); // 日dis_time_buf[7]=(time_buf[3]&0x0f);dis_time_buf[14]=(time_buf[7]&0x07); // 星期// 第 2 行显示dis_time_buf[8]=(time_buf[4]>>4); // 时dis_time_buf[9]=(time_buf[4]&0x0f);dis_time_buf[10]=(time_buf[5]>>4); // 分dis_time_buf[11]=(time_buf[5]&0x0f);dis_time_buf[12]=(time_buf[6]>>4); // 秒dis_time_buf[13]=(time_buf[6]&0x0f);}}// 定时器 2 初始化void Init_timer2(void){RCAP2H=0x3c;〃赋T2初始值0x3cb0,溢出20次为1秒,每次溢出时间为50ms RCAP2L=0xb0;TR2=1; //启动定时器 2ET2=1; // 打开定时器 2 中断EA=1; // 打开总中断}// 主函数void main(void){Delay_xms(50);// 等待系统稳定LCD_init(); //LCD 初始化LCD_clear(); // 清屏ds1302_init(); //DS1302 初始化Delay_xms(10);ds1302_write_time(); // 写入初始值Init_timer2(); // 定时器 2 初始化while(1){Display();}。