时钟芯片DS1302代码
DS1302时钟芯片读写详解
DS1302时钟芯片读写详解2008-09-26 13:07/*DS1302读写程序(C51)*/sbit DS13CLK =P1^5; /*DS1302的SCLK脚脉冲*/ sbit DS13IO =P1^6; /*DS1302的IO脚数据*/ sbit DS13CS =P1^7; /*DS1302的RST脚片选*/ /*向DS1302写一个字节*/void _wds13byte(uchar _code){uchar i;DS13CLK =0;DS13CLK =0;for(i=0;i<8;i++){if(_code&0x01) DS13IO =1;else DS13IO =0;DS13CLK =1;DS13CLK =1;DS13CLK =0;DS13CLK =0;_code =_code >> 1;}}/*从DS1302读一个字节*/uchar _rds13byte(void){uchar i,_code;_code=0;DS13CLK =0;DS13CLK =0;DS13IO =1;for(i=0;i<8;i++){_code =_code >>1;if(DS13IO) _code =_code|0x80;DS13CLK =1;DS13CLK =1;DS13CLK =0;DS13CLK =0;}return _code;}/*读功能_code读功能命令*/uchar readds1302(uchar _code){DS13CS =0; /*关闭DS1302*/DS13CLK =0;DS13CLK =0;DS13CS =1; /*使能DS1302*/_wds13byte(_code); /*读代码*/_code=_rds13byte(); /*返回读取数字*/DS13CLK =1;DS13CS =0; /*关闭DS1302*/return _code;}/*写功能fp写的地址,_code写的内容*/void writeds1302(uchar fp,uchar _code){DS13CS =0; /*关闭DS1302*/DS13CLK =0;DS13CLK =0;DS13CS =1; /*使能DS1302*/_wds13byte(fp); /*写控制命令*/_wds13byte(_code); /*写入数据*/DS13CLK=1;DS13CS =0; /*关闭DS1302*/}/*******DS1302设置快速充电***************/void ds13_charg(void){writeds1302(0x8e,0x00); /*解除写保护*/writeds1302(0x90,0xa5); /*单二极管2K电阻充电*/writeds1302(0x8e,0x80); /*置位写保护*/};;;DS1302读写程序(汇编);;;;******************************************************************* **/T_CLK Bit P1.5 ;实时时钟时钟线引脚T_IO Bit P1.6 ;实时时钟数据线引脚T_RST Bit P1.7 ;实时时钟复位线引脚;**********************************************************;子程序名:Set1302;功能:设置DS1302 初始时间,并启动计时。
51单片机ds1302时钟
sbit runing1=runing^1;//菜单
sbit runing2=runing^2;
sbit runing3=runing^3;
sbit runing4=runing^4;
sbit runing5=runing^5;//help
sbit runing6=runing^6;//闹铃
18b20初始化
------------------------------------------------*/
bit Init_DS18B20(void)
{
bit dat=0;
DQ = 1; //DQ复位
DelayUs2x(5); //稍做延时
DQ = 0; //单片机将DQ拉低
DelayUs2x(200); //精确延时大于480us小于960us
b=ReadOneChar(); //高位
b<<=8;
t=a+b;
return(t);
}
/*------------------------------------------------
写入命令函数
------------------------------------------------*/
void WriteOneChar(uchar dat)
{
uchar i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
DelayUs2x(25);
DQ = 1;
dat>>=1;
}
DelayUs2x(25);
DS1302时钟芯片代码
******************************************************#include < reg52.h>DS1302时钟程序*******************************************************/sbit ACC_0 = ACC^0;sbit ACC_1 = ACC^1;sbit ACC_2 = ACC^2;sbit ACC_3 = ACC^3;sbit ACC_4 = ACC^4;sbit ACC_5 = ACC^5;sbit ACC_6 = ACC^6;sbit ACC_7 = ACC^7;//**************************sbit T_SCLK = P3^5; // DS1302时钟信号 7脚sbit T_DIO= P3^6; // DS1302数据信号 6脚sbit T_CE = P3^7;//**************************uchar sec,min,hour,day,month,week,year; //时间变量//**************************uchar DS1302_addr[]={0x80, //0,写入秒(Second)寄存器0x81, //1,读出秒(Second)寄存器0x82, //2,写入分(Minute)寄存器0x83, //3,读出分(Minute)寄存器0x84, //4,写入小时(Hour)寄存器0x85, //5,读出小时(Hour)寄存器0x86, //6,写入日(Day)寄存器0x87, //7,读出日(Day)寄存器0x88, //8,写入月份(Month)寄存器0x89, //9,读出月份(Month)寄存器0x8a, //10,写入周(Week)寄存器0x8b, //11,读出周(Week)寄存器0x8c, //12,写入年份(Year)寄存器0x8d, //13,读出年份(Year)寄存器0x8e, //14,写保护_寄存器0x8f //15,涓流充电} ;//***************写入一字节***********************void DS1302_Input_Byte(uchar Input) //向时钟IC写入一字节{uchar i;ACC =Input;for(i=8; i>0; i--){T_DIO = ACC_0; //相当于汇编中的 RRCT_SCLK = 1;T_SCLK = 0;ACC = ACC >> 1;}}//**************读取一字节()*************************uchar DS1302_Output_Byte(void) //从时钟IC读取一字节() {uchar i;for(i=8; i>0; i--){ACC>>=1; T_DIO= 1;ACC_7 = T_DIO;T_SCLK = 1; //相当于汇编中的 RRCT_SCLK = 0;}return(ACC);}//**************向时钟IC写数据*************************void DS1302_Write_one( uchar addr,dat ) // 写入地址、数据子程序{T_CE=0; //T_CE引脚为低,数据传送中止 T_SCLK=0; //清零时钟总线T_CE = 1; //T_CE引脚为高,逻辑控制有效 DS1302_Input_Byte(addr); // 地址,命令DS1302_Input_Byte(dat); // 写1Byte数据T_SCLK = 1;T_CE = 0;}//************从数据读取数据*****************************uchar DS1302_Read ( uchar addr ) //数据读取子程序{uchar date;T_CE=0;T_SCLK=0;T_CE = 1;DS1302_Input_Byte(addr); // 地址,命令date = DS1302_Output_Byte(); // 读1Byte数据T_SCLK = 1;T_CE = 0;return(date);}//************从数据读取数据****************************void DS1302_Write( uchar sec_w,min_w,hour_w,day_w,month_w,week_w,year_w ) {DS1302_Write_one(0x8e,0x00);DS1302_Write_one(0x80,sec_w);DS1302_Write_one(0x82,min_w);DS1302_Write_one(0x84,hour_w);DS1302_Write_one(0x86,day_w);DS1302_Write_one(0x88,month_w);DS1302_Write_one(0x8a,week_w);DS1302_Write_one(0x8c,year_w);DS1302_Write_one(0x8e,0x80);}//************从数据读取数据*****************************/*void DS1302_readtime(){sec=DS1302_Read(0x81); //读秒min=DS1302_Read(0x83); //读分hour=DS1302_Read(0x85); //读时day=DS1302_Read(0x87); //读日month=DS1302_Read(0x89); //读月year=DS1302_Read(0x8d); //读年week=DS1302_Read(0x8b); //读星期}*///************数码管DS1302显示*****************************void DS1302_SMG_display(){/* DS1302_readtime();SMG_display(6,sec%0x10);delay(1);SMG_display(5,sec/0x10);delay(1);SMG_display(4,min%0x10);delay(1);SMG_display(3,min/0x10);delay(1);SMG_display(2,hour%0x10);delay(1);SMG_display(1,hour/0x10);delay(1);*///////////////////////////////////////////// uchar i=0,a=6,*p;p=DS1302_addr;*p++;for(i=0;i<3;i++){SMG_display(a,DS1302_Read(*p)%0x10);a--;delay(0);SMG_display(a,DS1302_Read(*p)/0x10);delay(0);a--;*p++;*p++;}delay(0);}//注意:有些单片机,需将T_DIO信号脚接个上拉电阻,否会出现数据读出错误.。
DS1302时钟芯片_C语言程序设计
/*输出数据:temp*/ for (i = 0; i < 8; i ++) {
temp = temp >> 1; if (IO_R) {
temp |= 0x80; } else { temp &= 0x7F; } SCK_SET; SCK_CLR; }
RST_CLR; return temp; }
//涓流充电
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]);
/******************************************************************************
********************************************************8
程
序
*******************************************************************************
time_buf[i]=time_buf[i]+tmp*16;
}
ds1302_write_byte(ds1302_control_add,0x00);
//关闭写保护
ds1302_write_byte(ds1302_sec_add,0x80);
//暂停
ds1302_write_byte(ds1302_charger_add,0xa9);
时钟芯片ds1302程序
这是对DS1302编程最常见的操作,有很好的参考价值!我们通过本例程可以了解 DS1302时钟芯片的基本原理和使用 ,理解并掌握DS1302时钟芯片,驱动程序的编写以及实现数字字符在数码管中的显示。
#include<reg52.h>#include <intrins.h>sbit SCK=P3^6; //时钟引脚sbit SDA=P3^4; //数据端口sbit RST = P3^5;// DS1302复位sbit LS138A=P2^2;sbit LS138B=P2^3;sbit LS138C=P2^4;bit ReadRTC_Flag;//定义读DS1302标志unsigned char l_tmpdate[7]={0,0,12,15,5,3,8};//秒分时日月周年08-05-15 12:00:00 unsigned char l_tmpdisplay[8];code unsigned char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年最低位读写位code unsigned char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};code unsigned chartable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//共阴数码管 0-9 '-' '熄灭‘表/******************************************************************/ /* 函数声明 *//******************************************************************/void Write_Ds1302_byte(unsigned char temp);void Write_Ds1302( unsigned char address,unsigned char dat );unsigned char Read_Ds1302 ( unsigned char address );void Read_RTC(void);//read RTCvoid Set_RTC(void); //set RTCvoid InitTIMER0(void);//inital timer0/******************************************************************/ /* 主函数 *//******************************************************************/ void main(void){InitTIMER0(); //初始化定时器0Set_RTC(); //写入时钟值,如果使用备用电池时候,不需要没每次上电写入,此程序应该屏蔽while(1){if(ReadRTC_Flag){ReadRTC_Flag=0;Read_RTC();l_tmpdisplay[0]=l_tmpdate[2]/16; //数据的转换,因我们采用数码管0~9的显示,将数据分开l_tmpdisplay[1]=l_tmpdate[2]&0x0f;l_tmpdisplay[2]=10; //加入"-"l_tmpdisplay[3]=l_tmpdate[1]/16;l_tmpdisplay[4]=l_tmpdate[1]&0x0f;l_tmpdisplay[5]=10;l_tmpdisplay[6]=l_tmpdate[0]/16;l_tmpdisplay[7]=l_tmpdate[0]&0x0f;}}}/******************************************************************/ /* 定时器0初始化 *//******************************************************************/ void InitTIMER0(void){TMOD|=0x01;//定时器设置 16位TH0=0xef;//初始化值TL0=0xf0;ET0=1;TR0=1;EA=1;}/******************************************************************/ /* 写一个字节 *//******************************************************************/ void Write_Ds1302_Byte(unsigned char temp){unsigned char i;for (i=0;i<8;i++) //循环8次写入数据{SCK=0;SDA=temp&0x01; //每次传输低字节temp>>=1; //右移一位SCK=1;}}/******************************************************************/ /* 写入DS1302 *//******************************************************************/ void Write_Ds1302( unsigned char address,unsigned char dat ){RST=0;_nop_();SCK=0;_nop_();RST=1;_nop_(); //启动Write_Ds1302_Byte(address); //发送地址Write_Ds1302_Byte(dat); //发送数据RST=0; //恢复}/******************************************************************/ /* 读出DS1302数据 *//******************************************************************/unsigned char Read_Ds1302 ( unsigned char address ){unsigned char i,temp=0x00;RST=0;_nop_();_nop_();SCK=0;_nop_();_nop_();RST=1;_nop_();_nop_();Write_Ds1302_Byte(address);for (i=0;i<8;i++) //循环8次读取数据{if(SDA)temp|=0x80; //每次传输低字节SCK=0;temp>>=1; //右移一位_nop_();_nop_();_nop_();SCK=1;}RST=0;_nop_(); //以下为DS1302复位的稳定时间_nop_();RST=0;SCK=0;_nop_();_nop_();_nop_();_nop_();SCK=1;_nop_();_nop_();SDA=0;_nop_();_nop_();SDA=1;_nop_();_nop_();return (temp); //返回}/******************************************************************/ /* 读时钟数据 *//******************************************************************/ void Read_RTC(void) //读取日历{unsigned char i,*p;p=read_rtc_address; //地址传递for(i=0;i<7;i++) //分7次读取秒分时日月周年{l_tmpdate[i]=Read_Ds1302(*p);p++;}}/******************************************************************//* 设定时钟数据 *//******************************************************************/ void Set_RTC(void) //设定日历{unsigned char i,*p,tmp;for(i=0;i<7;i++){ //BCD处理tmp=l_tmpdate[i]/10;l_tmpdate[i]=l_tmpdate[i]%10;l_tmpdate[i]=l_tmpdate[i]+tmp*16;}Write_Ds1302(0x8E,0X00);p=write_rtc_address; //传地址for(i=0;i<7;i++) //7次写入秒分时日月周年{Write_Ds1302(*p,l_tmpdate[i]);p++;}Write_Ds1302(0x8E,0x80);}/******************************************************************/ /* 定时器中断函数 *//******************************************************************/ void tim(void) interrupt 1 using 1//中断,用于数码管扫描{static unsigned char i,num;TH0=0xf5;TL0=0xe0;P0=table[l_tmpdisplay[i]]; //查表法得到要显示数字的数码段switch(i){case 0:LS138A=0; LS138B=0; LS138C=0; break;case 1:LS138A=1; LS138B=0; LS138C=0; break;case 2:LS138A=0; LS138B=1; LS138C=0; break;case 3:LS138A=1; LS138B=1; LS138C=0; break;case 4:LS138A=0; LS138B=0; LS138C=1; break;case 5:LS138A=1; LS138B=0; LS138C=1; break;case 6:LS138A=0; LS138B=1; LS138C=1; break;case 7:LS138A=1; LS138B=1; LS138C=1; break;}i++;if(i==8){i=0;num++;if(10==num) //隔段时间读取1302的数据。
DS1302时钟程序(完整版),液晶显示
#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar table0[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; //液晶显示数字0——9代码sbit SCLK=P1^0;sbit DATA=P1^1;sbit CE=P1^2;sbit RS=P2^0;sbit RW=P2^1;sbit EN=P2^2;sbit FB=P0^7;sbit start=P1^4;sbit stop=P1^5;uchar i;/*******************延时n微秒函数*****************/void delaynus(uchar n) //n us延时函数{// uchar i;for(i=n;i>0;i--);}/*******************写数据函数*****************/void write1302(uchar add,uchar dat){CE=0;SCLK=0;CE=1;for(i=0;i<8;i++) //写入地址{DATA=add&0x01;SCLK=1;SCLK=0;add>>=1;}for(i=0;i<8;i++) //写入数据{DATA=dat&0x01;SCLK=1;SCLK=0;dat>>=1;}SCLK=1;CE=0;}/*******************读数据函数*****************/uchar read1302(uchar add){uchar dat;CE=0;SCLK=0;CE=1;for(i=8;i>0;i--) //写入地址{DATA=add&0x01;SCLK=1;SCLK=0;add>>=1;}for(i=8;i>0;i--) //读出数据/********************为神马???**************************/{dat>>=1;if(DATA==1)dat=dat|0x80;SCLK=1;SCLK=0;}SCLK=1;CE=0;return dat;}/*******************DS1302初始化函数*****************/void init1302(){uchar flag;flag=read1302(0x81);if(flag&0x80){write1302(0x8e,0x00);write1302(0x80,0x00);write1302(0x82,(((1/10)<<4)|(1%10)));write1302(0x84,(((20/10)<<4)|(20%10)));write1302(0x86,(((19/10)<<4)|(19%10)));write1302(0x88,(((7/10)<<4)|(7%10)));write1302(0x8a,((2/10)<<4)|(2%10));write1302(0x8c,(((11/10)<<4)|(11%10)));write1302(0x90,0xa5); //充电。
51单片机 ds1302万年历 时钟显示
//DS1302时钟芯片程序#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit CLK=P2^3; //定义口sbit IO=P2^4;sbit RST=P2^5;sbit ACC7=ACC^7;sbit ACC0=ACC^0;uchar a[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}, //定义数码管显示码b[8]={0x00,0x00,0x12,0x23,0x11,0x07,0x08,0xbe},//写入时钟数据,最后be突发访问c[7],s,s1,ml1,mh1,ml2,mh2,ml3,mh3; //c存放读.出时钟数据void delay(uint z) // 延时{uint i;uchar j;for(i=z;i>0;i--)for(j=200;j>0;j++);}// 显示子程序void display(uchar mh1,uchar ml1,uchar mh2,uchar ml2,uchar mh3,uchar ml3){uchar x,k,r;for(k=0;k<80;k++){for(r=0;r<8;r++){x=P2&0XF8;P2=x+r ;if(r==2||r==5){ P0=0XBF;delay(3);}//------秒-------if(r==0){P0=a[ml1] ;delay(3) ;}if(r==1){P0=a[mh1] ;delay(3) ;}//------fen---------if(r==3){P0=a[ml2] ;delay(3) ;}if(r==4){P0=a[mh2] ;delay(3) ;}//-----shi---------if(r==6){P0=a[ml3] ;delay(3) ;}if(r==7){P0=a[mh3] ;delay(3) ;}delay(3);}}}//********DS1302读写程序************void w(uchar u) //写入1位字节{uchar i;ACC = u;for(i=8; i>0; i--){IO = ACC0;CLK = 1;CLK = 0;ACC = ACC >> 1;}}uchar r(void) //读出1位字节{uchar i;for(i=8; i>0; i--){ACC = ACC >>1;ACC7 = IO;CLK = 1;CLK = 0;}return(ACC);}void W1302(uchar ucAddr, uchar ucDa){RST = 0;CLK = 0;RST = 1;w(ucAddr); // 地址,命令w(ucDa); //写1Byte数据CLK = 1;RST = 0;}void wclock(uchar *p) //写入时钟多字节数据{uchar i;// W1302(0x80,0x00); //停止时钟W1302(0x8e,0x00); // 允许写RST=0;CLK=0;RST=1;w(0xbe); //写多字节命令for(i=8;i>0;i--){w(*p); //按数组指针逐个写入,写入数据在主函数调用时指向b数组p++;}W1302(0x00,0x50); //启动定时器CLK=1;RST=0;}void rclock(uchar *p) //读出时钟多字节数据{uchar i;RST=0;CLK=0;RST=1;w(0xbf);for(i=7;i>0;i--){*p=r();p++;}CLK=1;RST=0;}void main(void){uchar mh,ml,fh,fl,sh,sl,z,v,q,e,y,t,k;wclock(b);while(1){rclock(c);mh=(c[0]&0xf0)>>4;ml=c[0]&0x0f;fh=(c[1]&0xf0)>>4;fl=c[1]&0x0f;sh=(c[2]&0xf0)>>4;sl=c[2]&0x0f;display(mh,ml,fh,fl,sh,sl);if(mh==3&&ml==0){ for(k=0;k<3;k++){z=(c[3]&0xf0)>>4;v=c[3]&0x0f;q=(c[4]&0xf0)>>4;e=c[4]&0x0f;y=(c[6]&0xf0)>>4;t=c[6]&0x0f;display(z,v,q,e,y,t);}}}}。
51 单片机 ds1302 时钟芯片
{
uchar i;
rst_1302 = 1;
clk_1302 = 1;
delay(5;
for(i=0;i<8;i++
{
dat >>= 1;
dat7 = io_1302;
clk_1302 = 1;
_nop_(;
_nop_(;
clk_1302 = 0;
_nop_(;
}
51单片机ds1302时钟芯片
#define uint unsigned int
#define uchar unsigned char
sbit lcdrs = P1^0;
sbit lcdrw = P1^1;
sbit lcden = P1^2;
sbit key0 = P2^0;//功能键,选择时分秒
sbit key1 = P2^1;//加1键
sbit key2 = P2^2;//减1键
sbit key4 = P2^4;
sbit clk_1302 = P1^5; //1302芯片位定义
sbit io_1302 = P1^6;
sbit rst_1302 = P1^7;
uchar bdata dat;
sbit dat0 = dat^0;
sbit dat7 = dat^7;
hour = uc_R1302(0x85;
write_add(0x40+10,second;
write_add(0x40+7,minute;
write_add(0x40+4,hour;
}
keyscan(;
delay(1;
}
时钟芯片DS1302 的程序(C51程序)
时钟芯片DS1302 的程序(C51程序)模块名称:DS1302.c功能:实时时钟模块时钟芯片型号:DS1302 程序设计:zhaojunjie********************************************************************* /#includesbit T_CLK = P2^7; /*实时时钟时钟线引脚 */ sbit T_IO = P1^4; /*实时时钟数据线引脚 */ sbit T_RST = P1^5; /*实时时钟复位线引脚 */sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;void RTInputByte(uchar); /* 输入 1Byte */uchar RTOutputByte(void); /* 输出?1Byte */void W1302(uchar, uchar);uchar R1302(uchar);void Set1302(uchar *); /* 设置时间 */void Bcd2asc(uchar,uchar *);void Get1302(uchar curtime[]); /* 读取1302当前时间 *//********************************************************************函数名:RTInputByte()功能:实时时钟写入一字节说明:往DS1302写入1Byte数据 (内部函数)入口参数:d 写入的数据返回值:无设计:zhaojunjie********************************************************************* **/void RTInputByte(uchar d){uchar i;ACC = d;for(i=8; i>0; i--){T_IO = ACC0; /*相当于汇编中的 RRC */T_CLK = 1;T_CLK = 0;ACC = ACC >> 1;}}/********************************************************************函数名:RTOutputByte()功能:实时时钟读取一字节说明:从DS1302读取1Byte数据 (内部函数)入口参数:无返回值:ACC设计:zhaojunjie********************************************************************* **/uchar RTOutputByte(void){uchar i;for(i=8; i>0; i--){ACC = ACC >>1; /*相当于汇编中的 RRC */ACC7 = T_IO;T_CLK = 1;T_CLK = 0;}return(ACC);}/********************************************************************函数名:W1302()功能:往DS1302写入数据说明:先写地址,后写命令/数据 (内部函数)调用:RTInputByte() , RTOutputByte()入口参数:ucAddr: DS1302地址, ucData: 要写的数据返回值:无设计:zhaojunjie********************************************************************* **/void W1302(uchar ucAddr, uchar ucDa){T_RST = 0;T_CLK = 0;T_RST = 1;RTInputByte(ucAddr); /* 地址,命令 */RTInputByte(ucDa); /* 写1Byte数据*/T_CLK = 1;T_RST = 0;}/********************************************************************函数名:R1302()功能:读取DS1302某地址的数据说明:先写地址,后读命令/数据 (内部函数)调用:RTInputByte() , RTOutputByte()入口参数:ucAddr: DS1302地址返回值:ucData :读取的数据设计:zhaojunjie********************************************************************* **/uchar R1302(uchar ucAddr){uchar ucData;T_RST = 0;T_CLK = 0;T_RST = 1;RTInputByte(ucAddr); /* 地址,命令 */ucData = RTOutputByte(); /* 读1Byte数据 */T_CLK = 1;T_RST = 0;return(ucData);}/********************************************************************函数名:BurstW1302T()功能:往DS1302写入时钟数据(多字节方式)说明:先写地址,后写命令/数据调用:RTInputByte()入口参数:pWClock: 时钟数据地址格式为: 秒分时日月星期年控制8Byte (BCD码)1B 1B 1B 1B 1B 1B 1B 1B返回值:无设计:zhaojunjie********************************************************************* **/void BurstW1302T(uchar *pWClock){uchar i;W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/T_RST = 0;T_CLK = 0;T_RST = 1;RTInputByte(0xbe); /* 0xbe:时钟多字节写命令 */for (i = 8; i>0; i--) /*8Byte = 7Byte 时钟数据 + 1Byte 控制*/{RTInputByte(*pWClock); /* 写1Byte数据*/pWClock++;}T_CLK = 1;T_RST = 0;}/********************************************************************函数名:BurstR1302T()功能:读取DS1302时钟数据说明:先写地址/命令,后读数据(时钟多字节方式)调用:RTInputByte() , RTOutputByte()入口参数:pRClock: 读取时钟数据地址格式为: 秒分时日月星期年7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B返回值:无设计:zhaojunjie********************************************************************* **/void BurstR1302T(uchar *pRClock){uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;RTInputByte(0xbf); /* 0xbf:时钟多字节读命令 */for (i=8; i>0; i--){*pRClock = RTOutputByte(); /* 读1Byte数据 */pRClock++;}T_CLK = 1;}/********************************************************************函数名:BurstW1302R()功能:往DS1302寄存器数写入数据(多字节方式)说明:先写地址,后写数据(寄存器多字节方式)调用:RTInputByte()入口参数:pWReg: 寄存器数据地址返回值:无设计:zhaojunjie********************************************************************* **/void BurstW1302R(uchar *pWReg){uchar i;W1302(0x8e,0x00); /* 控制命令,WP=0,写操作*/T_RST = 0;T_CLK = 0;T_RST = 1;RTInputByte(0xfe); /* 0xbe:时钟多字节写命令*/for (i=31; i>0; i--) /* 31Byte 寄存器数据 */{RTInputByte(*pWReg); /* 写1Byte数据*/pWReg++;}T_CLK = 1;T_RST = 0;}/********************************************************************函数名:BurstR1302R()功能:读取DS1302寄存器数据说明:先写地址,后读命令/数据(寄存器多字节方式)调用:RTInputByte() , RTOutputByte()入口参数:pRReg: 寄存器数据地址返回值:无设计:zhaojunjie********************************************************************* **/void BurstR1302R(uchar *pRReg){uchar i;T_CLK = 0;T_RST = 1;RTInputByte(0xff); /* 0xff:时钟多字节读命令 */for (i=31; i>0; i--) /*31Byte 寄存器数据 */{*pRReg = RTOutputByte(); /* 读1Byte数据 */pRReg++;}T_CLK = 1;T_RST = 0;}/********************************************************************函数名:Set1302()功能:设置初始时间说明:先写地址,后读命令/数据(寄存器多字节方式)调用:W1302()入口参数:pClock: 设置时钟数据地址格式为: 秒分时日月星期年7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B返回值:无设计:zhaojunjie********************************************************************* **/void Set1302(uchar *pClock){uchar i;uchar ucAddr = 0x80;W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/for(i =7; i>0; i--){W1302(ucAddr,*pClock); /* 秒分时日月星期年*/pClock++;ucAddr +=2;}W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/}/********************************************************************函数名:Get1302()功能:读取DS1302当前时间说明:调用:R1302()入口参数:ucCurtime: 保存当前时间地址。
电子钟(ds1302芯片)
电⼦钟(ds1302芯⽚)code//#include#include#define uchar unsigned char#define uint unsigned intuchar code table[]="87-10-26 00"; //初始化年⽉⽇uchar code table1[]="00:00:00"; //初始化时间sbit T_IO=P2^5; //位定义1302芯⽚的接⼝,数据输出端定义在P2.5引脚sbit T_RST=P2^6; //位定义1302芯⽚的接⼝,复位端⼝定义在P2.6引脚sbit T_CLK=P2^4; //位定义1302芯⽚的接⼝,时钟输出端⼝定义在P2.4引脚sbit ACC_0=ACC^0;sbit ACC_7=ACC^7;char t=0,shi,fen,miao,day,month,year,zhou,count,ReadValue;sbit lcd_rs=P3^0;sbit lcd_rw=P3^1;sbit lcd_e=P3^2;sbit key1=P1^0; //独⽴按键1 ,设置时间sbit key2=P1^1; //独⽴按键2 ,增加时间sbit key3=P1^2; //独⽴按键3 ,减少时间void delay(uint z)//延时⼤概 Z ms 晶振12MHZ{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write_cmd(uchar cmd) //向1602写命令{lcd_rs=0;lcd_rw=0;lcd_e=0;_nop_();_nop_();P0=cmd;delay(1);lcd_e=1;delay(1);lcd_e=0;}void write_data(uchar date) //向1602写数据{lcd_rs=1;lcd_rw=0;lcd_e=0;_nop_();_nop_();P0=date;delay(1);lcd_e=1;delay(1);lcd_e=0;}void write_sfm(uchar add ,uchar date) //向1602指定位置写数据(时分秒){uchar shi,ge;shi=date/10;ge=date%10;write_cmd(0x80+0x40+add);write_data(0x30+shi);write_data(0x30+ge);}void write_ymd(uchar add ,uchar date) //向1602指定位置写数据(年⽉⽇) {uchar shi,ge;shi=date/10;ge=date%10;write_cmd(0x80+add);write_data(0x30+shi);write_data(0x30+ge);}/*********************************************************************//* 实时时钟模块时钟芯⽚型号:DS1302 *//*//********************************************************************** 名称: v_RTInputByte* 说明:* 功能: 往DS1302写⼊1Byte数据* 调⽤:* 输⼊: ucDa 写⼊的数据* 返回值: ⽆***********************************************************************/void v_RTInputByte(uchar ucDa){uchar i;ACC = ucDa;for(i=8; i>0; i--){T_IO = ACC_0; /*相当于汇编中的 RRC */T_CLK = 1;T_CLK = 0;ACC = ACC >> 1;}}/********************************************************************** 名称: uchar uc_RTOutputByte* 说明:* 功能: 从DS1302读取1Byte数据* 调⽤:* 输⼊:* 返回值: ACC***********************************************************************/uchar uc_RTOutputByte(void){uchar i;for(i=8; i>0; i--){ACC = ACC >>1; /*相当于汇编中的 RRC */ACC_7 = T_IO;T_CLK = 1;T_CLK = 0;}return(ACC);}/********************************************************************** 名称: v_W1302* 说明: 先写地址,后写命令/数据* 功能: 往DS1302写⼊数据* 调⽤: v_RTInputByte()* 输⼊: ucAddr: DS1302地址, ucDa: 要写的数据* 返回值: ⽆***********************************************************************/void v_W1302(uchar ucAddr, uchar ucDa){T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); /* 地址,命令 */v_RTInputByte(ucDa); /* 写1Byte数据*/T_CLK = 1;T_RST =0;}/********************************************************************** 名称: uc_R1302* 说明: 先写地址,后读命令/数据* 功能: 读取DS1302某地址的数据* 调⽤: v_RTInputByte() , uc_RTOutputByte()* 输⼊: ucAddr: DS1302地址* 返回值: ucDa :读取的数据***********************************************************************/ uchar uc_R1302(uchar ucAddr){uchar ucDa;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); /* 地址,命令 */ucDa = uc_RTOutputByte(); /* 读1Byte数据 */T_CLK = 1;T_RST =0;return(ucDa);}/********************************************************************** 名称: v_BurstW1302T* 说明: 先写地址,后写数据(时钟多字节⽅式)* 功能: 往DS1302写⼊时钟数据(多字节⽅式)* 调⽤: v_RTInputByte()* 输⼊: pSecDa: 时钟数据地址格式为: 秒分时⽇⽉星期年控制* 8Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B 1B* 返回值: ⽆***********************************************************************/ void v_BurstW1302T(uchar *pSecDa){uchar i;v_W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xbe); /* 0xbe:时钟多字节写命令 */for (i=8;i>0;i--) /*8Byte = 7Byte 时钟数据 + 1Byte 控制*/{v_RTInputByte(*pSecDa);/* 写1Byte数据*/pSecDa++;}T_CLK = 1;T_RST =0;}/******************************************************************** ** 名称: v_BurstR1302T* 说明: 先写地址,后读命令/数据(时钟多字节⽅式)* 功能: 读取DS1302时钟数据* 调⽤: v_RTInputByte() , uc_RTOutputByte()* 输⼊: pSecDa: 时钟数据地址格式为: 秒分时⽇⽉星期年* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B* 返回值: ucDa :读取的数据***********************************************************************/ void v_BurstR1302T(uchar *pSecDa){uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xbf); /* 0xbf:时钟多字节读命令 */for (i=8; i>0; i--){*pSecDa = uc_RTOutputByte(); /* 读1Byte数据 */pSecDa++;}T_CLK = 1;T_RST =0;}/******************************************************************** ** 名称: v_BurstW1302R* 说明: 先写地址,后写数据(寄存器多字节⽅式)* 功能: 往DS1302寄存器数写⼊数据(多字节⽅式)* 调⽤: v_RTInputByte()* 输⼊: pReDa: 寄存器数据地址* 返回值: ⽆***********************************************************************/ void v_BurstW1302R(uchar *pReDa){uchar i;v_W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xfe); /* 0xbe:时钟多字节写命令 */for (i=31;i>0;i--) /*31Byte 寄存器数据 */{v_RTInputByte(*pReDa); /* 写1Byte数据*/pReDa++;}T_CLK = 1;T_RST =0;}/********************************************************************** 名称: uc_BurstR1302R* 说明: 先写地址,后读命令/数据(寄存器多字节⽅式)* 功能: 读取DS1302寄存器数据* 调⽤: v_RTInputByte() , uc_RTOutputByte()* 输⼊: pReDa: 寄存器数据地址* 返回值: ⽆***********************************************************************/void v_BurstR1302R(uchar *pReDa){uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xff); /* 0xbf:时钟多字节读命令 */for (i=31; i>0; i--) /*31Byte 寄存器数据 */{*pReDa = uc_RTOutputByte(); /* 读1Byte数据 */pReDa++;}T_CLK = 1;T_RST =0;}/********************************************************************** 名称: v_Set1302* 说明:* 功能: 设置初始时间* 调⽤: v_W1302()* 输⼊: pSecDa: 初始时间地址。
DS1302显示时钟的C程序
#include<reg52.h> //包含单片机寄存器的头文件#include<intrins.h> //包含_nop_()函数定义的头文件#define uint unsigned int#define uchar unsigned charunsigned char code digit[10]={"0123456789"}; //定义字符数组显示数字sbit SCLK=P1^0; //位定义1302芯片的接口,时钟输出端口定义在P1.0引脚sbit DATA=P1^1; //位定义1302芯片的接口,数据输出端定义在P1.1引脚sbit RST=P1^2; //位定义1302芯片的接口,复位端口定义在P1.2引脚/*****************************************************函数功能:延时若干微秒入口参数:n***************************************************/void delay(uint i){ unsigned char j;while(i--){for(j=110;j>0;j--){;}}}/*****************************************************函数功能:向1302写一个字节数据入口参数:x***************************************************/void Write1302(unsigned char dat){unsigned char i;SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备delay(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续写8个二进制位数据{DATA=dat&0x01; //取出dat的第0位数据写入1302 低位在前,高位在后delay(2); //稍微等待,使硬件做好准备SCLK=1; //上升沿写入数据delay(2); //稍微等待,使硬件做好准备SCLK=0; //重新拉低SCLK,形成脉冲dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位}}/*****************************************************函数功能:根据命令字,向1302写一个字节数据入口参数:Cmd,储存命令字;dat,储存待写的数据***************************************************/void WriteSet1302(unsigned char Cmd,unsigned char dat){RST=0; //禁止数据传递SCLK=0; //确保写数居前SCLK被拉低RST=1; //启动数据传输delay(2); //稍微等待,使硬件做好准备Write1302(Cmd); //写入命令字Write1302(dat); //写数据SCLK=1; //将时钟电平置于高电平状态RST=0; //禁止数据传递}/*****************************************************函数功能:从1302读一个字节数据入口参数:x***************************************************/ unsigned char Read1302(void){unsigned char i,dat;delay(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续读8个二进制位数据{ dat>>=1;if(DATA==1) //如果读出的数据是1dat|=0x80; //将1取出,写在dat的最高位SCLK=1; //将SCLK置于高电平,为下降沿读出delay(2); //稍微等待SCLK=0; //拉低SCLK,形成脉冲下降沿delay(2); //稍微等待}return dat; //将读出的数据返回}/*****************************************************函数功能:根据命令字,从1302读取一个字节数据入口参数:Cmd***************************************************/ unsigned char ReadSet1302(unsigned char Cmd){unsigned char dat;RST=0; //拉低RSTSCLK=0; //确保写数居前SCLK被拉低RST=1; //启动数据传输Write1302(Cmd); //写入命令字dat=Read1302(); //读出数据SCLK=1; //将时钟电平置于已知状态RST=0; //禁止数据传递return dat; //将读出的数据返回}/*****************************************************函数功能:1302进行初始化设置***************************************************/void Init_DS1302(void){unsigned char flag;flag= ReadSet1302(0x81);if(flag&0x80) { //判断时钟芯片是否关闭WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令WriteSet1302(0x80,((55/10)<<4|(55%10))); //根据写秒寄存器命令字,写入秒的初始值WriteSet1302(0x82,((59/10)<<4|(59%10))); //根据写分寄存器命令字,写入分的初始值WriteSet1302(0x84,((23/10)<<4|(23%10))); //根据写小时寄存器命令字,写入小时的初始值WriteSet1302(0x86,((18/10)<<4|(18%10))); //根据写日寄存器命令字,写入日的初始值WriteSet1302(0x88,((6/10)<<4|(6%10))); //根据写月寄存器命令字,写入月的初始值WriteSet1302(0x8c,((9/10)<<4|(9%10))); //根据写年寄存器命令字,写入年的初始值WriteSet1302(0x90,0xa5); //打开充电功能选择2K电阻充电方式WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令}}//如果不想每次都初始化时间,也就是掉电后还想让时钟继续走时的话就用上面的语句/*--------------------这是每次都初始化的语句-----------------*//*WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令WriteSet1302(0x80,((55/10)<<4|(55%10))); //根据写秒寄存器命令字,写入秒的初始值WriteSet1302(0x82,((59/10)<<4|(59%10))); //根据写分寄存器命令字,写入分的初始值WriteSet1302(0x84,((23/10)<<4|(23%10))); //根据写小时寄存器命令字,写入小时的初始值WriteSet1302(0x86,((18/10)<<4|(18%10))); //根据写日寄存器命令字,写入日的初始值WriteSet1302(0x88,((6/10)<<4|(6%10))); //根据写月寄存器命令字,写入月的初始值WriteSet1302(0x8c,((9/10)<<4|(9%10))); //根据写年寄存器命令字,写入年的初始值WriteSet1302(0x90,0xa5); //打开充电功能选择2K电阻充电方式WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令*//****************************************************************************** *以下是对液晶模块的操作程序******************************************************************************* /sbit RS=P2^0; //寄存器选择位,将RS位定义为P2.0引脚sbit RW=P2^1; //读写选择位,将RW位定义为P2.1引脚sbit E=P2^2; //使能信号位,将E位定义为P2.2引脚sbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚/*****************************************************函数功能:判断液晶模块的忙碌状态返回值:result。
DS1302时钟芯片完整C语言应用程序_可直接调用
}
for(i=0;i<8;i++)
{
DS1302_CLK=0;
DS1302_DATA=DDATA&0X01;
DS1302_CLK=1;
DDATA=DDATA>>1; //传送数据。
}
DS1302_CLK=0;
DS1302_RST=0;
//使能端关闭。
}
/************************************************************/
uchar DS1302_Clock[8]={0x01,0x01,0x00,0x06,0x09,0x02,0x11,0}; //时钟缓存。秒、分、时、
日、月、周、年、控制寄存器。
void DS1302_Write(uchar CDATA,uchar DDATA); //写数据。
uchar DS1302_Read(uchar CDATA); //读数据。
#endif
/********DS1302_WriteClock()***********************************
函数名 :DS1302_WriteClock() 突发方式,写入所有时钟数据。
入口参数:无
出口参数:无
**************************************************************/
void DS1302_Write(uchar CDATA,uchar DDATA)
{
uchar i;
DS1302_RST=1;
//使能端有效,开始传送数据。
for(i=0;i<8;i++)
ds1302驱动代码
#ifndef __DS1302_H_#define __DS1302_H_/********************************************************************/ sbit SCK=P1^7;sbit SD=P2^3;sbit RST=P1^3;/********************************************************************/ /*复位脚*/#define RST_CLR RST=0 /*电平置低*/#define RST_SET RST=1 /*电平置高*//*双向数据*/#define SDA_CLR SD=0 /*电平置低*/#define SDA_SET SD=1 /*电平置高*/#define SDA_R S D /*电平读取*//*时钟信号*/#define SCK_CLR SCK=0 /*时钟信号*/#define SCK_SET SCK=1 /*电平置高*//********************************************************************/ /*单字节写入一字节数据*/void Write_Ds1302_Byte(unsigned char dat){unsigned char i;SCK = 0;for (i=0;i<8;i++){if (dat & 0x01) // 等价于if((addr & 0x01) ==1){SDA_SET; //#define SDA_SET SDA=1 /*电平置高*/}else{SDA_CLR; //#define SDA_CLR SDA=0 /*电平置低*/}SCK_SET;SCK_CLR;dat = dat >> 1;}}/********************************************************************/ /*单字节读出一字节数据*/unsigned char Read_Ds1302_Byte(void){unsigned char i, dat=0;for (i=0;i<8;i++){dat = dat >> 1;if (SDA_R) //等价于if(SDA_R==1) #define SDA_R SDA /*电平读取*/{dat |= 0x80;}else{dat &= 0x7F;}SCK_SET;SCK_CLR;}return dat;}/********************************************************************//*向DS1302 单字节写入一字节数据*/void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat){RST_CLR; /*RST脚置低,实现DS1302的初始化*/SCK_CLR; /*SCK脚置低,实现DS1302的初始化*/RST_SET; /*启动DS1302总线,RST=1电平置高*/addr = addr & 0xFE;Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是写操作,写之前将最低位置零*/Write_Ds1302_Byte(dat); /*写入数据:dat*/RST_CLR; /*停止DS1302总线*/SDA_CLR;}/********************************************************************//*从DS1302单字节读出一字节数据*/unsigned char Ds1302_Single_Byte_Read(unsigned char addr){unsigned char temp;RST_CLR; /*RST脚置低,实现DS1302的初始化*/SCK_CLR; /*SCK脚置低,实现DS1302的初始化*/RST_SET; /*启动DS1302总线,RST=1电平置高*/addr = addr | 0x01;Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是读操作,写之前将最低位置高*/ temp=Read_Ds1302_Byte(); /*从DS1302中读出一个字节的数据*/RST_CLR; /*停止DS1302总线*/SDA_CLR;return temp;}//时钟初始化void DS1302_Init(){Ds1302_Single_Byte_Write(0x8e,0x00);Ds1302_Single_Byte_Write(0x84,0x08);Ds1302_Single_Byte_Write(0x82,0x30);Ds1302_Single_Byte_Write(0x80,0x00);Ds1302_Single_Byte_Write(0x8e,0x80);}#endif。
DS1302时钟芯片C51源代码源程序
DS1302时钟芯片C51源代码源程序DS1302--- 51C语言代码,头文件与对应C代码已分离开,直接可用(自己写,绝对可用。
)其中星期几能直接由日期按公式推算出来,time.week=(time.year/100)/4-2*(time.year/100)+(time.year%100)+(time.year%100)/4+26*(tim e.month+1)/10 +time.day-1;(详情请搜:蔡乐公式)///////////////////////////////////////////////////////////////DS1302头文件:#ifndef _ds1302_h_#define _ds1302_h_#define uchar unsigned char#define uint unsigned int#define ulong unsigned long#define u32 unsigned long intsbit sdinn = P2^6;sbit sclkk = P2^5;sbit cee = P2^7;#define second_w 0x80#define second_r 0x81#define minute_w 0x82#define minute_r 0x83#define hour_w 0x84#define hour_r 0x85#define day_w 0x86#define day_r 0x87#define month_w 0x88#define month_r 0x89#define year_w 0x8c#define year_r 0x8d#define week_w 0x8a#define week_r 0x8b#define protect_w 0xc0#define protect_r 0xc1#define clock_base_w 0xc2#define clock_base_r 0xc3#define clock_state_w 0xcc#define clock_state_r 0xcd#define D_protect 0x77typedef struct{uint year;uint month;uint day;uint hour;uint minute;uint second;uint week;} Time_info;void DS1302_Writebyte(uchar dat);void time_write2DS1302(Time_info Time);void time_read_from_DS1302(Time_info *Time);uchar DS1302_Readbyte();void DS1302Write(uchar cmd, uchar dat);uchar DS1302Read(uchar cmd);void Init_DS1302(void);void display_date(unsigned char X,unsigned char Y,Time_info Read_T); void writeDate2DS1302(Time_info Time);void time_HMS2DS1302(Time_info Time);void Alarm_respond();void sendtime2computer();#endif///////////////////////////////////////////////////////////DS1302-C代码:#include "option.h"xdata uchar trans_buf;extern xdata uchar Date_Index;extern xdata uchar Time_Index;extern xdata uchar Write_date_buff[15];extern xdata uchar Alarm_buff[7];extern xdata uchar Alarm_arrive;extern xdata uchar arriveminute;extern xdata uchar Alarm_state;extern xdata Time_info Read_Time;xdata uchar tiao_buff[30];xdata uint hour,minute,second;xdata uchar old_second=250;void delay(unsigned long int i){while(i--);}void time_write2DS1302(Time_info Time)DS1302Write(0x8e,0x00);//写保护关trans_buf = ((Time.year%100/10)<<4)+((Time.year%10)&0X0F); // 写入年DS1302Write(year_w, trans_buf);trans_buf = (((Time.month%100/10)<<4)&0x10) + ((Time.month%10)&0X0F); //写入月DS1302Write(month_w, trans_buf);trans_buf = (((Time.day%100/10)<<4)&0x30) + ((Time.day%10)&0X0F);//写入日DS1302Write(day_w, trans_buf);trans_buf = (((Time.hour%100/10)<<4)&0x30)+((Time.hour%10)&0X0F);//写入时DS1302Write(hour_w, trans_buf);trans_buf = (((Time.minute%100/10)<<4)&0x70) + ((Time.minute%10)&0X0F); //写入分DS1302Write(minute_w, trans_buf);trans_buf = (((Time.second%100/10)<<4)&0x70) + ((Time.second%10)&0X0F); //写入秒DS1302Write(second_w, trans_buf);trans_buf = Time.week%7; //写入星期DS1302Write(week_w, trans_buf);DS1302Write(0x8e,0x80); //开写保护}void writeDate2DS1302(Time_info Time){DS1302Write(0x8e,0x00);//写保护关trans_buf = ((Time.year%100/10)<<4)+((Time.year%10)&0X0F); // 写入年DS1302Write(year_w, trans_buf);trans_buf = (((Time.month%100/10)<<4)&0x10) +((Time.month%10)&0X0F); //写入月DS1302Write(month_w, trans_buf);trans_buf = (((Time.day%100/10)<<4)&0x30) + ((Time.day%10)&0X0F);//写入日DS1302Write(day_w, trans_buf);Time.week = (int)(Time.year/100)/4-(int)2*(Time.year/100)+(int)(Time.year%100)+(int)(Time.year%100)/4+(int)26*(Time.mo nth+1)/10+(int)Time.day-1;// printf("--week:%5d--",Time.week);Time.week %= 7;if(Time.week == 0) Time.week = 7;trans_buf = Time.week; //写入星期DS1302Write(week_w, trans_buf);DS1302Write(0x8e,0x80); //开写保护}void time_HMS2DS1302(Time_info Time){DS1302Write(0x8e,0x00);//写保护关trans_buf = (((Time.hour%100/10)<<4)&0x30)+((Time.hour%10)&0X0F);//写入时DS1302Write(hour_w, trans_buf);trans_buf = (((Time.minute%100/10)<<4)&0x70) + ((Time.minute%10)&0X0F); //写入分DS1302Write(minute_w, trans_buf);trans_buf = (((Time.second%100/10)<<4)&0x70) + ((Time.second%10)&0X0F); //写入秒DS1302Write(second_w, trans_buf);DS1302Write(0x8e,0x80); //开写保护}void time_read_from_DS1302(Time_info *Time){Time->year = DS1302Read(year_r);Time->month = DS1302Read(month_r);Time->day = DS1302Read(day_r);Time->hour = DS1302Read(hour_r);Time->minute = DS1302Read(minute_r);Time->second = DS1302Read(second_r);Time->week = DS1302Read(week_r);Time->year = 2000+((Time->year>>4)*10)+(Time->year&0x0f);Time->month = ((Time->month>>4)*10) + (Time->month&0x0f);Time->day = (Time->day>>4)*10 + (Time->day&0x0f);Time->hour = (Time->hour>>4)*10 + (Time->hour&0x0f);Time->minute = ((Time->minute>>4)*10) + (Time->minute&0x0f);Time->second = (Time->second>>4)*10 + (Time->second&0x0f); }void DS1302_Writebyte(uchar dat){uchar i;sclkk = 0;delay(300);for(i = 0; i < 8; i++){sdinn = dat & 0x01;delay(90);sclkk = 1;delay(180);sclkk = 0;dat >>= 1;}}uchar DS1302_Readbyte(){uchar i, dat = 0;delay(90);for(i = 0; i < 8; i++){dat >>=1;if(sdinn)dat |= 0x80;sclkk = 1;delay(60);sclkk = 0;delay(60);}sdinn = 0;return dat;}void DS1302Write(uchar cmd, uchar dat) {cee = 0;sclkk = 0;cee = 1;DS1302_Writebyte(cmd);DS1302_Writebyte(dat);sclkk = 1;cee = 0;}uchar DS1302Read(uchar cmd) {uchar dat = 0;cee = 0;sclkk = 0;cee = 1;DS1302_Writebyte(cmd);dat = DS1302_Readbyte();sclkk = 1;cee = 0;return dat;}void Init_DS1302(void){Time_info time;uchar init_state;DS1302Write(0x8e,0x00);//写保护关init_state = DS1302Read(protect_r); DS1302Write(0x8e,0x80); //开写保护if(init_state != D_protect){time.year = 2014;time.month = 12;time.day = 5;time.hour = 18;time.minute = 57;time.second = 50; //日期换算为星期[c/4]-2c+y+[y/4]+[26(m+1)/10]+d-1time.week = (time.year/100)/4-2*(time.year/100)+(time.year %100)+(time.year%100)/4+26*(time.month+1)/10+time.da y-1;time.week %= 7;if(time.week == 0) time.week = 7;time_write2DS1302(time);DS1302Write(0x8e,0x00);//写保护关DS1302Write(protect_w,D_protect); //初始化一次标示DS1302Write(0x8e,0x80); //开写保护}DS1302Write(0x8e,0x00);//写保护关Alarm_buff[0] = DS1302Read(clock_base_r+0);Alarm_buff[1] = DS1302Read(clock_base_r+2);Alarm_buff[2] = DS1302Read(clock_base_r+4);Alarm_buff[3] = DS1302Read(clock_base_r+6);Alarm_buff[4] = DS1302Read(clock_base_r+8);Alarm_buff[5] = DS1302Read(clock_base_r+10);Alarm_state = DS1302Read(clock_state_r);DS1302Write(0x8e,0x80); //开写保护}void display_date(unsigned char X,unsigned char Y,Time_info Read_T) {xdata char dis_info[12];sprintf(dis_info, "%04d/%02d/%02d", (int)Read_T.year, (int) Read_T.month, (int)Read_T.day);LCD_write_english_string(X,Y,dis_info);sprintf(dis_info, "%02d/%02d/%02d", (int)Read_T.hour, (int) Read_T.minute, (int)Read_T.second);LCD_write_english_string(X+6,Y+1,dis_info);sprintf(dis_info, "Week:%d", (int)Read_T.week);LCD_write_english_string(X+12,Y+2,dis_info);}void Alarm_respond(){hour = (uint)Alarm_buff[0]*10+Alarm_buff[1];minute = (uint)Alarm_buff[2]*10+Alarm_buff[3];second = (uint)Alarm_buff[4]*10+Alarm_buff[5];if(Alarm_state==1){time_read_from_DS1302(&Read_Time);if((old_second < Read_Time.second)||(Read_Time.second==0)){if(arriveminute!=Read_Time.minute) Alarm_arrive = 0;if((Read_Time.hour == hour)&&(Read_Time.minute== minute)&&(Read_Time.second == second)){Alarm_arrive = 1;arriveminute = Read_Time.minute;}}old_second = Read_Time.second;}}void sendtime2computer(){time_read_from_DS1302(&Read_Time);printf("time%04d/%02d/%02d/%02d:%02d:%02d", Read_Time.year, Read_Time.month, Read_Time.day, Read_Time.hour, Read_Time.minute,Read_Time.second);printf("%d--\n",Read_Time.week);}。
DS1302时钟基础使用(含代码)
DS1302时钟基础使⽤(含代码)了解其管脚X1 X2 32.768KHz 晶振管脚GND 地RST 复位脚I/O 数据输⼊/输出引脚,具有三态SCLK 串⾏时钟Vcc1,Vcc2(备⽤电源供电)电源供电管脚DS1302 的寄存器及⽚内RAM控制寄存器⽤于存放DS1302的控制命令字,DS1302的RST引脚回到⾼电平后写⼊的第⼀个字就为控制命令。
它⽤于对DS1302读写过程进⾏控制,它的格式如下:D7:固定为1D6:RAM/CK位,=1⽚内RAM,=0⽇历、时钟寄存器选择位。
D5~D1:地址位,⽤于选择进⾏读写的⽇历、时钟寄存器或⽚内RAM。
对⽇历、时钟寄存器或⽚内RAM的选择见表。
D0:读写选择,=0写,=1读⽇历时钟寄存器写保护寄存器⽤于初始化时钟void Ds1302Init(){uchar n;Ds1302Write(0x8E,0X00); //禁⽌写保护,就是关闭写保护功能for (n=0; n<7; n++)//写⼊7个字节的时钟信号:分秒时⽇⽉周年{Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);}Ds1302Write(0x8E,0x80); //打开写保护功能}寄存器说明数据输出输⼊在控制指令字输⼊后的下⼀个SCLK时钟的上升沿时,数据被写⼊DS1302,数据输⼊从低位即位0开始。
同样,在紧跟8位的控制指令字后的下⼀个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到⾼位7。
单字节读和写DS1302是通过SPI串⾏总线跟单⽚机通信的,当进⾏⼀次读写操作时最少得读写两个字节,第⼀个字节是控制字节,就是⼀个命令,告诉DS1302是读还是写操作,是对RAM还是对CLOK寄存器操作。
第⼆个字节就是要读或写的数据了。
单字节读写:只有在SCLK为低电平时,才能将CE置为⾼电平。
所以在进⾏操作之前先将SCLK置低电平,然后将CE置为⾼电平,接着开始在IO上⾯放⼊要传送的电平信号,然后跳变SCLK。
DS1302中文资料,带源代码
DS1302 引脚
X1 X2 32.768KHz 晶振管脚 GND 地 CE 复位脚 I/O 数据输入/输出引脚 SCLK 串行时钟 Vcc1,Vcc2 电源供电管脚
各引脚的功能为:
Vcc1:主电源;Vcc2:备份电源。当Vcc2>Vcc1+0.2V时,由Vcc2 向DS1302供电,当Vcc2< Vcc1时,由Vcc1向DS1302供电。 SCLK:串行时钟,输入,控制数据的输入与输出; I/O:三线接口时的双向数据线; CE:输入信号,在读、写数据期间,必须为高。该引脚有两个功能: 第一,CE开始控制字访问移位寄存器的控制逻辑;其次, CE 提供结束单字节或多字节数据传输的方法。
参考电路:
如上图所示: DS1302 与单片机的连接也仅需要 3 条线:CE 引脚、SCLK 串行时钟 引脚、I/O 串行数据引脚,Vcc2 为备用电源,外接 32.768kHz 晶振, 为芯片提供计时脉冲。
实际电路:
Vcc_5V:为电路中的主电源;Vcc2,也就是 BT1 为备份电源。当 Vcc2>Vcc1+0.2V 时, 由 Vcc2 向 DS1302 供 电 , 当 Vcc2< Vcc1 时 , 由 Vcc1 向 DS1302 供电 CLK 和 I/O 虽然和 IIC 总线接在一条引脚上,但 DS1302 其实并不是 使用 IIC 总线,而是一种三线式总线,
delayus(2); } return dat;//返回读取出的数据 }
寄存器和 RAM
对 DS1302 的操作就是对其内部寄存器的操作,DS1302 内部共有 12 个寄存器, 其中有: 7 个寄存器与日历、时钟相关,存放的数据位为 BCD 码形式。 此外,DS1302 还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器 及与 RAM 相关的寄存器等。 时钟突发寄存器可一次性顺序读写除充电寄存器以外的寄存器。 如下所示:
DS1302程序代码
DS1302程序代码#include <reg51.h>#include <string.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit SDA=P1^0; //DS1302数据线sbit CLK=P1^1; //DS1302时钟线sbit RST=P1^2; // DS1302 复位线char Adjust_Index=-1; //当前调节的时间对象:秒,分,时,日,月,年(0,1,2,3,4,6)uchar MonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31}; // 一年中每个月的天数,二月的天数由年份决定uchar DateTime[7];//所读取的日期时间//函数声明void Write_Byte_TO_DS1302(uchar X); // 向DS1302写入一个字节uchar Read_Byte_FROM_DS1302(); //从DS1302中读取一个字节uchar Read_Data_FROM_DS1302(uchar addr); //从DS1302指定位置读取数据, 读数据void Write_Data_TO_DS1302(uchar addr,uchar dat); // 向DS1302指定位置写入数据, 写数据void SET_DS1302(); // 设置时间void GetTime(); // 读取当前时间uchar Is_Leapyear(uint year);// 判断是否为闰年//*--------写字节函数,向DS1302写入一个字节--------*//void Write_Byte_TO_DS1302(uchar X) // 向DS1302写入一个字节{uchar i;for(i=0;i<8;i++){SDA=X&1;CLK=1;CLK=0;X>>=1;}}//*--------读字节函数,从DS1302读取一个字节--------*//uchar Read_Byte_FROM_DS1302() //从DS1302中读取一个字节{uchar i,byte,t;for(i=0;i<8;i++){byte>>=1;t=SDA;byte|=t<<7;CLK=1;CLK=0;}//BCD码转换return byte/16*10+byte%16;}//-------------------------------------------------------------//从DS1302指定位置读取数据 , 读数据//---------------------------------------------------------------uchar Read_Data_FROM_DS1302(uchar addr) //从DS1302指定位置读取数据 , 读数据{uchar dat;RST=0;CLK=0;RST=1;Write_Byte_TO_DS1302(addr); //向DS1302写入一个地址dat=Read_Byte_FROM_DS1302(); //在上面写入的地址中读取数据CLK=1;RST=0;return dat;}//-------------------------------------------------------------//向DS1302指定位置写入数据, 写数据//---------------------------------------------------------------void Write_Data_TO_DS1302(uchar addr,uchar dat) // 向DS1302指定位置写入数据, 写数据{CLK=0;RST=1;Write_Byte_TO_DS1302(addr);Write_Byte_TO_DS1302(dat);CLK=1;RST=0;}//-----------------------------------------------------------// 设置时间//---------------------------------------------------------void SET_DS1302() // 设置时间{uchar i;Write_Data_TO_DS1302(0x8E,0x00); //写控制字,取消写保护// 分,时,日,月,年依次写入for(i=1;i<7;i++){// 分的起始地址是10000010(0x82),后面依次是时,日,月,周,年,写入地址每次递增2Write_Data_TO_DS1302(0x80+2*i,(DateTime[i]/10<<4)|(DateTime[i]%10));}Write_Data_TO_DS1302(0x8E,0x80); //写控制字,加写保护}//--------------------------------------------------------// 读取当前时间//-------------------------------------------------------void GetTime() // 读取当前时间{uchar i;for(i=0;i<7;i++){DateTime[i]=Read_Data_FROM_DS1302(0x81+2*i);}}//-------------------------------------------------------------------// 判断是否为闰年//-------------------------------------------------------------------uchar Is_Leapyear(uint year){return (year%4==0&&year%100!=0)||(year%400==0) ;}//------------------------------------------------------------------// 求自2000.1.1开始的任何一天是星期几?//----------------------------------------------------------------------void Refresh_Week_Day(){uint i,d,w=5; //已知1999年12.31是星期五for(i=2000;i<2000+DateTime[6];i++){d=Is_Leapyear(i)?366:365;w=(w+d)%7;}d=0;for (i=1;i<DateTime[4];i++){d+=MonthsDays[i];}d+=DateTime[3];//保存星期,0-6表示星期日,星期一至星期六,为了与DS1302的星期格式匹配,返回值需要加1DateTime[5]=(w+d)%7+1;}//-------------------------------------------------//年,月,日和时,分++/--//----------------------------------------------------void Datetime_Adjust(char X){switch(Adjust_Index){case 6: //年调整,00-99if(X==1&&DateTime[6]<99){DateTime[6]++;}if(X==-1&&DateTime[6]>0){DateTime[6]--;}//获取2月天数MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28;//如果年份变化后当前月份的天数大于上限则设为上限if(DateTime[3]>MonthsDays[DateTime[4]]){DateTime[3]=MonthsDays[DateTime[4]];}Refresh_Week_Day(); //刷新星期break;case 4: //月调整01-12if(X==1&&DateTime[4]<12){DateTime[4]++;}if(X==-1&&DateTime[4]>1){DateTime[4]--;}//获取2月天数MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28;//如果年份变化后当前月份的天数大于上限则设为上限if(DateTime[3]>MonthsDays[DateTime[4]]){DateTime[3]=MonthsDays[DateTime[4]];}Refresh_Week_Day(); //刷新星期break;case 3: // 日调整00-28或00-29或00-30或00-31//调节之前首先根据当前年份得出该年中2月的天数MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28;//根据当前月份决定调节日期的上限if(X==1&&DateTime[3]<MonthsDays[DateTime[4]]){DateTime[3]++;}if(X==-1&&DateTime[3]>0){DateTime[3]--;}Refresh_Week_Day(); //刷新星期break;case 2: // 时调整if(X==1&&DateTime[2]<23){DateTime[2]++;}if(X==-1&&DateTime[4]>0){DateTime[2]--;}break;case 1: // 分调整if(X==1&&DateTime[1]<59){DateTime[1]++;}if(X==-1&&DateTime[4]>0){DateTime[1]--;}break;case 0: // 秒调整if(X==1&&DateTime[1]<59){DateTime[0]++;}if(X==-1&&DateTime[4]>0){DateTime[0]--;}break;}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
write_com(0x80+0x40+add-1);
write_date(0x10);
delay(100);
display_1602N(add,2,time%10);
display_1602N(add-1,2,time/10);
delay(100);
}
void shanshuo1(uchar add,time) //1602第一行闪烁函数
shanshuo1(15,timetmp[5]);
keynum=jiance();
zj(5);
writebyte(0x8a,timetmp[5]/10*16+timetmp[5]%10);
}
while(ss==6) //调年
{
key=0;
timetmp[6]=readbyte(0x8d)/16*10+readbyte(0x8d)%16; //同上
shanshuo2(10,timetmp[1]);
keynum=jiance();
zj(1);
writebyte(0x82,timetmp[1]/10*16+timetmp[1]%10);
}
while(ss==2) //调时
{
key=0;
timetmp[2]=readbyte(0x85)/16*10+readbyte(0x85)%16; //同上
shanshuo1(9,timetmp[3]);
keynum=jiance();
zj(3);
writebyte(0x86,timetmp[3]/10*16+timetmp[3]%10);
}
while(ss==4) //调月
{
key=0;
timetmp[4]=readbyte(0x89)/16*10+readbyte(0x89)%16;
shanshuo1(3,timetmp[6]);
keynum=jiance();
zj(6);
writebyte(0x8c,timetmp[6]/10*16+timetmp[6]%10);
}
}
}
void main()
{
init_1602(); //初始化1602
writetime(); //首次上电,往1302里面写时间
display_1602S(1,2,"TIME");
display_1602S(5,2,":");
display_1602N(6,2,hour/10);
display_1602N(7,2,hour%10);
display_1602S(8,2,":");
display_1602N(9,2,min/10);
shanshuo1(6,timetmp[4]);
keynum=jiance();
zj(4);
writebyte(0x88,timetmp[4]/10*16+timetmp[4]%10);
}
while(ss==5) //调周
{
key=0;
timetmp[5]=readbyte(0x8b)/16*10+readbyte(0x8b)%16; //同上
for(i=0;i<7;i++)
{
writebyte(j,time[i]);
j+=2;
}
}
uchar readbyte(add) //读一个单位时间(分/秒/时/年/月/日/周)
{
uchar date;
rst=0;sclk=0;rst=1;
write(add);
date=read();
rst=0;sclk=1;
hour=readdata[2];
day=readdata[3];
month=readdata[4];
week=readdata[5];
year=readdata[6];
}
void shanshuo2(uchar add,time) //1602第二行闪烁函数
{
write_com(0x80+0x40+add);
{
ss=0;
jpaction(); //相应调时操作
writebyte(0x80,timetmp[0]/10*16+timetmp[0]%10); //重写秒,把秒写回到调之前的位置
ss=0;
key=0;
}
}
}
delay(100); //延时
}
void zj(uchar num) //增减函数
{
switch(keynum)
{
case 1:ss++;break; //如果是1,则进入下一位的调整
case 2:{ //如果是2,则当前闪烁的位加1
timetmp[num]++;
if(timetmp[num]>MAX[num]) //如何超过了闪烁位的最大值,返回最小值
}
}
void display() //显示函数
{
display_1602N(0,1,2);
display_1602N(1,1,0);
display_1602N(2,1,year/10);
display_1602N(3,1,year%10);
display_1602S(4,1,"-");
display_1602N(5,1,month/10);
while(1)
{
readtime(); //从1302中读时间
process(); //把取出的时间(BCD码)转化为十进制
timeout(); //把时间从数组中提取出来
display(); //在1302上显示时间
keynum=jiance(); //检测按键是不是要调整时间
if(keynum==1)
write(0x00);
rst=0;sclk=0;rst=1;
write(add);
write(date);
rst=0;sclk=0;rst=1;
write(0x8e);
write(0x80);
rst=0;sclk=1;
}
void writetime() //初始化时间
{
uchar i,j=0x80;
return date;
}
void readtime() //读取时间
{
uchar i,j=0x81;
for(i=0;i<7;i++)
{
readdata[i]=readbyte(j);
j+=2;
}
}
void process() //数制转换
{ uchar i;
for(i=0;i<7;i++)
{
readdata[i]=(readdata[i]>>4)*10+(readdata[i]&0x0f);
}
}
void jpaction() //调时操作
{
while(ss<7)
{
while(ss==0) //调秒
{
key=0;
timetmp[0]=readbyte(0x81)/16*10+readbyte(0x81)%16; //从1302中取出时间
shanshuo2(13,timetmp[0]); //显示时间并闪烁
代码:
//1为功能键,2为增加时间键,3为减少时间键
#include<reg52.h>
#include<yj1602.h>
#include<jp.h>
#define uchar unsigned char
sbit sclk=P1^5;
sbit io=P1^6;
sbit rst=P1^7;
uchar time[]={0x00,0x42,0x08,0x04,0x09,0x06,0x10};
keynum=jiance(); //按键检测
zj(0); //对时间进行操作
writebyte(0x80,timetmp[0]/10*16+timetmp[0]%10); //把调整过的时间写到1302中
}
while(ss==1) //调分
{
key=0;
timetmp[1]=readbyte(0x83)/16*10+readbyte(0x83)%16; //同上
shuju=shuju>>1;
sclk=0;
if(io)
shuju=shuju|0x80;
sclk=1;
}
return shuju;
}
void writebyte(uchar add,date) //写时间的一个单位(分/秒/时/年/月/日/周)
{
rst=0;sclk=0;rst=1;
write(0x8e);
uchar timetmp[7];
uchar MAX[]={59,59,23,31,12,7,99};
uchar MINX[]={0,0,0,1,1,1,1};
uint readdata[7];
uchar sec,min,hour,day,month,week,year;
uchar keynum,ss;
display_1602N(6,1,month%10);
display_1602S(7,1,"-");
display_1602N(8,1,day/10);