基于DS1302设计的数字钟原理图与PCB教程
基于DS1302设计的数字钟原理图与PCB教程
基于DS1302设计的数字钟任务一电路原理图的设计1、最小系统电路步骤一:新建设计。
双击桌面PROTEUS软件图标,打开软件,单击工具栏“File”,出现如下图所示下拉菜单。
单击“New Design”菜单,弹出如下对话框。
选择绘图模板,我们选择DEFAULT模板,单击DEFAULT图标,单击“OK”按钮。
进入原理图编辑界面,如下图所示。
步骤二:文件命名和保存。
在绘制电路原理图应当先对文件进行命名,然后保存。
单击保存图标,弹出对话框,选择文件存储路径。
如下图所示:我们把文件保存在桌面的“电路原理图”这个文件夹内。
单击“保存”按钮弹出对话框,在“文件名”编辑框中填写电路原理图名称,“基于DS1302设计的数字钟”。
如下图所示。
单击“保存”按钮,回到原理图编辑页面。
同时在文件夹“电路原理图”中出现电路原理图标,如下图所示。
步骤三:选择主控元器件。
在编辑框最左边的工具栏中选择图标,进入器件模式,然后单击图标,弹出“Pick Device”对话框,如下图所示:在Category下拉框中选择Microprocessor ICs,然后选择芯片AT89C51或AT89C51单片机,如下图所示:单击OK按钮,单片机芯片选择完成,这时在对象选择器和预览窗口中均出现了所选择的芯片AT89C52,在对象选择器单击芯片名称,如AT89C52,再把鼠标移至编辑窗口区(工作区),右击鼠标,主控芯片AT89C52就拖入了工作区。
单片机芯片选择完毕。
如下图所示:步骤四:时钟振荡电路的设计。
51单片机的18和19引脚外接2个皮法级的电容和晶振就可以构成时钟振荡电路。
按照上一步骤选择AT89C52芯片的方法一一从元器件库中选择2个30pf的电容、12M的晶振,还有一个地。
如下图所示:步骤五:复位电路设计。
单片机的9引脚外接复位电路,本系统中用按键k1、2个电阻R1、R2和电容组成,具体电路结构如下图所示:此外,还有电源电路,单片机的20引脚、40引脚分别接电源的地和电。
ds1302程序及原理图
/**************************************************;文件名:DS1302.c;功能:设置时间,然后将时间读出显示在数码管上;硬件描述:PORTD口接数码管的8个笔段; PORTA 0~2及PORTE 0~2分别接6位数码管的位;RC3接SCK,RC4接SDA,RC2接RST*/#include "pic.h"#define uchar unsigned char#define uint unsigned int#define Hidden 16__CONFIG(HS&WDTDIS&LVPDIS); //配置文件,设置为HS方式振荡,禁止看门狗,低压编程关闭ucharDispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x8 6,0x8E,0xFF};uchar BitTab[]={0xfb,0xfd,0xfe};uchar DispBuf[6];#define LSB 0x01#define WrEnDisCmd 0x8e //写允许/禁止指令代码#define WrEnDat 0x00 //写允许数据#define WrDisDat 0x80 //写禁止数据#define OscEnDisCmd 0x80 //振荡器允许/禁止指令代码#define OscEnDat 0x00 //振荡器允许数据#define OscDisDat 0x80 //振荡器禁止数据#define WrMulti 0xbe //写入多个字节的指令代码#define WrSingle 0x84 //写入单个字节的指令代码#define RdMulti 0xbf //读出多个字节的指令代码#define cClk RC3 //与时钟线相连的PIC16F877A芯片的管脚#define cDat RC4 //与数据线相连的PIC16F877A芯片的管脚#define cRst RC2 //与复位端相连的PIC16F877A芯片的管脚#define SCL_CNT TRISC3 //SCL管脚控制位#define SDA_CNT TRISC4 //SDA管脚控制位#define RST_CNT TRISC2 //RST管脚控制位void mDelay(uint DelayTime){ uint temp;for(;DelayTime>0;DelayTime--){ for(temp=0;temp<270;temp++){;}}}void interrupt Disp(){ static uchar dCount; //用作显示的计数器if(TMR1IF==1&&TMR1IE==1)//Timer 1 inetrrupt{TMR1H=-(8000/256);TMR1L=-(8000%256); //重置定时初值}PORTA|=0x07; //关前面的显示PORTE|=0X07; //关前面的显示PORTD=DispTab[DispBuf[dCount]]; //显示第i位显示缓冲区中的内容if(dCount<3)PORTE&=BitTab[dCount]; //第1~3位是由PORTE控制的elsePORTA&=BitTab[dCount-3]; //第4~6位是由PORTA的低3位控制的dCount++;if(dCount==6)dCount=0;TMR1IF=0; //清中断标志}//数码管位 1 2 3 4 5 6//引脚RE0 RE1 RE2 RA2 RA1 RA0//根据这个表,只要改变PORTA&=0xfe,即可点亮任意一个数码管//例:PORTA&=0xfd //点亮第5位数码管// PORTE&=0xfe //点亮第3位数码管void uDelay(uchar i){ for(;i>0;i--){;}}void SendDat(uchar Dat){ uchar i;for(i=0;i<8;i++){cDat=Dat&LSB; //数据端等于tmp数据的末位值Dat>>=1;cClk=1;uDelay(1);cClk=0;}}/*写入1个或者多个字节,第1个参数是相关命令#define WrMulti 0xbe //写入多个字节的指令代码#define WrSingle 0x84 //写入单个字节的指令代码第2个参数是待写入的值第3个参数是待写入数组的指针*/void WriteByte(uchar CmdDat,uchar Num,uchar *pSend){uchar i=0;SDA_CNT=0; //数据端设为输出cRst=0;uDelay(1);cRst=1;SendDat(CmdDat);for(i=0;i<Num;i++){ SendDat(*(pSend+i));}cRst=0;}/*读出字节,第一个参数是命令#define RdMulti 0xbf //读出多个字节的指令代码第2个参数是读出的字节数,第3个是指收数据数组指针*/void RecByte(uchar CmdDat,uchar Num,uchar *pRec){uchar i,j,tmp;SDA_CNT=0; //数据端设为输出cRst=0; //复位引脚为低电平uDelay(1);cClk=0;uDelay(1);cRst=1;SendDat(CmdDat); //发送命令SDA_CNT=1; //数据端设为输入for(i=0;i<Num;i++){ for(j=0;j<8;j++){ tmp>>=1;if(cDat)tmp|=0x80;cClk=1;uDelay(1);cClk=0;}*(pRec+i)=tmp;}uDelay(1);cRst=0;}/*当写保护寄存器的最高位为0时,允许数据写入寄存器。
基于DS1302的电子时钟设计
基于DS1302的电子时钟设计2012~ 2013 学年第二学期《单片机》课程设计报告题目:基于DS1302的电子时钟设计专业:电气工程系自动化班级: 10自动化(2)班姓名:费孝斌洪建勇刘云飞桑乐陆欢欢魏笑指导教师:林开司电气工程系2013年5月12日任务书摘要电子时钟主要是利用电子技术将时钟电子化、数字化,拥有时钟精确、体积小、界面友好、可扩展性能强等特点,被广泛应用于生活和工作当中。
另外,在生活和工农业生产中,也常常需要温度,这就需要电子时钟具有多功能性。
本设计主要为实现一款可正常显示时钟/日历、带有定时闹铃的多功能电子时钟。
本文对当前电子钟开发手段进行了比较和分析,最终确定了采用单片机技术实现多功能电子时钟。
本设计应用AT89C52芯片作为核心,6位LED数码管显示,使用DS1302实时时钟日历芯片完成时钟/日历的基本功能。
这种实现方法的优点是电路简单,性能可靠,实时性好,时间精确,操作简单,编程容易。
该电子时钟可以应用于一般的生活和工作中,也可通过改装,提高性能,增加新功能,从而给人们的生活和工作带来更多的方便。
关键词:电子时钟;多功能;AT89C52;时钟日历芯片目录摘要一、引言 (4)二、基于单片机的电子时钟硬件选择分析 (5)2.1主要IC芯片选择 (5)2.1.1微处理器选择 (5)2.1.2 DS1302简介 (6)2.1.3 DS1302引脚说明 (7)2.2电子时钟硬件电路设计 (8)2.2.1时钟电路设计 (9)2.2.2整点报时功能 (10)三、protel软件画原理图 (11)3.1系统工作流程图 (12)3.2原理图 (13)四、proteus软件仿真及调试 (14)4.1电路板的仿真 (15)4.2软件调试 (16)五、源程序 (17)六、参考文献 (18)引言时间是人类生活必不可少的重要元素,如果没有时间的概念,社会将不会有所发展和进步。
从古代的水漏、十二天干地支,到后来的机械钟表以及当今的石英钟,都充分显现出了时间的重要,同时也代表着科技的进步。
DS1302 数字钟设计
一、采用内部定时的程序:(注意,程序中应用的是共阴极数码管)#include<reg52.h>#define uint unsigned int#define uchar unsigned charuchar code Dis_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴极数码管编码sbit P10=P1^0;sbit P11=P1^1;sbit P12=P1^2;sbit P13=P1^3;uchar cnt,seccnt,mincnt,hourcnt,daycnt,moncnt,yearcnt;ucharseccnt1,seccnt10,mincnt1,mincnt2,hourcnt1,hourcnt10,daycnt1,daycnt10,moncnt1,moncn t10,year1,year10;void delay(unsigned char i) //延时子程序{unsigned char j;while((i--)!=0){for(j=625;j>0;j--);}}void Display(time0,time1,time2,time3){P2=0x07;P0=Dis_code[time0];delay(1);P2=0x0b;P0=Dis_code[time1];delay(1);P2=0x0d;P0=Dis_code[time2]|0x80;delay(1);P2=0x0e;P0=Dis_code[time3];delay(1);}void main(){seccnt1,seccnt10,mincnt1,mincnt10,hourcnt1,hourcnt10,daycnt1,daycnt10,moncnt1,monc nt10,yearcnt1,yearcnt10;uchar m=0,flag;yearcnt=11;moncnt=10;daycnt=12;TMOD=0X01;TH1=0X3C;TL1=0XAE;//定时器设置初值15535,定时50msTR1=1;EA=1;ET1=1;P10=0;while(1){if(cnt==20){cnt=0;seccnt++;if(seccnt==60){ seccnt=0;mincnt++;if(mincnt==60){mincnt=0;hourcnt++;if(hourcnt==24){hourcnt=0;daycnt++;if(daycnt==31){daycnt=1;moncnt++;if(moncnt==13){moncnt=1;yearcnt++;if(yearcnt==100)yearcnt=0;}}}}}}}if(P11==0)//翻页按钮{ //flag=0;delay(100);if(P11==0){m++;//页码控制if(m>2){m=0;}}}while(P11==0);if(P12==0)//调节时间的按钮{delay(100);if(P12==0){ TR1=~TR1;//按下一次停止计时,再按一次开始计时 }}while(P12==0);if(TR1==0)//如果计时停止,开始校正时间{if(P13==0){delay(100);if(P13==0){flag++;}}while(P13==0);}else flag=0;switch(m){case 0:if(flag>0){flag--;mincnt++;mincnt=mincnt%60;}seccnt1=seccnt%10;seccnt10=seccnt/10;mincnt1=mincnt%10;mincnt10=mincnt/10;Display(seccnt1,seccnt10,mincnt1,mincnt10);break;case 1:if(flag>0){flag--; hourcnt++; daycnt=(daycnt|(hourcnt/24))%30; hourcnt=hourcnt %24;}// hourcnt=(hourcnt|flag)%24;hourcnt1=hourcnt%10;hourcnt10=hourcnt/10;daycnt1=daycnt%10;daycnt10=daycnt/10;Display(hourcnt1,hourcnt10,daycnt1,daycnt10);break;case 2:if(flag>0){flag--; moncnt++; moncnt=moncnt%13;if(moncnt==0){moncnt++;yearcn t++;}}moncnt1=moncnt%10;moncnt10=moncnt/10;yearcnt1=yearcnt%10;yearcnt10=yearcnt/10;Display(moncnt1,moncnt10,yearcnt1,yearcnt10);break;}}}void Time1() interrupt 3{TH1=0X3C;TL1=0XAE;cnt++;}二、采用DS1302的程序(应用上面的电路图,数码管为共阳极型)#include <reg52.h>//定义共阳极字型码0123456789-unsigned char codedispcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};unsigned char time[]={0,0,0,0};//用来储存分秒unsigned char date[]={0,0,0,0};//用来储存日时unsigned char year[]={0,0,0,0};//用来储存年月typedef struct __SYSTEMTIME__{unsigned char Second;unsigned char Minute;unsigned char Hour;unsigned char Week;unsigned char Day;unsigned char Month;unsigned char Year;unsigned char DateString[9];unsigned char TimeString[9];}SYSTEMTIME; //定义的时间类型SYSTEMTIME time1;sbit DS1302_CLK = P1^6; //实时时钟时钟线引脚sbit DS1302_IO = P1^7; //实时时钟数据线引脚sbit DS1302_RST = P1^5; //实时时钟复位线引脚sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;sbit P10=P1^0;sbit P11=P1^1;sbit P12=P1^2;sbit P13=P1^3;sbit P14=P1^4;//#define AM(X) X//#define PM(X) (X+12) // 转成24小时制#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 DS1302_RAM(X) (0xC0+(X)*2) //用于计算DS1302_RAM 地址的宏void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数) {unsigned char i;ACC = d;for(i=8; i>0; i--){DS1302_IO = ACC0; //相当于汇编中的RRCDS1302_CLK = 1;DS1302_CLK = 0; //发一个高跳变到低的脉冲ACC = ACC >> 1;}}unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数) {unsigned char i;for(i=8; i>0; i--){ACC = ACC >>1; //相当于汇编中的RRCACC7 = DS1302_IO;DS1302_CLK = 1;DS1302_CLK = 0; //发一个高跳变到低的脉冲}return(ACC);}void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据{DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(ucAddr); // 地址,命令DS1302InputByte(ucDa); // 写1Byte数据DS1302_CLK = 1;DS1302_RST = 0; //RST 0->1->0,CLK 0->1}unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据{unsigned char ucData;DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1; //enableDS1302InputByte(ucAddr|0x01); // 地址,命令ucData = DS1302OutputByte(); // 读1Byte数据DS1302_CLK = 1; //RST 0->1->0,CLK 0->1DS1302_RST = 0;return(ucData);}void DS1302_SetProtect(bit flag) //是否写保护{if(flag)Write1302(0x8E,0x10); //WP=1,不能写入elseWrite1302(0x8E,0x00);//WP=0,可以写入}void DS1302_SetTime(unsigned char Address, unsigned char Value) // 设置时间函数{DS1302_SetProtect(0);Write1302(Address, ((Value/10)<<4 | (Value%10))); //高4位为十位,低4位为个位}void DS1302_GetTime(SYSTEMTIME *Time){unsigned char ReadValue;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);}void Initial_DS1302(void){unsigned char Second=Read1302(DS1302_SECOND);if(Second&0x80) //如果第七为1(表明没有启动), 则启动时钟DS1302_SetTime(DS1302_SECOND,0);}void delay(unsigned char i) //延时子程序{unsigned char j;while((i--)!=0){for(j=625;j>0;j--);}}/*unsigned char button_time(n,x,y) //时钟调整子程序unsigned char n,x,y;{if(P1^7==0){delay(50);if(P1^7==0){n++;if(n==x)n=0;while(P1^7==0);}}if(P1^1==0){delay(50);if(P1^1==0){if(n==0)n=y;elsen--;while(P1^1==0);}}return n;}*//*unsigned char button_date(n,x,y) //日期调整子程序unsigned char n,x,y;{if(P1^7==0){delay(50);if(P1^7==0){n++;if(n==x)n=1;while(P1^7==0);}}if(P1^1==0){delay(50);if(P1^1==0){if(n==1)n=y;elsen--;while(P1^1==0);}}return n;}*/void display1(minute10,minute1,second10,second1) //显示第一页分秒子程序//unsigned char second10,second1,minute10,minute1;{P2=0x08;P0=dispcode[second1];//显示秒的个位delay(1);P2=0x04;P0=dispcode[second10]; //显示秒的十位delay(1);P2=0x02;P0=dispcode[minute1]; //显示分的个位delay(1);P2=0x01;P0=dispcode[minute10];//显示分的十位delay(1);}void display2(data10,data1,hour10,hour1) //显示第二页天时子程序//unsigned char data10,data1,hour10,hour1;{P2=0xf8;P0=dispcode[data1];//显示天的个位delay(1);P2=0xf4;P0=dispcode[data10]; //显示天的十位delay(1);P2=0xf2;P0=dispcode[hour1]; //显示时的个位delay(1);P2=0xf1;P0=dispcode[hour10];//显示时的十位delay(1);}void display3(year10,year1,month10,month1) //显示第三页年月子程序//unsigned char year10,year1,month10,month1;{P2=0xf2;P0=dispcode[month1];//显示月的个位delay(1);P2=0xf1;P0=dispcode[month10]; //显示月的十位delay(1);P2=0xf8;P0=dispcode[year1]; //显示月的个位delay(1);P2=0xf4;P0=dispcode[year10];//显示月的十位delay(1);}void main(){unsigned char flag=0;Initial_DS1302(); //初始化DS1302这个时钟芯片,P10=0; //点亮测试灯while(1){DS1302_GetTime(&time1); //读取时间参数time[3]=(time1.Second)%10; //把秒的个位数据存入time[3]time[2]=(time1.Second)/10; //把秒的十位数据存入time[2]time[1]=(time1.Minute)%10; //把分的个位数据存入time[1]time[0]=(time1.Minute)/10; //把分的十位数据存入time[0]date[3]=(time1.Day)%10;date[2]=(time1.Day)/10;date[1]=(time1.Hour)%10;date[0]=(time1.Hour)/10;year[3]=(time1.Year)%10;year[2]=(time1.Year)/10;year[1]=(time1.Month)%10;year[0]=(time1.Month)/10;// display1(time[0],time[1],time[2],time[3]);if(P11==0){delay(50);if(P11==0){flag++;if(flag>2)//flag: 1 显示第二页日时;2 显示第三页年月0:显示第一页分秒{flag=0;}}while(P11==0);}/*if(P1^6==0) //如果按下Time Set键一下,开始显示日期,再按一下进入日期跟时钟的调节模式{delay(50);if(P1^6==0){flag++;if(flag>6){flag=0;}}while(P1^6==0);}*/switch(flag){case 0:display1(time[0],time[1],time[2],time[3]); //调用子函数display,把存入数组time 的数据给显示出来break;case 1:display2(date[0],date[1],date[2],date[3]); //调用子函数display,把存入数组date 的数据给显示出来break;case 2:display3(year[0],year[1],year[2],year[3]);break;/* case 3:time1.Month=button_date(time1.Month,13,12); //调整月DS1302_SetTime(0x88,time1.Month);display(10,10,date[2],date[3]);break;case 4:time1.Day=button_date(time1.Day,32,31); //调整日DS1302_SetTime(0x86,time1.Day);display(10,10,date[4],date[5]);break;case 5:time1.Minute=button_time(time1.Minute,60,59); //调整分DS1302_SetTime(0x82,time1.Minute);display(time[2],time[3],10,10);break;case 6:time1.Second=button_time(time1.Second,60,59); //调整秒DS1302_SetTime(0x80,time1.Second);display(10,10,time[4],time[5]);break;*/}}}。
51单片机实战指南-使用DS1302设计数字时钟
YEAR
WP
0
0
0 0000
本章内容:
1
DS1302芯片介绍
22 封装的编程思想和结构体类型
3 2
DS1302读写操作的编程实现
4
DS1302读写实战
12.2.1 封装的编程思想
➢ 封装是面向对象编程三大特性(封装、继承、多态)之一 ➢ 核心思想就是尽可能地隐藏内部的细节,只保留一些对外接
口使之与外部发生联系 ➢ 就C语言而言,封装的体现就是函数的编写(小封装)和模
} DS1302_CE = 0;
//传送数据结束
return dat;
}
12.3.2 读写函数的封装-DS1302WriteByte
/* 发送一个字节到DS1302通信总线上 */
void DS1302WriteByte(unsigned char dat)
{
unsigned char i;
for (i=0; i<8; i++)
bit 5
bit 4
bit 3
bit 2
bit 1
bit 0
1
RAM/CK A4
A3
A2
A1
A0
R/W
寄存器名
秒寄存器 分钟寄存器 小时寄存器 日期寄存器 月份寄存器 星期寄存器 年份寄存器 控制寄存器
命令字
写操作 读操作
80H
81H
82H
83H
84H
85H
86H
87H
88H
89H
8AH 8BH
8CH 8DH
12.4 DS1302读写实战-ds1302.c
void mai时间后会刷新显示
基于DS1302数字时钟电路的设计说明
基于DS1302数字时钟电路的设计摘要本设计选取串行接口时钟芯片DS1302与单片机同步通信构成数字时钟电路。
其简单的三线接口能为单片机节省大量资源,DS1302的后背电源与对后背电源进行涓细电流充电的能力保证电路断电后仍能保存时间和数据信息等。
这些优点解决了目前常用的实时时钟所无法解决的问题。
该时钟电路强大的功能和优越的性能,在很多领域的应用中,尤其是某些自动化控制、长时间无人看守的测控系统等对时钟精确性和可靠性有较高要求的场合,具有很高的使用价值。
关键词:单片机;寄存器;可编程目录第一章核心芯片简介21.1 DS1302简介21.1.1 DS1302引脚功能与部结构21.1.2 DS1302的控制字31.1.3 DS1302的复位引脚41.1.4 DS1302的数据输入输出41.1.5 DS1302的寄存器41.2 AT89S51简介51.2.1 AT89S51芯片的引脚与特点 (6)1.2.2 AT89S51的主要性能参数:101.2.3 AT89S51的新功能:10第二章方案设计与论证12第三章软硬件设计143.1 硬件电路设计123.1.1 单片机AT89S51外围电路设计123.1.2 DS1302与单片机的接口设计133.1.3 显示设计143.1.4 电源设计143.2 软件实现15结论16参考文献20词21附录17第一章核心芯片简介1.1 DS1302简介DS1302[1]是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟芯片,它可以对年、月、日、周日、时、分、秒进行计时,且具有闰年补偿功能,工作电压宽达2.5~5.5V。
时钟可工作在24小时格式或12小时(AM/PM)格式。
DS1302与单片机的接口使用同步串行通信,仅用3条线与之相连接。
可采用一次传送一个字节或突发方式一次传送多个字节的时钟信号或RAM数据。
DS1302部有一个31×8的用于临时性存放数据的RAM寄存器。
ds1302原理及管脚图
5脚
//地址、数据发送子程序
void Write1302 ( unsigned char addr,dat )
{
unsigned char i,temp;
SCLK=0;
//清零时钟总线
CE = 1;
//CE 引脚为高,逻辑控制有效
//发送地址
for ( i=8; i>0; i-- ) //循环 8 次移位
void led_disp(unsigned char *poi)
{
P0=seg[*poi % 16];
//第 1 个数码管:显示秒(个位);
delay(2);
//持续 2ms
P0=0xff;
//消影
P0=seg[*poi /16]^0x10; delay(2); P0=0xff; poi++;
//第 2 个数码管:显示秒(十位);
unsigned char i; ACC=da; for(i=8;i>0;i--) {
T_IO=ACC0; T_CLK=0;
T_CLK=1; ACC=ACC>>1; } }
/******************DS1302:读取操作(下降沿)*****************/ unsigned char read_byte(void) {
unsigned char Read1302 ( unsigned char addr ) {
unsigned char i,temp,dat1,dat2; CE=0;
SCLK=0;
CE = 1; //发送地址
for ( i=8; i>0; i-- )
//循环 8 次移位
{
SCLK = 0;
基于DS1302时钟芯片数字钟报告
课程设计报告题目:基于DS1302的数字钟报告学院:专业:电子信息工程班级:学号:指导教师:2010 年 7 月 7日摘要 (4)ABSTRACT (4)前言 (5)第一章数字钟设计的意义及任务 (6)1.1数字钟设计的意义 (6)1.2设计任务 (6)第二章系统的硬件设计和方案对比选择 (7)2.1系统设计结构图 (7)2.2系统设计方案对比选择 (7)2.2.1 MCU微处理控制器的方案对比选择 (7)2.2.2 LCD液晶显示模块的方案对比选择 (8)2.2.3 实时时钟电路的方案对比选择 (9)第三章系统的硬件设计电路及元件说明 (10)3.1MCU微控制器电路 (10)3.2LCD液晶显示电路 (12)3.3实时时钟电路 (16)3.4复位电路 (17)3.5晶振电路 (17)第四章系统的软件设计。
(18)4.1主程序 (18)第五章程序的调试 (19)5.1PROTEUS仿真 (19)5.2利用学习板进行调试 (20)5.3调试过程中出现的问题 (21)设计总结 (21)参考文献 (22)附录一系统程序: (23)附录二基于DS1302数字钟设计的原理图 (33)附录三基于DS1302数字钟设计的PCB图 (34)附录四基于DS1302数字钟设计的元件清单 . 错误!未定义书签。
基于DS1302的数字钟设计报告摘要根据AT89C52的特点和数字钟的特点,本文提出一种用单片控制DS1302利用LCD1602显示的数字钟的设计方法,同时给出软硬件电路的设计方法。
设计报告硬件电路设计和软件编程两个方面。
本系统通过AT89C52做为CPU进行总控制,利用AT89C52对DS1302进行控制,DS1302可以对年、月、日、周、日、时、分、秒进行计时,最后利用LCD1602液晶显示进行显示。
该设计实用简便能够对年、月、日、周、日、时、分、秒进行有效准确的计时及显示。
关键词:单片机 DS1302 LCD1602 数字钟Based on the design of the digital clock DS1302 reportAbstractAccording to the characteristics and the digital clock AT89C52 characteristics, this paper presents a DS1302 control by using single chip LCD1602 digital clock shows the design method and design method of software and hardware circuit is given. Design report hardware and software programming. The system through the AT89C52 as CPU for total control and utilization of DS1302 AT89C52 control, DS1302 to year, month, day, week, day, when, minutes and seconds on the clock LCD1602 LCD display show.Keywords: SCM DS1302 LCD1602 digital clock前言自古就有:“一寸光阴,一寸金”的说法。
给出DS1302的典型应用原理图
给出DS1302的典型应用原理图1. 概述本文将介绍DS1302实时时钟芯片的典型应用原理图。
DS1302是一款非易失性实时时钟芯片,在许多电子产品中被广泛使用。
它具有低功耗、精确计时等优点,适用于需要具备时间功能的电路设计。
2. DS1302原理图下面是DS1302的典型应用原理图(供参考):电源电路:--------------VCC --- 5V电源GND --- 接地--------------数据通信和控制线:---------------------------RST --- 复位信号IO --- 数据输入/输出SCLK --- 时钟信号CE --- 芯片使能信号---------------------------外部时钟电路:--------------------R --- 32.768kHz晶振C --- 晶振接地--------------------3. DS1302应用原理图解析•电源电路:DS1302芯片需要提供5V电源和接地,确保芯片正常工作。
•数据通信和控制线:RST、IO、SCLK和CE是DS1302与其他电路进行数据通信和控制的接口线。
RST用于复位芯片,IO用于数据的输入和输出,SCLK为时钟信号,CE为芯片的使能信号。
•外部时钟电路:DS1302芯片需要连接一个外部的32.768kHz晶振,以提供精确的时钟输入。
4. DS1302应用原理图使用说明1.连接电源电路:将VCC引脚连接至5V电源,将GND引脚连接至接地。
2.连接数据通信和控制线:根据实际需求,将RST、IO、SCLK和CE引脚连接至其他电路。
3.连接外部时钟电路:将R引脚连接至外部32.768kHz晶振,将C引脚接地。
5. 注意事项•在连接DS1302芯片时,务必确保正确连接电源和接地,以避免芯片损坏。
•在连接数据通信和控制线时,需要按照芯片的说明书来引脚连接,避免误接或引脚连接错误。
•外部时钟电路的连接需要注意晶振的正确极性,并确保晶振稳定工作。
基于DS1302多功能数字钟电子电工课程设计
物理与电子科学学院电子电工实验基于DS1302多功能数字时钟--万年历实验报告实验名称:基于DS1302多功能数字钟实验日期: 2014年 01 月 05 日专业:电子信息工程*名:**班级:物电 1105 班学号: *************一、设计理念:电子万年历是一个应用非常广泛地实用日常计时工具,带有显示温度,显示世纪,年,月,日,星期,时,分,秒和按键可调时间及其按键设置闹钟地功能,同时具有月末自动更新,闰年补偿功能,整点报时等多种功能.环境温度检测系统在日常生活和工业应用非常广泛,能实时采集周围地温度信息进行显示.此系统是基于STC89C52单片机设计地,包含液晶显示模块,DS1302实时时钟模块,DS18B20温度采集模块,键盘扫描模块,蜂鸣器报警模块.STC89C52作为控制核心,具有功耗低,功能强等特点,电压可选3到5V电源供电.显示模块采用1602液晶动态显示,相对数码管而言经济实用,占用空间小,对于显示数字、字母最为合适,而且与单片机连线简单,占用IO口相对较少.实时时钟芯片DS1302是一款经济实惠功能强大地较新型产品,该器件提供RTC/日历,可外加器件实现定时闹钟等功能,如果检测到主电源故障,该器件可自动切换到备用电源供电,可以保证在断电情况下精准走时,计时.温度检测显示模块采用数字式温度传感器DS18B20,该芯片具有精度高,测量范围广等优点,易与单片机连接,模块电路组成简单并同时具有温度报警功能.关键词:STC89C52,DS1302,DS18B20,1602液晶显示,电子万年历,采集设备周围环境温度、整点报时,闹钟时分通过按键设置,时、分、秒、年、月、日、星期通过按键进行调节校准……二、设计思路:核心控制体:STC89C52单片机实时时钟芯片:DS1302数字式温度传感器:DS18B20总共设有四个按键,为节约资源考虑,每个按键都有多种功能.四个按键分别标号为key1,key2,key3,key4.第一次按下key2,key3,key4都没有反应,首先按下key1键可选择指针位置,key2键为加键,key3为减键,key4键为闹钟设置清零键.操作简单,按键灵活.整点报时功能,可以按下key4键终止报警.系统设计框图:系统硬件需求介绍:STC89C52单片机一片,DS1302实时时钟芯片一个,DS18B20数字式温度传感器一个,+5V无源蜂鸣器一个,12MHZ、32KHZ晶振各一个,多个按键和开关,常用电容电阻,连接线,三极管,二极管若干,滑动变阻器一个,+3V纽扣电池一个.三、实施方案:1、单片机核心控制模块:核心控制器件选用STC89C52单片机.STC89C52单片机为40管脚双列直插芯片,它是一种高性能,低功耗地8位CMOS微处理器芯片,市场应用最多.而且价格便宜,控制方便,便于应用有4个I/O口分别为P1,P2,P3,P4.其中每一个管脚都能做独立地输入输出管脚,它地第9脚位复位管脚,接上电容和上拉电阻再带个开关构成复位电路.18,19管脚接外部晶振和两个微调电容构成外部晶振电路.单片机,复位电路,晶振,5V电源构成单片机最小系统.其中与AT89C52单片机管脚连接如下图:2、实时时钟电路模块:DS1302引脚排列:如下图引脚说明:1)1脚,Vcc2:后备电源,此设计中接+3V纽扣电池;8脚,VCC1:主电源,接+5V.在主电源关闭地情况下,也能保持时钟地连续运行.DS1302由Vcc1或Vcc2两者中地较大者供电.当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电.当Vcc2小于Vcc1时,DS1302由Vcc1供电.2)X1、X2即2脚3脚:振荡源,外接32.768kHz晶振.3)4脚END,接地端.4)5脚RST:复位/片选线,通过把RST输入驱动置高电平来启动所有地数据传送.RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据地传送手段.当RST为高电平时,所有地数据传送被初始化,允许对DS1302进行操作.如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态.上电运行时,在Vcc>2.0V之前,RST必须保持低电平.只有在SCLK为低电平时,才能将RST置为高电平.5)I/O为串行数据输入输出端(双向).6)SCLK为时钟输入端.**特别注意:5,6,7脚在硬件电路实现中,必须接上拉电阻,接+5V.3、DS18B20 工作模块: DS18B20 地温度检测与数字数据输出全集成于一个芯片之上,从而抗干扰力更强.其一个工作周期可分为两个部分,即温度检测和数据处理.DS18B20 地主要特征:全数字温度转换及输出.先进地单总线数据通信.最高 12 位分辨率,精度可达土 0.5摄氏度.12 位分辨率时地最大工作周期为 750 毫秒.可选择寄生工作方式.检测温度范围为–55°C ~+125°C (–67°F ~+257°F)内置 EEPROM,限温报警功能.64 位光刻 ROM,内置产品序列号,方便多机挂接.多样封装形式,适应不同硬件系统.4、液晶显示模块:1602字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,本设计采用16列*2行地字符型LCD1602带背光地液晶显示屏.引脚接口说明:第1脚:VSS为地电源.第2脚:VDD接5V正电源.第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K地电位器调整对比度.第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器.第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作.当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据.第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令.第7~14脚:D0~D7为8位双向数据线.第15脚:背光源正极.第16脚:背光源负极.5、蜂鸣器电路模块本实验设计中蜂鸣器用CS8050三极管驱动,蜂鸣器用5V地无源蜂鸣器,并接一个发光二极管作为指示灯,同时在负极串接一个限流电阻,数据端口接P3^7.四、Proteus仿真原理总框图:五、硬件电路实现:六、源程序:Shuzizhong.c#include <reg51.h>#include"ds18b20.h"#define uchar unsigned char#define uint unsigned intuchar shi,fen,miao,ringshi,ringfen,nian,yue,ri,week,temp,count,m。
ds1302实时时钟c程序加仿真原理图
#ifndef _1602_yejing_#define _1602_yejing_#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit lcden=P3^4;sbit lcdrs=P3^5;void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write_com(uchar com) {lcdrs=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_data(uchar date){lcdrs=1;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void write_lcd(uchar x,char *cha){ uchar length,i=0;write_com(x);for(length=0;cha[length]!=0;length++);for(i=0;i<length;i++){write_data(cha[i]);delay(5);}}void write_bcd(uchar cha){uchar ch1,ch2;ch1=(cha&0x0f)+'0';ch2=((cha>>4)&0x0f)+'0';write_data(ch2);write_data(ch1);}void write_fd(float t)//显示float型函数{ uchar s1,s2,s3,s4;uint tt;tt=t*100;s1=tt/1000;s1+=0x30;s2=tt%1000/100;s2+=0x30;s3=tt%1000%100/10;s3+=0x30;s4=tt%10;s4+=0x30;write_data(s1);write_data(s2);write_data(46);write_data(s3);write_data(s4);}void init(){lcden=0;write_com(0x38);//设置16*2显示write_com(0x0c);//设置开显示,不显示光标write_com(0x06);//写一个字符后地址指针加1write_com(0x01);//显示清0,数据指针清0}#endif/**************************************************************************THE REAL TIMER DS1302 DRIVER LIBCOPYRIGHT (c) 2010 BY ZYK.-- ALL RIGHTS RESERVED --File Name: DS1302.hAuthor: ZHANG YUAN KECreated: 2010/06/21Modified: NORevision: 1.0***************************************************************************/ #ifndef _DS1302_2010_06_21_#define _DS1302_2010_06_21_sbit SCLK = P1^6; //实时时钟时钟线引脚sbit DIO = P1^7; //实时时钟数据线引脚sbit CE = P1^5; //实时时钟复位线引脚sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;char sec,min,hour,day,mon,week,year;char *tab[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat",};void write_1302(uchar add,uchar dat){uchar i;ACC=add;CE=0;SCLK=0;CE=1;for(i=0;i<8;i++){DIO=ACC0;SCLK=1;SCLK=0;ACC>>=1;}ACC=dat;for(i=0;i<8;i++){DIO=ACC0;SCLK=1;SCLK=0;ACC>>=1;}CE=0;}uchar read_1302(uchar add){uchar i;ACC=add;CE=0;SCLK=0;CE=1;for(i=8;i>0;i--) // 为什么不能for(i=0;i<8;i++) 又为什么用我写的函数不能改时间!!!!!!!!!!!!{DIO=ACC0;SCLK=1;ACC>>=1;SCLK=0;}for(i=8;i>0;i--){ ACC>>=1;ACC7=DIO;SCLK=1;SCLK=0;}return(ACC);CE=0;}void inputbyte(uchar d) //实时时钟写入一字节(内部函数){uchar i;ACC=d;for(i=8;i>0;i--){DIO=ACC0; //相当于汇编中的RRCSCLK=1;SCLK=0;ACC>>=1;}}uchar outputbyte() //实时时钟读取一字节(内部函数){uchar i;for(i=8; i>0; i--){ACC=ACC>>1; //相当于汇编中的RRCACC7=DIO;SCLK=1;SCLK=0;}return(ACC);}void write_1302(uchar add,uchar dat) //ucAddr: DS1302地址, ucData: 要写的数据{CE=0;SCLK=0;CE=1;inputbyte(add); // 地址,命令inputbyte(dat); // 写1Byte数据CE=0;}uchar read_1302(uchar add) //读取DS1302某地址的数据{uchar dat;CE=0;SCLK=0;CE=1;inputbyte(add); // 地址,命令dat=outputbyte(); // 读1Byte数据CE=0;return(dat);}void setprotect(bit flag){if(flag)write_1302(0x8e,0x80);elsewrite_1302(0x8e,0x00);}void gettime_1302(){sec=read_1302(0x81);min=read_1302(0x83);hour=read_1302(0x85);day=read_1302(0x87);mon=read_1302(0x89);week=read_1302(0x8b);year=read_1302(0x8d);}void stop_time(bit flag) // 是否将时钟停止{unsigned char dat;dat=read_1302(0x81);setprotect(0);if(flag)write_1302(0x80, dat|0x80);elsewrite_1302(0x80, dat&0x7F);}void init_1302(){uchar second=read_1302(0x81);if(second&0x80)write_1302(0x80,0);}/****************************************************************************** **void BurstWrite1302(unsigned char *pWClock) //往DS1302写入时钟数据(多字节方式) {unsigned char i;Write1302(0x8e,0x00); // 控制命令,WP=0,写操作?DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(0xbe); // 0xbe:时钟多字节写命令for (i = 8; i>0; i--) //8Byte = 7Byte 时钟数据+ 1Byte 控制{DS1302InputByte(*pWClock); // 写1Byte数据pWClock++;}DS1302_CLK = 1;DS1302_RST = 0;}void BurstRead1302(unsigned char *pRClock) //读取DS1302时钟数据(时钟多字节方式) {unsigned char i;DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(0xbf); // 0xbf:时钟多字节读命令for (i=8; i>0; i--){*pRClock = DS1302OutputByte(); // 读1Byte数据pRClock++;}DS1302_CLK = 1;DS1302_RST = 0;}******************************************************************************* */#endif#include "1602.h"#include "DS1302.h"sbit set=P3^2;sbit jia1=P3^0;sbit jian1=P3^1;uchar bcdtoasc(uchar cha){return ((cha/16)*10+(cha%16));}uchar asctobcd(uchar cha){return ((cha/10)*16+(cha%10));}void disp_week(){ switch(week){case 1:{write_lcd(0xcd,tab[0]); break;}case 2:{write_lcd(0xcd,tab[1]); break;}case 3:{write_lcd(0xcd,tab[2]); break;}case 4:{write_lcd(0xcd,tab[3]); break;}case 5:{write_lcd(0xcd,tab[4]); break;}case 6:{write_lcd(0xcd,tab[5]); break;}case 7:{write_lcd(0xcd,tab[6]); break;}}}void disp_time(){write_com(0x87);write_bcd(year);write_com(0x8a);write_bcd(mon);write_com(0x8d);write_bcd(day);write_com(0xc5);write_bcd(hour);write_com(0xc8);write_bcd(min);write_com(0xcb);write_bcd(sec);disp_week();}void keyscan(){jia1=1;jian1=1;stop_time(1);if(set==0){delay(10);if(set==0) {delay(200); slect++;}if(slect==8) {slect=0; stop_time(0);write_com(0x0c);} }if(slect){switch(slect){ case 1:{write_com(0xcb);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);sec=read_1302(0x81);sec=sec&0x7f;sec=bcdtoasc(sec);sec+=1;if(sec==60)sec=0;sec=asctobcd(sec);write_1302(0x80,sec);write_com(0x0c);write_bcd(sec);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);sec=read_1302(0x81);sec=sec&0x7f;sec=bcdtoasc(sec);sec-=1;if(sec<0)sec=59;sec=asctobcd(sec);write_1302(0x80,sec);write_com(0x0c);write_bcd(sec);}}break;}case 2:{write_com(0xc8);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);min=read_1302(0x83);min=bcdtoasc(min);min+=1;if(min==60)min=0;min=asctobcd(min);write_1302(0x82,min);write_com(0x0c);write_bcd(min);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);min=read_1302(0x83);min=bcdtoasc(min);min-=1;if(min<0)min=59;min=asctobcd(min);write_1302(0x82,min);write_com(0x0c);write_bcd(min);}}break;}case 3:{write_com(0xc5);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);hour=read_1302(0x85);hour=bcdtoasc(hour);hour+=1;if(hour==24)hour=0;hour=asctobcd(hour);write_1302(0x84,hour);write_com(0x0c);write_bcd(hour);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);hour=read_1302(0x85);hour=bcdtoasc(hour);hour-=1;if(hour<0)hour=23;hour=asctobcd(hour);write_1302(0x84,hour);write_com(0x0c);write_bcd(hour);}}break;}case 4:{write_com(0x8d);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);mon=read_1302(0x89);year=read_1302(0x8d);day=read_1302(0x87);day=bcdtoasc(day);day+=1;year=bcdtoasc(year);if(year%4==0){if(mon==2){if(day==29)day=1;}else if(day==30)day=1;}else{ switch(mon){case 1:{if(day==32)day=1;break;}case 2:{if(day==30)day=1;break;}case 3:{if(day==32)day=1;break;}case 4:{if(day==31)day=1;break;}case 5:{if(day==32)day=1;break;}case 6:{if(day==31)day=1;break;}case 7:{if(day==32)day=1;break;}case 8:{if(day==32)day=1;break;}case 9:{if(day==31)day=1;break;}case 0x10:{if(day==32)day=1;break;}case 0x11:{if(day==31)day=1;break;}case 0x12:{if(day==32)day=1;break;}}if(mon==1|mon==3|mon==5|mon==7|mon==8|mon==0x10|mon==0x12) if(day==32)day=0; */if(mon==4|mon==6|mon==9|mon==0x11){if(day==31)day=1;}else if(day==32)day=1;}day=asctobcd(day);write_1302(0x86,day);write_com(0x0c);write_bcd(day);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);day=read_1302(0x87);day=bcdtoasc(day);day-=1;if(day<1){ mon=read_1302(0x89);year=read_1302(0x8d);switch(mon){ case 0x01: {day=31; break;}case 0x02: {day=29; break;}case 3: {day=31; break;}case 4: {day=30; break;}case 5: {day=31; break;}case 6: {day=30; break;}case 7: {day=31; break;}case 8: {day=31; break;}case 9: {day=30; break;}case 0x10: {day=31; break;}case 0x11: {day=30; break;}case 0x12: {day=31; break;}}year=bcdtoasc(year);if(year%4==0)if(mon==2)day=28;}day=asctobcd(day);write_1302(0x86,day);write_com(0x0c);write_bcd(day);}}break;}case 5:{write_com(0x8a);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);mon=read_1302(0x89);mon=bcdtoasc(mon);mon+=1;if(mon==13)mon=1;mon=asctobcd(mon);write_1302(0x88,mon);write_com(0x0c);write_bcd(mon);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);mon=bcdtoasc(mon);mon-=1;if(mon<1)mon=12;mon=asctobcd(mon);write_1302(0x88,mon);write_com(0x0c);write_bcd(mon);}}break;}case 6:{write_com(0x87);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);year=read_1302(0x8d);year=bcdtoasc(year);year+=1;if(year==100)year=0;year=asctobcd(year);write_1302(0x8c,year);write_com(0x0c);write_bcd(year);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);year=read_1302(0x8d);year=bcdtoasc(year);year-=1;if(year<0)year=99;year=asctobcd(year);write_com(0x0c);write_bcd(year);}}break;}case 7:{write_com(0xcd);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);week=read_1302(0x8b);week=bcdtoasc(week);week+=1;if(week==8)week=1;week=asctobcd(week);write_1302(0x8a,week);write_com(0x0c);disp_week();/* switch(week){case 1:{write_lcd(0xcd,tab[0]); break;}case 2:{write_lcd(0xcd,tab[1]); break;}case 3:{write_lcd(0xcd,tab[2]); break;}case 4:{write_lcd(0xcd,tab[3]); break;}case 5:{write_lcd(0xcd,tab[4]); break;}case 6:{write_lcd(0xcd,tab[5]); break;}case 7:{write_lcd(0xcd,tab[6]); break;}} */}}if(jian1==0){delay(10);if(jian1==0){ delay(200);week=read_1302(0x8b);week=bcdtoasc(week);week-=1;if(week<1)week=7;week=asctobcd(week);write_1302(0x8a,week);write_com(0x0c);disp_week();/* switch(week){case 1:{write_lcd(0xcd,tab[0]); break;}case 2:{write_lcd(0xcd,tab[1]); break;}case 3:{write_lcd(0xcd,tab[2]); break;}case 4:{write_lcd(0xcd,tab[3]); break;}case 5:{write_lcd(0xcd,tab[4]); break;}case 6:{write_lcd(0xcd,tab[5]); break;}case 7:{write_lcd(0xcd,tab[6]); break;} } */}}break; }}}}main(){init();init_1302();write_lcd(0x80,"DATE:20 - -");write_lcd(0x80+0x40,"TIME: : :");while(1){gettime_1302();set=1;if(set==0){delay(10);if(set==0){delay(200);slect++;}}while(slect)keyscan();disp_time();delay(30);}}。
单片机应用课程设计基于DS1302电子时钟的设计报告参考模板教材
单片机应用课程设计报告(2012~2013学年第2学期)设计题目:基于DS1302电子时钟的设计班别:2010级自动化1班姓名:李永兴贺孝言王永伟指导教师:***时间:2013年5月目录1 设计任务 (3)2 系统总体方案设计 (3)2.1各个模块方案论证 (3)2.1.1 时钟芯片的选择 (3)2.1.2 显示器的选择 (3)2.2总体方案设计 (4)3 硬件电路设计 (4)3.1单片机最小系统 (4)3.21302时钟电路 (5)3.3按键调时电路 (6)4 系统软件设计 (7)4.1主程序流程图 (7)4.2子程序流程图 (8)4.2.1 DS1302子程序流程图 (8)4.2.2 1602子程序流程图 (9)4.3按键校正调时程序 (9)5 实物调试 (10)5.1实物性能分析 (10)5.2总结 (13)附录1 (15)(1)系统总电路图 (15)(2)系统仿真图 (15)附录2 (17)部分程序清单 (17)1 设计任务基本要求:采用DS1302时钟芯片与单片机STC89C52相结合设计电子时钟,能够显示出实时年、月、日、时、分、秒等时间,并且可以通过按键进行时间调整。
2 系统总体方案设计2.1 各个模块方案论证2.1.1 时钟芯片的选择由于设计的是电子时钟,而单片机STC89C52自带计时功能,利用单片机实现数据的显示和调整是可行的,采用单片机计时,利用它的一个16位定时器/计数器每50ms产生一个中断信号,中断20次后产生一个秒信号,然后根据时间进制关系依次向分、时、日、星期、月、年进位。
这样可以直接用单片机的内部定时/计数器来完成电子万年历的设计。
用单片机内部的定时/计数器来制作电子万年历,虽然无须外接其他芯片,充分利用了单片机的资源,但是计时精度不够高,误差较大,掉电后所有数据将被丢失,且软件编程较为复杂。
在以单片机为核心构成的装置中,经常需要一个实时的时钟和日历,以便对一些实时发生事件记录时给予时标。
DS1302 时钟电路
时钟电路1应用:1.1需要显示时钟及日期或实现时钟控制的电子设备。
1.2本电路在HGT2110、HGT3101、HDM2100、HDM3200中成功应用。
2特性:2.1年、月、日、时、分、秒、星期的实时走时;2.2可设置为12小时制或24小时制走时;2.3日历时钟数据可读写,可启动写保护;2.4可接入3V电池,断电后由电池供电走时,电池供电通常可持续一年以上;2.5可对电池设置充电参数。
3核心部件:3.1DS1302,DIP8 或SOP8封装(推荐)。
4外围关键元件:4.132768Hz晶体振荡器;4.23V电池。
5设计注意事项:5.1晶体振荡器必须采用32768Hz,其引脚不得接入其它元件;5.2晶振引脚具有高阻抗特性,印制板漏电会导致停振。
设计时引脚应尽量短,远离周边元件或导线,并应大于2mm;5.3此器件对潮湿、低温敏感,推荐线路进行防潮处理;5.4不推荐使用大容量电容替代电池,电容引脚易与其它线路板接通造成其它线路板元件损坏。
6软件设计要点:6.1上电初始化必须设置为充电;6.2上电后对秒进行操作,可避免时钟锁定;6.3非写入数据操作后启动写保护;7原理图:7.1见DS1302.Ddb文件;8引脚说明或时序图:8.1见DS1302.pdf文件;9主要指标:10C语言例程:10.1本例在HDM3200消防电话总机中应用,CPU为ATmega32L ,工作频率为4MHz。
//************************************************************************// // 日历时钟DS1302公用变量说明 // // -------------------------------------------------------------------- // // uchar cale[7] 下标对应 0 1 2 3 4 5 6 // // year month day hour minute second week // // 年月日时分秒星期 // // write_cale(why) 将cale[]中指定的日期或时间写入dallas中 // // get_cale(why); 获得由why指定的日期或时钟,并且赋值给cale[why] // // why--指定年、周、月、日、时、分、秒中的一个, why可取year或 // // month或day或hour或minute或second或week // //************************************************************************// // -------------------------------------------------------------------- // // 充电设置 //// -------------------------------------------------------------------- // // 使用bttay_charger(uchar charge_set)函数,其中 // // charge_set: 0--不充电 4.3V时 0mA 0mA // // 1--2K充电 4.3V时 1.8mA 1.5mA // // 2--4K充电 4.3V时 0.9mA 0.8mA // // 3--8K充电 4.3V时 0.45mA 0.4mA // // 默认使用1只二极管建议使用4K电阻(0.9mA) // // -------------------------------------------------------------------- // //************************************************************************////DS1302时钟端口定义(以下端口可根据实际使用改变)-------------------------// #define SET_DS_RST SETBIT(PORTD,1) //ret=1#define CLK_DS_RST CLRBIT(PORTD,1) //ret=0#define SET_DS_SCL SETBIT(PORTB,7) //scl=1#define CLK_DS_SCL CLRBIT(PORTB,7) //scl=0#define SET_DS_DAT SETBIT(PORTB,2) //data=1#define CLK_DS_DAT CLRBIT(PORTB,2) //data=0#define IN_DS_DAT CLRBIT(DDRB,2) //data port is input#define OUT_DS_DAT SETBIT(DDRB,2) //data port is output#define CHK_DS_DAT CHKBIT(PINB,2) //get data#define dec_dallas(x) ((x/10)*16+x%10) //将10进制数转换为dallas数#define dallas_dec(x) ((x/16)*10+x%16) //将dallas数转换为10进制数//日历时钟全局变量定义---------------------------------------------------// unsigned char cale[7]; //日期缓存数据,下标用以下宏表示#define year 0 //年#define month 1 //月#define day 2 //日#define hour 3 //时#define minute 4 //分#define second 5 //秒#define week 6 //星期//**********************************************************//// DS1302日历时钟电路程序 //// ------------------------------------------------------ //// 涓流充电:read_dallas(0x91) write_dallas(0x90) //// 控制:read_dallas(0x8f) write_dallas(0x8e) //// 年:read_dallas(0x8d) write_dallas(0x8c) //// 周:read_dallas(0x8B) write_dallas(0x8a) //// 月:read_dallas(0x89) write_dallas(0x88) //// 日:read_dallas(0x87) write_dallas(0x86) //// 时:read_dallas(0x85) write_dallas(0x84) //// 分:read_dallas(0x83) write_dallas(0x82) //// 秒:read_dallas(0x81) write_dallas(0x80) //// ----------------------------------------------------- //// 内有31字节RAM 存储器,掉电失去: //// write_dallas(0xc0 - 0xfc) 偶数写 //// read_dallas(0xc1 - 0xfd) 奇数读 ////**********************************************************////**********************************************************//// 数据写入时钟芯片DS1302 //// ------------------------------------------------------ //// 功能:将数据ch写入地址为rtc_add的存储单元中 //// 输入参数:地址----uchar rtc_add //// 数据----uchar ch ////**********************************************************//void write_dallas(uchar rtc_add,uchar ch){unsigned char i;OUT_DS_DAT; //set DAT outputCLK_DS_SCL; //CLK=0SET_DS_RST; //RST=1for(i=0;i<8;i++){if(rtc_add & (0x01<<i)) SET_DS_DAT; //DAT=1else CLK_DS_DAT; //DAT=0SET_DS_SCL; //CLK=1CLK_DS_SCL; //CLK=0}for(i=0;i<8;i++){if(ch & (0x01<<i)) SET_DS_DAT; //DAT=1else CLK_DS_DAT; //DAT=0SET_DS_SCL; //CLK=1CLK_DS_SCL; //CLK=0}CLK_DS_RST; //RST=0 IN_DS_DAT; //set DAT input}g//**********************************************************//// 从时钟芯片DS1302 读出数据 //// ------------------------------------------------------ //// 功能:将数据ch写入由地址为rtc_add存储单元中读出数据 //// 输入参数:地址----uchar rtc_add //// 返回参数:数据----uchar read_dallas() ////**********************************************************// unsigned char read_dallas(unsigned char rtc_add){unsigned char i,j;j=0;OUT_DS_DAT; //set DAT outputCLK_DS_SCL; //CLK=0SET_DS_RST; //RST=1for(i=0;i<8;i++) {if(rtc_add & (0x01<<i)) SET_DS_DAT; //DAT=1else CLK_DS_DAT; //DAT=0SET_DS_SCL; //CLK=1CLK_DS_SCL; //CLK=0}IN_DS_DAT; //set DAT inputSET_DS_DAT; //DAT=1 置为上拉电阻for(i=0;i<8;i++) {if(CHK_DS_DAT) j|=0x01<<i; //j=DATSET_DS_SCL; //CLK=1CLK_DS_SCL; //CLK=0}CLK_DS_RST; //RST=0;return(j);}//**********************************************************//// 设置DS1302日期或时间 //// ------------------------------------------------------ //// 功能:将cale[]中指定的日期或时间设置到DS1302中 //// 输入参数:why--指定年、周、月、日、时、分、秒中的一个 //// 即year、week、month、day、hour、minute、second //// 以下例程将8点30分10秒写入DS1302: //// cale[hour]=8; //// cale[minute]=30; //// cale[second]=10; //// for(i=hour; i<=second; i++) write_cale(i); ////**********************************************************// void write_cale(uchar why){uchar d;write_dallas(0x8e,0x00); //关闭写保护d=dec_dallas(cale[why]);if(!why) write_dallas(0x8c,d); //写年else if(why<week) write_dallas(0x80+(10-why*2),d); //写月日时分秒else write_dallas(0x8a,d); //写星期write_dallas(0x8e,0x80); //启动写保护}//**********************************************************//// 获得DS1302指定的日期或时间 //// ------------------------------------------------------ //// 功能:将DS1302中指定的日期或时间赋给cale[why] //// 输入参数:why--指定年、周、月、日、时、分、秒中的一个 //// 即year、week、month、day、hour、minute、second //// 以下例程获取DS102当前时间,并将时间写入cale[]中: //// for(i=hour; i<=second; i++) get_cale(i); ////**********************************************************//void get_cale(uchar why){uchar d;if(!why) d=read_dallas(0x8d); //读年else if(why<week) d=read_dallas(139-(why*2)); //读月日时分秒 else d=read_dallas(0x8b); //读周cale[why]=dallas_dec(d);}//**********************************************************//// 快速获得月、日、时、分、秒 //// ------------------------------------------------------ //// 功能:获取DS1302当前月、日、时、分、秒写入cale[] ////**********************************************************//void fast_get_cale(void){uchar i;for(i=1;i<6;i++) cale[i]=dallas_dec(read_dallas(139-(i*2)));}//**********************************************************//// 获得秒 //// ------------------------------------------------------ //// 功能:直接返回当前秒 //// 返回参数:当前秒—get_second() ////**********************************************************//unsigned char get_second(void) {return dallas_dec(read_dallas(0x81));}//**********************************************************//// 电池充电设置 (应在电路上电时进行初始化设置) //// ------------------------------------------------------ //// 功能:对电池充电方式进行选择或设置 //// 输入参数:charge_set (取值见下表) //// 使用read_dallas(0x91) write_dallas(0x90) 进行设置 //// ------------------------------------------------------ //// 关于充电寄存器: //// D7 D6 D5 D4 D3 D2 D1 D0 //// -------------------------------------------------- //// | 充电设置1010 | 二极管设置|充电限流电阻| //// -------------------------------------------------- //// | 1010: 使能充电 |01: 接通1D |00:无 01:2K | //// | |10: 接通2D |10:4K 11:8K | //// -------------------------------------------------- //// ------------------------------------------------------- //// | 串联电阻 | 1只二极管 | 2只二极管 | //// charge_set: 0--不充电 4.3V时 0mA 0mA //// charge_set: 1--2K充电 4.3V时 1.8mA 1.5mA //// charge_set: 2--4K充电 4.3V时 0.9mA 0.8mA //// charge_set: 3--8K充电 4.3V时 0.45mA 0.4mA //// ------------------------------------------------------ //// 默认使用1只二极管建议使用4K电阻(0.9mA) ////**********************************************************//void bttay_charger(uchar charge_set){write_dallas(0x8e,0x00); //关闭写保护if(!charge_set) write_dallas(0x90,0x00);else write_dallas(0x90,(0xa4|charge_set));write_dallas(0x8e,0x80); //启动写保护}//主程序中应用方法Void main(void){……//时钟初始化bttay_charger(2); //电池充电初始化:0.9mA充电 write_dallas(0x8e,0x00); //关闭写保护write_dallas(0x90,(0xa4|2));write_dallas(0x8e,0x80); //启动写保护get_rili(second);if(rili[second]>59) //时钟自锁时去除锁保护{rili[second]=0;write_rili(second);}get_rili(year); //获得年fast_get_rili(); //获得年月日时分秒……while(1){……}}编著:王立新日期:2009年5月。
ds1302时钟
RST=0;
SCLK=0;
T=1;
write_byte(add);
write_byte(dat);
SCLK=1;
RST=0;
}
uchar read_1302(uchar add)//从1302读数据函数,指定读取数据来源地址
{
uchar temp;
RST=0;
SCLK=0;
RST=1;
write_byte(add);
write_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码
temp=read_byte();
SCLK=1;
RST=0;
return(temp);
}
uchar BCD_Decimal(uchar bcd)//BCD码转十进制函数,输入BCD,返回十进制
{
uchar Decimal;
Decimal=bcd>>4;
return(Decimal=Decimal*10+(bcd&=0x0F));
{
uchar gw,sw;
gw=dat%10;//取得个位数字
sw=dat/10;//取得十位数字
write_1602com(er+add);//er是头文件规定的值0x80+0x40
write_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码
write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码
delay(1);
en=1; //en置高电平,为制造下降沿做准备
delay(1);
单片机学习项目 (12) 实时时钟DS1302的原理与应用
单片机学习项目项目12-实时时钟DS1302的原理与应用一:电路原理图利用数码管显示时间,可以在电子表电路基础上连接DS1302完成,见图5-3-3所示。
6反相器74HC04为动态显示的数码管阳极驱动,中间非门省略。
图中数码管的驱动采用74HC573。
DS1302的SCLK接单片机P3.7, I/O(SDA)端口接P1.0,RST接P1.1;DS1302的X1和X2接32768Hz的标准时钟晶振。
一:程序设计主程序主用作用是调用DS1302子程序,把读取到的是时间信息通过数码管显示出来,由于采用动态显示,因此主程序中要用到定时器中断。
分页显示在定时器中断服务函数中进行。
程序清单如下:#include<reg51.h>#include”ds1302.c”uchar cp1,cp2,cp3;code uchar seven_seg[10] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};code uchar seg_bit[] ={0x01,0x02,0x04,0x08,0x10,0x20};uchar flash;bit conv;void time0_isr(void) interrupt 1 //利用中断对数码管上显示的数据进行刷新{TH0= (65536 –2000) / 256;TL0= (65536 –2000) % 256;cp1++;if(cp1>= 250)//0.5秒{cp1= 0;flash= ~flash; //产生小数点闪烁变量cp2++;if(cp2>= 5){conv= !conv;//产生交替显示变量cp2= 0;}}P0= 0xff;//消隐if(conv== 1){switch(cp3){case0:P0 = seven_seg[sec % 10];break;case1:P0 = seven_seg[sec / 10];break;case2:P0 = seven_seg[min % 10] & (0x7f | flash);break;case3:P0 = seven_seg[min / 10];break;case4:P0 = seven_seg[hour % 10] & (0x7f | flash);break;case5:P0 = seven_seg[hour / 10];break;} }else{switch(cp3){case0:P0 = seven_seg[date % 10];break;case1:P0 = seven_seg[date / 10];break;case2:P0 = seven_seg[month % 10];break;case3:P0 = seven_seg[month / 10];break;case4:P0 = seven_seg[year % 10];break;case5:P0 = seven_seg[year / 10];break;}}P2= seg_bit[cp3];cp3++;if(cp3>= 6)cp3 = 0;}void timer0_init(void) //Timer0初始化{TMOD= 0x01;TH0= (65536 –2000) / 256;TL0= (65536 –2000) % 256;TR0= 1;ET0= 1;EA = 1;}void main(void){uchari = 46;//举例,比如要调整时间,分钟设定为46分i= DEC_BCD_conv(i);timer0_init();write_ds1302_add_dat(0x8e,0x00); //写操作,可以对DS1302调整write_ds1302_add_dat(0x80,0x30); //写秒,30秒write_ds1302_add_dat(0x82,i); //写分,46分write_ds1302_add_dat(0x84,0x12); //写时,12时write_ds1302_add_dat(0x86,0x28); //写日,28日write_ds1302_add_dat(0x88,0x05); //写月,5月write_ds1302_add_dat(0x8a,0x03); //写星期,星期三write_ds1302_add_dat(0x8c,0x12); //写年,(20)12年write_ds1302_add_dat(0x8e,0x80); //写保护while(1){get_ds1302_time();}}一、DS1302驱动程序DS1302驱动程序包含以上操作函数,程序完成后存放在DS1302.c中,用于带有DS1302芯片的单片机系统中。
基于DS1302的数码管时钟电路设计
单片机与可编程器件LED数码管时钟电路采用24h计时方式,时、分、秒用六位数码管显示,其中小时、分、秒之间用小数点分开。
该电路采用AT89C52单片机和DS1302实时时钟芯片,使用5V电源进行供电,使用两个按键进行调时,调整过程中被调节的分钟或时钟将进入闪亮状态,看上去非常直观,另外,本设计还具有快速调时功能,当按键一直被按下时,便进入快速调时状态。
由于本时钟电路的计时是由芯片DS1302来完成的,计时准确 ,单片机通过串行通信来控制DS1302工作,同时进行键盘和显示的控制。
DS1302芯片介绍1.DS1302的功能及其结构DS1302芯片是美国DALLAS公司推出的低功耗实时时钟芯片,它采用串行通信方式,只需3条线便可以和单片机通信,并且其片内均含RAM,可增加系统的RAM,DS1302的时钟校准比较容易,若采用专用的晶体振荡器,几乎无须调整即可以达到国家要求的时钟误差标准。
DS1302有两个电源输入端,其中的一个用来做备用电源,这样避免了由于突然停电而造成时钟停止,因此它非常适合于长时间无人职守的监测控制系统或需经常记录某些具有特殊意义的数据及对应时间的场合。
DS1302提供秒、分、时、日、星期、月、年的信息,每月的天数和闰年的天数可自动调整,并可通过AM/PM 指示决定采用24 或12 小时格式。
DS1302串行时钟芯片主要由移位寄存器、控制逻辑、振荡器、实时时钟及31B的RAM组成。
在数据传送前,必须把RST置为高电平,且把提供地址和命令信息的8位装入到移位寄存器。
在进行单字节传送或多字节传送时,开始的8位命令字节用于指定40B(前31B RAM和9B时钟寄存器)中哪个将被访问。
在开始的8个时钟周期把命令装入移位寄存器之后,另外的时钟在读操作时输出数据,在写操作时输入数据。
DS1302的封装引脚示意图和内部结构图分别见图1和图2。
其中,X1、X2接32.768kHz 晶振,GND为地,复位线驱动至高电平,启动所有的数据传送。
DS1302电子钟制作解读
引言芯片简介2.1 DS1302简介DS1302[1]是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟芯片,它可以对年、月、日、周日、时、分、秒进行计时,且具有闰年补偿功能,工作电压宽达2.5~5.5V。
时钟可工作在24小时格式或12小时(AM/PM)格式。
DS1302与单片机的接口使用同步串行通信,仅用3条线与之相连接。
可采用一次传送一个字节或突发方式一次传送多个字节的时钟信号或RAM数据。
DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。
DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后背电源双电源引脚,同时提供了对后背电源进行涓细电流充电的能力。
2.1.1 DS1302引脚功能与内部结构DS1302的引脚功能如表1所示,外形及内部结构如图1所示[2]:表1 DS1302引脚功能表图1 DS1302管脚图及内部结构图2.1.2 DS1302的控制字DS1302的控制字节如图2所示:7 6 5 4 3 2 1 0图2 DS1302控制字节的含义控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入到DS1302中。
位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。
2.1.3 DS1302的复位引脚通过把RST 输入驱动置高电平来启动所有的数据传送。
RST 输入有两种功能:首先,RST 接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST 提供了终止单字节或多字节数据的传送手段。
当RST 为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。
如果在传送过程中置RST 为低电平,则会终止此次数据传送,并且I/O 引脚变为高阻态。
上电运行时,在Vcc≥2.5V 之前,RST 必须保持低电平。
用ds1302做时钟电路图详解
DS1302 是由美国 DALLAS 公司推出的具有涓细电流充电能力的低功 耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,且具有 闰年补偿等多种功能。 DS1302 主要性能指标: 1、DS1302 是一个实时时钟芯片,可以提供秒、分、小时、日期、 月、年等信息,并且还有软件自动调整的能力,可以通过配置 AM/PM 来决 定采用 24 小时格式还是 12 小时格式。 2、拥有 31 字节数据存储 RAM。 3、串行 I/O 通信方式,相对并行来说比较节省 IO 口的使用。 4、DS1302 的工作电压比较宽,大概是 2.0V~5.5V 都可以正常工作。
一次。 ds1302 相关文章:51 单片机 DS1302 实时时钟驱动程序
5、DS1302 这种时钟芯片功耗一般都很低,它在工作电压 2.0V 的时 候,工作电流小于 300nA。 6、DS1302 共有 8 个引脚,有两种封装形式,一种是 DIP-8 封装,芯 片宽度(不含引脚)是 300mil,一种是 SOP-8 封装,有两种宽度,一种是 150mil,一种是 208mil。 7、当供电电压是 5V 的时候,兼容标准的 TTL 电平标准,这里的意 思是,可以完美的和单片机进行通信。 8、由于 DS1302 是 DS1202 的升级版本,所以所有的功能都兼容 DS1202。此外 DS1302 有两个电源输入,一个是主电源,另外一个是备用电 源,比如可以用电池或者大电容,这样是为了保证系统掉电的情况下,我们 的时钟还会继续走。如果使用的是充电电池,还可以在正常工作时,设置充 电功能,给我们的备用电池进行充电。 DS1302 引脚功能 1 脚 VCC2 是主电源正极的引脚,2 脚 X1 和 3 脚 GND 是负极,5 脚 CE 是使能引脚,接单片机的 IO 口,6 脚 I/O 是数据传输引脚,接单片机的 IO 口,7 脚 SCLK 是通信时钟引脚,接单 片机的 IO 口,8 脚 VCC1 是备用电源引脚。 如果在 8 脚接一个 10uF 的电容,经过试验可以运行 1 分钟左右的时 间,如果大家想运行时间再长,可以加大电容的容量。电路图如下: 用 ds1302 做时钟电路图 DS1302 的电路一个重点就是时钟电路,它所使用的晶振是一个 32.768k 的晶振,晶振外部也不需要额外添加其他的电容或者电阻电路了。时 钟的精度,首先取决于晶振的精度以及晶振的引脚负载电容。如果晶振不准 或者负载电容过大过小,都会导致时钟误差过大。在这一切都搞定后,最终 一个考虑因素是晶振的温漂。随着温度的变化,晶振往往精度会发生变化, 因此,在实际的系统中,其中一种方法就是经常校对。比如我们所用的电脑 的时钟,通常我们会设置一个选项将计算机设置于 internet 时间同步。选中这 个选项后,一般可以过一段时间,我们的计算机就会和 internet 时间校准同步
用ds1302制作一个精密的电子时钟
用ds1302制作一个精密的电子时钟感想:我看视频的时候讲的是DS12CR887这块芯片,两块毕竟是不一样的,所以,我只是看了他讲怎样看时序,之后的就没再看了。
我就拿着自己下载打印的DS1302数据手册,研习,研习,再研习。
还查了书上的,网上的,源程序。
但是,你别指望着谁会把所有的东西都给你写上去。
只能作为参考。
后来,我终于写出了一个程序,可是一编译,就漏洞百出。
最主要的有两点:for循环和BCD码。
不过还好,都得到了很好的解决。
解决方案:#include#include#define uchar unsigned char#define uint unsigned intuchar data table[]="2009-01-01 Mon.";uchar data table1[]=" 00:00:00";uchar code xingqi[]="Mon. Tue. Wed. Thu. Fri. Sat. Sun.";uchar num;uchar hour,min,sec,week,day,month,year;sbit ds1302_sclk=P1^4;sbit ds1302_io=P1^5;sbit ds1302_ce=P2^2;sbit acc0=ACC^0;sbit acc7=ACC^7;sbit lcdrs=P1^7; //端口定义sbit lcdrw=P1^6;sbit lcde=P2^4;sbit le=P3^ 6;sbit led en=P2^5;sbit dkle=P3^7;void delay(uint a);void write_byte(uchar dat) //写入一个字节{uchar i;ACC=dat;for(i=8;i>0;i--){ds1302_io=acc0;ds1302_sclk=1;ds1302_sclk=0;ACC=ACC>>1;}}uchar read_byte() //读出一个字节{uchar i;for(i=8;i>0;i--){ACC=ACC>>1;acc7=ds1302_io;ds1302_sclk=1;ds1302_sclk=0;}return(ACC);}void s_write(uchar add,uchar dat)//单字节写入子函数{ds1302_ce=0;ds1302_sclk=0;ds1302_ce=1;write_byte(add);write_byte(dat);ds1302_sclk=1;ds1302_ce=0;}uchar s_read(uchar add) //单字节读出子函数{uchar temp;ds1302_ce=0;ds1302_sclk=0;ds1302_ce=1;write_byte(add);temp=read_byte();ds1302_sclk=1;ds1302_ce=0;temp=(temp/0x0a)*10+temp%0x0a;return(temp);}void set_ds1302(uchar *pClock) //设置ds1302的时间{uchar i;uchar add=0x80;EA=0;s_write(0x8e,0x00);for(i=7;i>0;i--){s_write(add,*pClock);pClock++;add+=2;}s_write(0x8e,0x80);EA=1;}void read_ds1302(uchar Curtime[]) //读取ds1302的时间{uchar i;uchar add=0x81;EA=0;for(i=7;i>0;i--){Curtime[i]=s_read(add);add+=2;}EA=1;}void write_com(uchar com) //写命令子函数{lcde=0;lcdrw=0;lcdrs=0;delay(1);lcde=1;delay(1);P0=com;delay(1);lcde=0;}void write_data(uchar dat) //写数据子函数{lcde=0;lcdrw=0;lcdrs=1;delay(1);lcde=1;delay(1);P0=dat;delay(1);lcde=0;}void init(){month=1;day=1;year=9;lcde=0; //LCD1602初始化le=0;leden=0;write_com(0x38);delay(100);write_com(0x38);delay(50);write_com(0x38);delay(10);write_com(0x08);write_com(0x01);write_com(0x0c);write_com(0x80);for(num=0;num<15;num++) //在第一行显示“ 2000-00-00 Mon.”{write_data(table[num]);}write_com(0x80+0x40);for(num=0;num<10;num++) //在第二行末尾显示“00:00:00”{write_data(table1[num]);}}void write_time(uchar add,uchar dat) //写入时间子函数{uchar shi,ge;shi=dat/16;ge=dat%16;write_com(0x80+0x40+add);write_data(0x30+shi);write_data(0x30+ge);}void write_riqi(uchar add,uchar dat) //写入日期子函数{uchar shi,ge;shi=dat/16;ge=dat%16;write_com(0x80+add);write_data(0x30+shi);write_data(0x30+ge);}void write_xingqi(uchar dat) //写入星期子函数{write_com(0x80+0x0b);switch(dat){case 1: for(num=0;num<4;num++){write_data(xingqi[num]);};break;case 2: for(num=5;num<9;num++){write_data(xingqi[num]);};break;case 3: for(num=10;num<14;num++){write_data(xingqi[num]);};break;case 4: for(num=15;num<19;num++){write_data(xingqi[num]);};break;case 5: for(num=20;num<24;num++){write_data(xingqi[num]);};break;case 6: for(num=25;num<29;num++){write_data(xingqi[num]);};break;case 7: for(num=30;num<34;num++){write_data(xingqi[num]);};break;}}void main(){init();delay(5);s_write(0x8e,0x00); //控制写入WP=0 s_write(0x90,0xa5);s_write(0x80,0x00); //秒s_write(0x82,0x20); //分s_write(0x84,0x09); //时24时制s_write(0x86,0x27); //日s_write(0x88,0x08); //月s_write(0x8a,0x04); //星期s_write(0x8c,0x09); //年 */s_write(0x8e,0x80);//控制写入WP=1;P0=0xff;while(1){sec=s_read(0x81);write_time(8,sec);write_com(0x80+0x40+9);min=s_read(0x83);write_time(5,min);write_com(0x80+0x40+6);hour=s_read(0x85);write_time(2,hour);write_com(0x80+0x40+3); week=s_read(0x8b);write_xingqi(week);write_com(0x80+0x0d);day=s_read(0x87);write_riqi(8,day);write_com(0x80+9);month=s_read(0x89);write_riqi(5,month);write_com(0x80+6);year=s_read(0x8d);write_riqi(2,year);write_com(0x80+3);}}void delay(uint a) { //延时子函数uint i,j;for(j=a;j>0;j--)for(i=250;i>0;i--) ;}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于DS1302设计的数字钟
任务一电路原理图的设计
1、最小系统电路
步骤一:新建设计。
双击桌面PROTEUS软件图标,打开软件,单击工具栏“File”,出现如下图所示下拉菜单。
单击“New Design”菜单,弹出如下对话框。
选择绘图模板,我们选择DEFAULT模板,单击DEFAULT图标,单击“OK”按钮。
进入原理图编辑界面,如下图所示。
存。
单击保存图标,弹出对话框,选择文件存储路径。
如下图所示:
我们把文件保存在桌面的“电路原理图”这个文件夹内。
单击“保存”按钮弹出对话框,在“文件名”编辑框中填写电路原理图名称,“基于DS1302设计的数字钟”。
如下图所示。
路原理图标,如下图所示。
步骤三:选择主控元器件。
在编辑框最左边的工具栏中选择图标,进入器件
模式,然后单击图标,弹出“Pick Device”对话框,如下图所示:
AT89C51单片机,如下图所示:
单击OK按钮,单片机芯片选择完成,这时在对象选择器和预览窗口中均出现了所选择的芯片AT89C52,在对象选择器单击芯片名称,如AT89C52,再把鼠标移至编辑窗口区(工作区),右击鼠标,主控芯片AT89C52就拖入了工作区。
单片机芯片选择完毕。
如下图所示:
步骤四:时钟振荡电路的设计。
51单片机的18和19引脚外接2个皮法级的电容和晶振就可以构成时钟振荡电路。
按照上一步骤选择AT89C52芯片的方法一
一从元器件库中选择2个30pf的电容、12M的晶振,还有一个地。
如下图所示:
个电阻R1、R2和电容组成,具体电路结构如下图所示:
此外,还有电源电路,单片机的20引脚、40引脚分别接电源的地和电。
另外单片机31引脚直接接地,表示单片机的CPU直接从片内的ROM中读取指令。
2、DS1302时钟电路
DS1302时钟电路主要由时钟芯片DS1302和单片的P1口相连,DS1302有8个引脚,1引脚直接接电,2、3引脚跨接一个32768HZ的晶振,4引脚接地,5、6、7引脚分别连接单片机P1口的P1^2、P1^0、P1^1。
8引脚外接备用电源,具体连接如下图所示。
3、LCD1602显示电路模块
显示电路由LCD1602和单片机的P0口和P2口组成。
LCD1602有14个引脚,1、2引脚分别接地和电;3引脚连接一个变阻器的划片端,可改变进入LCD1602液晶显示器3引脚的电压,调节显示对比度;4、5、6引脚分别连接单片机P2口的P2^0、P2^1、P2^2 ;D0-D7引脚直接和单片机的P0口连接。
当单片机的P0口作为数据输出时使用,要外接上拉电阻。
具体连接如下图所示:
4、按键输入模块
按键输入模块的4个按键通过一个4输入与门和单片机的外部中断端口相
连。
具体连接如下图所示:
把以上电路模块综合就可以得到整体电路原理图,如下图所示:
任务二PCB图的设计
一、网络表的导入
步骤一:电气规则检查
1.击菜单栏Tool中的Electrical Rule Cluck单击它,弹出对话框
2.对话框中最后一行显示ERC errors found.没有发现错误,单击Close 步骤二:元器件封装检查
1.单击工具栏中的弹出对话框
步骤三:.对话框中出现“missing”就从库中查找替代封装
1.在编辑框最左边的工具栏中选择图标,进入器件模式,然后单击图标,弹出“Pick Device”对话框,如下图所示:
2.在元器件中查找与元器件“AND_4”相类似并带有封装的元器件如下图:
记下其封装名‘DIL14’。
3.选中原理图中的U3 单击右键显示如下图:
4.单击上图中最下面的“”出现此对话框
单击图中‘Add’出现如下图所示:
在查找栏中输入刚记下的封装名‘DIL14’如下图:
选中单击右下角的‘OK’则出
现如下图:
给封装的引脚标上号:
点击按钮弹出如下对话框
单击弹出对话框
点击Yes。
步骤四:发现“NONE”就制作封装1.点击工具栏中图标弹出对话框
选择点击‘OK’.弹出对话框
点击图片右上角‘’出现如下图:
2.点击左边工具栏中图标‘’画4个焊盘;并标上序号,
3.点击左边工具栏图标‘’画方框将焊盘框起来如下图:
4.选中该图单击右键
点击上图中键显示下图
5.在此对话框中第一行空白处输入新的名字如‘KAI GUAN’,第二行空白处选‘Connectors’,第三行空白处选Surface Mount,第四行空白处选‘(None)’第五行空白处不写。
点击’OK’。
6将制作的封装添加到元器件中
a.选中元器件并单击右键选中出现下图
点击‘OK’出现下图:
点击图中‘Add’显示下图:
b.在查找栏中输入制作封装的名字‘KAI GUAN’选中它点击‘OK’或双击它出现下图:
在中下标入序号1, 2。
点击图中键弹出对话框点‘OK’,出现如下对话框:
点击上图中‘’弹出对话框
点击‘Yes’。
c.选中元器件并单击右键出现下图:
点击弹出如下图:
在上图中里标上号如‘K1或K2 …’并将上图中点掉再点击‘OK’
.
二、布局
1.在工具栏中点击图标出现界面,如下图:
选中图标点击OK进入绘制PCB板界面如下图:
2.单击工具栏中图标‘’再.点击左下角图标‘’选中‘’在PCB绘制界面画方框,如下图:
4.点击→Auto Placer,弹出对话框
点击OK出现下图:
1.点击工具栏中图标进行布线如下图:
2.穿孔
2.完成的PCB图如下。