ds1302头文件

合集下载

DS1302时钟芯片 C语言程序设计

DS1302时钟芯片 C语言程序设计

unsigned char i,tmp; time_buf[1]=ds1302_read_byte(ds1302_year_add); //年 time_buf[2]=ds1302_read_byte(ds1302_month_add); //月 time_buf[3]=ds1302_read_byte(ds1302_date_add); //日 time_buf[4]=ds1302_read_byte(ds1302_hr_add); //时 time_buf[5]=ds1302_read_byte(ds1302_min_add); //分 time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7F;//秒 time_buf[7]=ds1302_read_byte(ds1302_day_add); //周 for(i=0;i<8;i++){ //BCD处理 tmp=time_buf[i]/16; time_buf1[i]=time_buf[i]%16; time_buf1[i]=time_buf1[i]+tmp*10; } } /*DS302初始化函数*/ void ds1302_init(void) { RST_CLR; /*RST脚置低*/ SCK_CLR; /*SCK脚置低*/ }
} else { temp &= 0x7F; } SCK_SET; SCK_CLR; } RST_CLR; /*停止DS1302总线*/ return temp; } /*向DS302写入时钟数据*/ void ds1302_write_time(void) { unsigned char i,tmp; for(i=0;i<8;i++){ //BCD处理 tmp=time_buf1[i]/10; time_buf[i]=time_buf1[i]%10; 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_write_byte(ds1302_year_add,time_buf[1]); //年 ds1302_write_byte(ds1302_month_add,time_buf[2]); //月 ds1302_write_byte(ds1302_date_add,time_buf[3]); //日 ds1302_write_byte(ds1302_day_add,time_buf[7]); //周 ds1302_write_byte(ds1302_hr_add,time_buf[4]); //时 ds1302_write_byte(ds1302_min_add,time_buf[5]); //分 ds1302_write_byte(ds1302_sec_add,time_buf[6]); //秒 ds1302_write_byte(ds1302_day_add,time_buf[7]); //周 ds1302_write_byte(ds1302_control_add,0x80); //打开写保护 } /*从DS302读出时钟数据*/ void ds1302_read_time(void) {

ds1302编程资料

ds1302编程资料

***************************************/#include <iom16v.h> //包含型号头文件#include <macros.h> //包含"位"操作头文件#define uchar unsigned char#define uint unsigned int#define TRUE 1#define FALSE 0#include "YJ1602.C" //包含1602液晶函数文件/******************RTC常量******************/#define RTC_CLK PC4#define RTC_DATA PC5#define RTC_CS PC7//命令#define RD 0x01#define WR 0x00#define C_SEC 0x80 //秒(查手册)#define C_MIN 0x82 //分#define C_HR 0x84 //时#define C_DAY 0x86 //日#define C_MTH 0x88 //月#define C_WK 0x8A //星期DATE#define C_YR 0x8C //年#define C_WP 0x8E //控制(写保护)#define C_CHARGE 0x90 //涓流充电#define C_BURST 0xBE //时钟多字节//配置#define CLK_HALT 0x80 //停止时钟控制位SECOND bit7#define CLK_START 0x00 //启动时钟#define M12_24 0x80 //12/24小时值选择位HOUR bit7 #define PROTECT 0x80 //写保护控制位CONTROL bit7 #define UPROTECT 0x00 //写保护控制位CONTROL bit7 //涓流充电控制常量#define TC_D1R2 0xA5 //high 1 Diode +2K Resistors#define TC_D2R8 0xAB //low 2 Diodes+8K Resistors#define TC_DISABLED 0x00 //Disabled(TCS<>1010 or DS=00 or RS=00) //RAM 命令#define C_RAMBASE 0xC0 //RAM0~RAM30<<1 地址需左移一位//时间调节按钮#define DS1302_SetInit PINC //时间初始化输入数据总线端口定义#define UP 0x01 //时间调节按钮(加)端口定义#define down 0x02 //时间调节按钮(减)端口定义#define confirm 0x04 //时间调节按钮(确定/切换)端口定义//数组定义uchar line1[10]={'1','0','-','0','0','-','0','0',' ','\0'};//显示第1行的字符数组uchar line2[16]={'0','0',':','0','0',':','0','0',' ','w','e','e','k',':','0','\0'};//显示第2行的字符数组uchar settime[7]={0x50,0x59,0x23,0x22,0x03,0x04,0x12};//设置的秒,分,时,日,月,星期,年/*******************************************函数名称: delay_us功能: us级延时函数参数: US--要延时的时间返回值: 无/********************************************/void delay_us(uint US){uint i;US=US*5/4; //5/4是在8MHz晶振下,通过软件仿真反复实验得到的数值for( i=0;i<US;i++);}/*******************************************函数名称: delay_ms功能: ms级延时函数参数: MS--要延时的时间返回值: 无/********************************************/void delay_ms(uint MS){uint i,j;for( i=0;i<MS;i++)for(j=0;j<1141;j++); //1141是在8MHz晶振下,通过软件仿真反复实验得到的数值}/*******************************************函数名称: DS1302_init功能: 初始化DS1302的数据接口参数: 无返回值: 无/********************************************/void DS1302_portinit(void){DDRC|=BIT(RTC_CLK)|BIT(RTC_DATA)|BIT(RTC_CS);//将时钟端(RTC_CLK)数据端(RTC_DATA)片选端(RTC_CS)设置为输出}/*******************************************函数名称: DS1302_writeB功能: 向DS1302写入一个字节数据(没有RST操作)参数: byte--要写入的数据返回值: 无/********************************************/void DS1302_writeB(uchar byte){uchar i;for(i=0;i<8;i++) //8位数据计数{PORTC&=~BIT(RTC_CLK); //拉低时钟端if(byte&0x01) //当前位是否是1{PORTC|=BIT(RTC_DATA); //当前位是1,拉高数据端}else{PORTC&=~BIT(RTC_DATA); //当前位是0,拉低数据端}delay_us(10); //调整时钟和脉冲宽度PORTC|=BIT(RTC_CLK); //时钟上升沿(DS1302采样数据)byte>>=1; //数据右移1位,为送出新数据位做准备}}/*******************************************函数名称: DS1302_readB功能: 从DS1302读出一个字节数据(没有RST操作)参数: 无返回值: byte--读出的数据/********************************************/uchar DS1302_readB(void){uchar i,byte=0;DDRC&=~BIT(RTC_DATA); //将数据端口设置为输入PORTC&=~BIT(RTC_DATA); //无上拉电阻for(i=0;i<8;i++) //8位数据计数{byte>>=1; //保存读入的数据位PORTC|=BIT(RTC_CLK); //时钟上升沿delay_us(10); //延时,调整时钟脉冲宽度PORTC&=~BIT(RTC_CLK); //时钟下降沿,DS1302输出数据位delay_us(10); //等待数据变化(MEGA16太快,必须等待DS1302的数据位输出,否则不能正确读出)if(PINC&BIT(RTC_DA TA)) //当前位是否是高电平{byte|=BIT(PB7); //是高电平就将返回数据的当前位置1}else{byte&=~BIT(PB7); //是低电平就将返回数据的当前位置0 }}DDRC|=BIT(RTC_DATA); //最后将数据端口设置为输出return byte; //返回读出的数据}/*******************************************函数名称: DS1302_writeD功能: 向DS1302的某个地址写入一个字节数据参数: addr--地址值(寄存器或RAM)data--要写入的地址返回值: 无/********************************************/void DS1302_writeD(uchar addr,uchar data){PORTC&=~BIT(RTC_CS); //拉低片选端PORTC&=~BIT(RTC_CLK); //拉低时钟端delay_us(10);PORTC|=BIT(RTC_CS); //拉高片选端delay_us(10); //调整片选脉冲DS1302_writeB(addr); //写入操作命令(地址)delay_us(10);PORTC&=~BIT(RTC_CLK); //拉低时钟端delay_us(10);DS1302_writeB(data); //写入数据PORTC&=~BIT(RTC_CLK); //拉低时钟端delay_us(10); //调整片选脉冲PORTC&=~BIT(RTC_CS); //拉低片选端}/*******************************************函数名称: DS1302_readD功能: 从DS1302的某个地址读出一个字节数据参数: addr--地址值(寄存器或RAM)返回值: data--读出的数据/********************************************/uchar DS1302_readD(uchar addr){uchar data;PORTC&=~BIT(RTC_CS); //拉低片选端PORTC&=~BIT(RTC_CLK); //拉低时钟端delay_us(10);PORTC|=BIT(RTC_CS); //拉高片选端delay_us(10); //调整片选脉冲DS1302_writeB(addr); //写入操作命令(地址)delay_us(10);data=DS1302_readB(); //读出数据delay_us(10);PORTC&=~BIT(RTC_CLK); //拉低时钟端PORTC&=~BIT(RTC_CS); //拉低片选端return data; //返回读出的数据}/*******************************************函数名称: DS1302_setT功能: 设置DS1302的时间参数: ptTimeD--设置时间数组指针返回值: 无/********************************************/void DS1302_setT(uchar ptTimeD[]){uchar i;uchar addr = 0x80; //写入地址从秒寄存器开始DS1302_writeD(C_WP|WR,UPROTECT); //控制命令,WP位为0,允许写操作delay_ms(5);for(i=0;i<7;i++){DS1302_writeD(addr|WR,ptTimeD[i]); // 秒分时日月星期年addr+=2;delay_ms(1);}DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作}/*******************************************函数名称: DS1302_getT功能: 读取DS1302的当前时间参数: time[]--读取的时间数组返回值: 无/********************************************/void DS1302_getT(uchar time[]){uchar i;////////下面的是单次读写///////////////////////////* uchar addr = 0x80; //读取地址从秒寄存器开始for(i=0;i<7;i++){time[i]=DS1302_readD(addr|RD); // 秒分时日月星期年addr+=2;}*//////////////////////////////////////////////////////////////下面是多字节读取///////////////PORTC&=~BIT(RTC_CS); //拉低片选端delay_us(10);PORTC|=BIT(RTC_CS); //拉高片选端delay_us(10); //调整片选脉冲DS1302_writeB(0xbf); // 0xbf:时钟多字节读取命令for (i=0;i<8;i++) //时间数据的存放格式是:{ //秒,分,时,日,月,星期,年,控制time[i]=DS1302_readB(); //【7个数据(BCD格式)+1个控制】}PORTC&=~BIT(RTC_CS); //拉低片选端///////////////////////////////////////////////PORTC&=~BIT(RTC_CLK); //拉低时钟端(时钟端在不操作时为低)}/*******************************************函数名称: DS1302_check功能: 检测DS1302是否正常工作参数: 无返回值: exist--为TRUE为检测到DS1302,为FALSE为没检测到/********************************************/uchar DS1302_check(void){uchar exist;DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令DS1302_writeD(C_RAMBASE|WR,0xA5); //RAM0写入0xA5exist=DS1302_readD(C_RAMBASE|RD); //读取RAM0if(exist==0xA5){exist=TRUE; //如果读取值与写入值相等,返回TRUE }else{exist=FALSE; //如果读取值与写入值不相等,返回FALSE}return exist;}/*******************************************函数名称: DS1302_init功能: 初始化DS1302参数: 无返回值: 无/********************************************/void DS1302_init(void){DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令DS1302_writeD(C_SEC|WR,CLK_START); //启动振荡器,DS1302开始工作DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作}/*******************************************函数名称: BCD_ASCII功能: 将压缩BCD码转换成ascii码参数: BCD--将要转换的压缩BCD码ptasc--转换后的ASCII码数组指针返回值: 无/********************************************/void BCD_ASCII(uchar BCD,uchar ptasc[]){ptasc[0]=BCD/16|0x30; //0X58 35 38 //转换十位ptasc[1]=BCD&0x0F|0x30; //转换个位}/*******************************************函数名称: Disp_time功能: 在1602液晶上显示当前时间(第1行格式:年-月-日星期;第2行格式:时-分-秒)参数: time[]--时间数组返回值: 无/********************************************/void Disp_time(uchar time[]){uchar i,asc[2];for(i=0;i<3;i++) //为第2行的字符数组赋值{BCD_ASCII(time[2-i],asc);line2[i*3]=asc[0];line2[i*3+1]=asc[1];}BCD_ASCII(time[6],asc); //为第1行的年赋值line1[0]=asc[0];line1[1]=asc[1];BCD_ASCII(time[4],asc); //为第1行的月赋值line1[3]=asc[0];line1[4]=asc[1];BCD_ASCII(time[3],asc); //为第1行的日赋值line1[6]=asc[0];line1[7]=asc[1];BCD_ASCII(time[5],asc); //为第2行的星期赋值line2[14]=asc[1];while(LCD1602_readBF());LCD1602_gotoXY(1,3); //第1行从第4个位置开始显示LCD1602_sendstr("20"); //将07年显示为2007的形式LCD1602_sendstr(line1); //第1行显示while(LCD1602_readBF());LCD1602_gotoXY(2,0); //第2行从第1个位置开始显示LCD1602_sendstr(line2); //第2行显示}/*******************************************函数名称: Set_Init()功能: 可以用按钮手动初始化ds1302的初始值操作:按下确定按钮之后,开始用上下按钮调节,调节之后按下确定按钮进入下一个时间的调节参数: 无返回值: 无/********************************************/void Set_Init(){uchar year=0; //初始化--年uchar month=1; //初始化--月uchar day=1; //初始化--日uchar time=0; //初始化--时uchar minute=0;//初始化--分uchar second=0;//初始化--秒uchar week=1; //初始化--星期while((DS1302_SetInit&confirm)==0);//判断按钮是否松开do//年份的调节,范围为2000~2099{if((year<=99)){if((DS1302_SetInit&UP)==0) //年份加一最大为2099{ year++;if(year==100) year=0; //当为最大值的时候,再加一为最小值while((DS1302_SetInit&UP)==0);}}//判断按钮是否松开if((year>=0)){if((DS1302_SetInit&down)==0) //年份减一最小为2000{ if(year==0) year=100; //当为最小值时,再减一为最大值year--;while((DS1302_SetInit&down)==0);}}//判断按钮是否松开line1[0]=(year/10)|0x30;//把十进制码转换成1602所显示的ASCII码line1[1]=(year%10)|0x30;//把十进制码转换成1602所显示的ASCII码LCD1602_gotoXY(1,5); //从第1行第6列开始显示LCD1602_sendstr(line1);//显示所改的内容LCD1602_gotoXY(1,6); //光标闪烁的地址LCD1602_sendbyte(0,0x0f);// 打开光标闪烁delay_ms(30); //延时很重要(影响光标的闪烁)}while((DS1302_SetInit&confirm)==confirm);//判断确定按钮是否按下while((DS1302_SetInit&confirm)==0);//判断按钮是否松开do//月份的调节范围1~12{if((month<=12))//加{if((DS1302_SetInit&UP)==0){ month++;if(month==13) month=1;while((DS1302_SetInit&UP)==0);}}if((month>=1))//减{if((DS1302_SetInit&down)==0){ if(month==1) month=13;month--;while((DS1302_SetInit&down)==0);}}line1[3]=(month/10)|0x30;line1[4]=(month%10)|0x30;LCD1602_gotoXY(1,5);LCD1602_sendstr(line1);LCD1602_gotoXY(1,9);LCD1602_sendbyte(0,0x0f);delay_ms(30); //延时很重要(影响光标的闪烁?}while((DS1302_SetInit&confirm)==confirm);while((DS1302_SetInit&confirm)==0);do//天数的调节范围1~31{if((day<=31))//加{if((DS1302_SetInit&UP)==0){ day++;if(day==32) day=1;while((DS1302_SetInit&UP)==0);}}if((day>=1))//减{if((DS1302_SetInit&down)==0){ if(day==1) day=32;day--;while((DS1302_SetInit&down)==0);}} line1[6]=(day/10)|0x30;line1[7]=(day%10)|0x30;LCD1602_gotoXY(1,5);LCD1602_sendstr(line1);LCD1602_gotoXY(1,12);LCD1602_sendbyte(0,0x0f);delay_ms(30); //延时很重要(影响光标的闪烁)}while((DS1302_SetInit&confirm)==confirm);while((DS1302_SetInit&confirm)==0);do//小时的调节范围00~23{if((time<=23))//加{if((DS1302_SetInit&UP)==0){ time++;if(time==24) time=0;while((DS1302_SetInit&UP)==0);}}if((time>=0))//减{if((DS1302_SetInit&down)==0){ if(time==0) time=24;time--;while((DS1302_SetInit&down)==0);}} line2[0]=(time/10)|0x30;line2[1]=(time%10)|0x30;LCD1602_gotoXY(2,0);LCD1602_sendstr(line2);LCD1602_gotoXY(2,1);LCD1602_sendbyte(0,0x0f);delay_ms(30); //延时很重要(影响光标的闪烁)}while((DS1302_SetInit&confirm)==confirm);while((DS1302_SetInit&confirm)==0);do//分钟的调节范围00~59{if((minute<=59))//加{if((DS1302_SetInit&UP)==0){ minute++;if(minute==60) minute=0;while((DS1302_SetInit&UP)==0);}}if((minute>=0))//减{ if(minute==0) minute=60;minute--;while((DS1302_SetInit&down)==0);}} line2[3]=(minute/10)|0x30;line2[4]=(minute%10)|0x30;LCD1602_gotoXY(2,0);LCD1602_sendstr(line2);LCD1602_gotoXY(2,4);LCD1602_sendbyte(0,0x0f);delay_ms(30); //延时很重要(影响光标的闪烁)}while((DS1302_SetInit&confirm)==confirm);while((DS1302_SetInit&confirm)==0);do//秒的调节范围00~59{if((second<=59))//加{if((DS1302_SetInit&UP)==0){ second++;if(second==60) second=0;while((DS1302_SetInit&UP)==0);}}if((second>=0))//减{if((DS1302_SetInit&down)==0){ if(second==0) second=60;second--;while((DS1302_SetInit&down)==0);}} line2[6]=(second/10)|0x30;line2[7]=(second%10)|0x30;LCD1602_gotoXY(2,0);LCD1602_sendstr(line2);LCD1602_gotoXY(2,7);LCD1602_sendbyte(0,0x0f);delay_ms(30); //延时很重要(影响光标的闪烁)}while((DS1302_SetInit&confirm)==confirm);while((DS1302_SetInit&confirm)==0);do//星期的调节范围1~7{if((week<=7))//加{if((DS1302_SetInit&UP)==0){ week++;if(week==8) week=1;while((DS1302_SetInit&UP)==0);}}if((week>=1))//减{ if(week==1) week=8;week--;while((DS1302_SetInit&down)==0);}}line2[14]=(week%10)|0x30;LCD1602_gotoXY(2,0);LCD1602_sendstr(line2);LCD1602_gotoXY(2,14);LCD1602_sendbyte(0,0x0f);delay_ms(30); //延时很重要(影响光标的闪烁)}while((DS1302_SetInit&confirm)==confirm);while((DS1302_SetInit&confirm)==0);settime[6]= ((0x10*(year/10))|(year%10));//(年)把十进制转换成DS1302所需要的十六进制码settime[4]= ((0x10*(month/10))|(month%10));//月settime[3]= ((0x10*(day/10))|(day%10));//日settime[2]= ((0x10*(time/10))|(time%10));//时settime[1]= ((0x10*(minute/10))|(minute%10));//分settime[0]= ((0x10*(second/10))|(second%10));//秒settime[5]= ((0x10*(week/10))|(week%10));//星期DS1302_portinit(); //初始化DS1302的三根数据线DS1302_init(); //启动振荡器,DS1302开始工作DS1302_setT(settime); //设置初始时间}/*******************************************函数名称: main功能: 1. 在1602液晶上显示当前时间2.可以设置时间(M1-M9为数字0-9,M13为设置模式和显示模式选择,M14为当前设置位选择)参数: 无返回值: 无/********************************************/void main(void){//uchar setadd,setdat,shift; //setadd指定将当前数值送入DS1302的哪个寄存器//setdat是当前设置的数值,即被送入DS1302指定寄存器的数//shift来实现十位和各位的设置相互独立(因为十位和个位是在一个寄存器里的)//uchar dis_x,dis_y; //存储1602液晶当前光标的位置uchar gettime[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};//保存当前时间的数组LCD1602_initial(); //初始化1602液晶DS1302_portinit(); //初始化DS1302的三根数据线DS1302_init(); //启动振荡器,DS1302开始工作DS1302_setT(settime); //设置初始时间while(1) //以下程序完成显示和设置时间{if((DS1302_SetInit&confirm)==0){Set_Init();}DS1302_getT(gettime); //获得当前时间Disp_time(gettime); //显示当前时间}}。

DS1302读写程序IIC总线

DS1302读写程序IIC总线

DS1302读写程序(IIC总线)#include; //包含单片机寄存器的头文件#include; //包含_nop_()函数定义的头文件#define uchar unsigned char#define uint unsigned intsbit SRT=P3^5;sbit IO=P3^4;sbit SCK=P3^6;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};uchar miao,fen,shi,tian,yue,zhou,nian;uchar read_DS1302(uchar addr)//读DS1302子程序;{uchar dat,i,temp,j;SRT=0;SCK=0;IO=0;//必须先置低,否则易出错;SRT=1;for(i=0;i;>;1;SCK=1;_nop_();}// IO=1;//释放总线,以便接下来的读操作,//否则读出的数据永远都是0x00,//但因addr最高总是1,在传送最高位时,即IO=dat=1, //所以此句可以不要;for(j=0;j;>;=1;if(IO)temp=temp|0x80;SCK=1;_nop_();}SCK=0;//必须严格按时序拉低,不然出错;SRT=0;IO=1;//必须释放总线;return temp;}void write_DS1302(uchar add,uchar date)//写DS1302子程序;{uchar dat1,i,dat2,j;SRT=0;SCK=0;IO=0;SRT=1;_nop_();for(i=0;i;>;1;IO=dat1;SCK=1;_nop_();}for(j=0;j;>;1;IO=dat2;SCK=1;_nop_();}SCK=0;SRT=0;IO=1;}void delay(uint n) {while(n--);}void display(){uchar miao1,miao2,fen1,fen2,shi1,shi2; P0=0xff;P1=0x00;miao1=miao&0x0f;miao2=miao&0xf0;miao2=miao2>;>;4;fen1=fen&0x0f;fen2=fen&0xf0;fen2=fen2>;>;4;shi1=shi&0x0f;shi2=shi&0xf0;shi2=shi2>;>;4;P1=table[miao1];P0=0x7f;delay(200);P1=table[miao2];P0=0xbf;delay(200);P1=0x40;P0=0xdf;delay(200);P1=table[fen1];P0=0xef;delay(200);P1=table[fen2];P0=0xf7;delay(200);P1=0x40;P0=0xfb;delay(200);P1=table[shi1];P0=0xfd;delay(200);P1=table[shi2];P0=0xfe;delay(200);}void main(){//设置日期时间(2013/09/11,21:03:00,星期3);while(1){miao=read_DS1302(0x81);fen=read_DS1302(0x83);shi=read_DS1302(0x85);tian=read_DS1302(0x87);yue=read_DS1302(0x89);zhou=read_DS1302(0x8b);nian=read_DS1302(0x8d);//读取DS18B20数据; P2=miao;display();}}。

DS1302时钟 LCD1206 显示 C程序

DS1302时钟 LCD1206 显示 C程序

STC12C5A08AD 单片机DS1302 时钟芯片LCD1602 液晶显示#include <stc12c5a08ad.h> //stc单片机专用的头文件#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int#define ulong unsigned long#define dat P0 //定义LCD1602的数据口为P0 void delay(unsigned int xms ); //声明延时函数void delay2(unsigned int xms);void display(void); //显示程序void keyscan(void);sbit key0=P2^0;sbit key1=P2^1;sbit key2=P2^2;sbit key3=P2^3;sbit beep=P3^4;/****ds1302****/#define DS1302_SECOND_WRITE 0x80#define DS1302_MINUTE_WRITE 0x82#define DS1302_HOUR_WRITE 0x84#define DS1302_DAY_WRITE 0x86#define DS1302_MONTH_WRITE 0x88#define DS1302_WEEK_WRITE 0x8A#define DS1302_YEAR_WRITE 0x8Cvoid Set_MIN(uchar s);void Set_HR(uchar s);void Init_DS1302(void) ;void DS1302WriteByte(uchar dat);void DS1302Write(uchar cmd,uchar dat);uchar DS1302Read(uchar cmd);uchar DS1302Read_1(uchar cmd);uchar DS1302ReadByte();uchar DS1302ReadByte_1();sbit RST=P1^4;sbit SCLK=P3^6;sbit SDA=P3^7;/*** lcd1206***/sbit rs=P1^0; //定义RS口为P10sbit rw=P1^1; //定义RW口为P11sbit e=P1^2; //定义E口为P12void xianshi_sfm(uchar wei,uchar dat);void shj_1602(uchar a); //液晶写数据程序void int_1602(void); //液晶初始化void zhl_1602(uchar a); //液晶写指令程序uchar a,b,c,d;uchar code table0[7]={"time is"}; //定义LCD1602显示2行的字符uchar code table3[10]={"0123456789"};uchar code table4[1]={":"};/**************延时函数*****************/void delay(unsigned int xms) //延时函数,{unsigned int i,j ;for(i=xms;i>0;i--)for(j=110;j>0;j--);}/*****************LCD1602 显示程序******************************/void zhl_1602(uchar a) //写指令到LCM程序{// busy_1602(); //查询忙碌标志信号程序e=0;rs=0;rw=0;e=1;dat=a;delay(5);e=0;}void shj_1602(uchar a) //写数据到LCM程序{// busy_1602(); //查询忙碌标志信号程序e=0;rs=1;rw=0;e=1;dat=a;delay(5);e=0;}void int_1602(void) //启动LCM程序{zhl_1602(0x38); // 设置显示模式,数据接口位数zhl_1602(0x0c); // 设置显示开关,是否显示光标,是否闪动光标zhl_1602(0x06); // 设置光标移动方向左或右,设置所有文字是否移动}/*****************液晶LCD1602显示主程序程序***********/void display(void) //液晶显示程序{uchar i,ri,yue,nian; //定义计数值int_1602(); //初始化1602zhl_1602(0x80);delay(5); //写指令(11000000) 指定从第一行指针位置开始写for(i=0;i<7;i++) //发送数据第一行time is:{shj_1602(table0[i]);delay(5);}zhl_1602(0x80+10);delay(5); //for(i=0;i<1;i++) //发送数据第一行时间显示的“: ”{shj_1602(table4[i]);delay(5);}zhl_1602(0x80+13);delay(5); //for(i=0;i<1;i++) //发送数据第一行时间显示的“: ”{shj_1602(table4[i]);delay(5);}a=(DS1302Read(0x81)/16)*10+(DS1302Read(0x81)%16); //转换为十进制c=(DS1302Read(0x83)/16)*10+(DS1302Read(0x83)%16);d=(DS1302Read(0x85)/16)*10+(DS1302Read(0x85)%16);ri=(DS1302Read(0x87)/16)*10+(DS1302Read(0x87)%16);yue=(DS1302Read(0x89)/16)*10+(DS1302Read(0x89)%16);nian=(DS1302Read(0x8d)/16)*10+(DS1302Read(0x8d)%16);xianshi_sfm(8,d); // 时钟显示时delay(20);xianshi_sfm(11,c); // 时钟显示分delay(20);xianshi_sfm(14,a); // 时钟显示秒delay(20);xianshi_sfm(0X48,ri); // day 0X48 为换第二行写入显示年月日delay(20);xianshi_sfm(0X45,yue); // yuedelay(20);xianshi_sfm(0X42,nian); // niandelay(20);xianshi_sfm( 0x40,20); // 显示20 xx 年份的前缀}/*****时间显示子程序***/void xianshi_sfm(uchar wei,uchar dat){uchar shi,ge;shi=dat/10;ge=dat%10;zhl_1602(0x80+wei);//第一行显示+位选择delay(5);shj_1602(table3[shi]);delay(5);shj_1602(table3[ge]);delay(5);}/*************DS1302程序*************** /cmd: 要写入的控制字节dat: 读取的数据******uchar DS1302Read_1(uchar cmd)//十二小时制调用{uchar dat;RST=0; //////// 初始CE 线置为0SCLK=0; //////// 初始时钟线置为0RST=1; //////// 初始CE 置为 1 ,传输开始DS1302WriteByte(cmd); //////// 传输命令字,要读取的时间dat=DS1302ReadByte_1(); //////// 读取要得到的时间SCLK=1; //////// 时钟线拉高RST=0; //////// 读取结束,CE 置为0 ,结束数据的传输return dat; //////// 返回得到的时间/ / / / 日期}/********** 读操作************/uchar DS1302ReadByte_1() //十二小时制调用{uchar i,dat,dat1,dat2;delay(2);for(i=0;i<8;i++){dat>>=1; //////// 要返回的数据左移一位if(SDA==1) //////// 当数据线为高时,证明该位数据为1dat|=0x80; //////// 要传输数据的当前值置为1, 若不是则为0SCLK=1; // 拉高时钟线delay(5);SCLK=0; //////// 制造下降沿delay(5);}// RST=0; //////// 初始CE 线置为0dat1=dat-0x80; // -0x80 是设置12小时制后去掉”DS1302_HOUR_WRITE 0x84“设置的最高位1 以免影响取值错误否则时显示错误dat2=dat1/16; //数据进制转换dat1=dat1%16; //十六进制转十dat1=dat1+dat2*10;return (dat1); //////// 返回读取出的数据}/********** 读操作************/uchar DS1302Read(uchar cmd) //二四小时制调用{uchar dat;RST=0; //////// 初始CE 线置为0SCLK=0; //////// 初始时钟线置为0RST=1; //////// 初始CE 置为 1 ,传输开始DS1302WriteByte(cmd); //////// 传输命令字,要读取的时间dat=DS1302ReadByte(); //////// 读取要得到的时间SCLK=1; //////// 时钟线拉高RST=0; //////// 读取结束,CE 置为0 ,结束数据的传输return dat; //////// 返回得到的时间/ / / / 日期}/****写数据***/void DS1302Write(uchar cmd, uchar dat){RST=0; //////// 初始CE 线置为0SCLK=0; //////// 初始时钟线置为0RST=1; //////// 初始CE 置为1 ,传输开始DS1302WriteByte(cmd);DS1302WriteByte(dat); //////// 写入要修改的时SCLK=1; //////// 时钟线拉高RST=0; //////// 读取结束,CE 置为0 ,}/*******写操作*******/void DS1302WriteByte(uchar dat){uchar i;SCLK=0; //////// 初始时钟线置为0delay(5);for(i=0;i<8;i++) //////// 开始传输8 个字节的数据{SDA=dat&0x01; //////// 取最低位,注意DS130的数据和地址都是从最低位开始传输的delay(5);SCLK=1; //////// 时钟线拉高,制造上升沿,SDA 的数据被传输delay(5);SCLK=0; //////// 时钟线拉低,为下一个上升沿做准备dat>>=1; //////// 数据右移一位,准备传输下一位数据}// RST=0; //////// 初始CE 线置为0}/********** 读操作************/uchar DS1302ReadByte() //二四小时制调用{uchar i,dat;delay(2);for(i=0;i<8;i++){dat>>=1; //////// 要返回的数据左移一位if(SDA==1) //////// 当数据线为高时,证明该位数据为1dat|=0x80; //////// 要传输数据的当前值置为1, 若不是则为0SCLK=1; // 拉高时钟线delay(5);SCLK=0; //////// 制造下降沿delay(5);}RST=0; //////// 初始CE 线置为0return (dat); /}/*******DS1302初始化***********/void Init_DS1302(void){DS1302Write(0x8e,0x00); //////// 写保护关DS1302Write(DS1302_SECOND_WRITE,0x55); //////// 初始秒值为55DS1302Write(DS1302_MINUTE_WRITE,0x59); //////// 初始分钟值为59DS1302Write(0x84,0x23);////////24小时模式///若设置(0X84 0X92)初始为12小时模式,初始时间为12点,读程序时调用uchar DS1302Read_1(uchar cmd)DS1302Write(DS1302_DAY_WRITE,0x18); //年月日星期初值设置DS1302Write(DS1302_MONTH_WRITE,0x05);DS1302Write(DS1302_YEAR_WRITE,0x13);DS1302Write(DS1302_WEEK_WRITE,0x06);DS1302Write(0xc0,0xf0); //////// 初始化一次标示DS1302Write(0x8e,0x80); //开启写入保护}//主程序void main(){Init_DS1302();delay(5);while(1){display(); // 显示keyscan();}}/*****键控设置时间程序调整时,分的显示值可对时间校准***/void Set_MIN(uchar s) //1为分钟加,0为分钟减{unsigned char temp;DS1302Write(0x8E,0x00);//去除写保护temp=DS1302Read(0x83);if(s){temp+=1;if(temp>0x59)temp=0;if((temp&0x0f)>0x09) //if(temp%0x10>0x09) 当低四位大于9时temp=(temp+16)&0xf0; // temp=((temp+0x10) & 0xf0);高四位进1位低四位归零}else{if(temp>0) //temp-=1;else //TEMP 等于0 时;·temp=0x59;if((temp%0x10)>0x09) //减到低位为0后再减一次低位为1111,为15 取余运算后大于9 ,同时高位被低位借位减1,降了一个十位数temp=(temp&0xf0+0x09); //temp=((temp/0x10)*0x10 + 0x09) 则取高位值,低位置9,从而达到0至9循环}DS1302Write(0x82,temp);DS1302Write(0x8e,0x80);}void Set_HR(uchar s) //1为小时加,0为小时减{unsigned char temp;DS1302Write(0x8E,0x00);//去除写保护temp=DS1302Read(0x85);//小时数保存在低5位// temp<<=3;// temp>>=3;if(s){temp+=1;if(temp==0x0a) //加到0000 1010 时分位不需要10 手动加一操作时是按照2进制加一,芯片自动运行时按照BCD码进位的即低四位到9后加1 ,进位至高四位加1temp=0x10; //进一至十位BCD码if(temp==0x1a)temp=0x20;if(temp==0x24)temp=0;}else{ temp-=1;if(temp==0xff) //当为00000000 再减一位变成0XFFtemp=0x23; //改变0XFF 为自己需要的0X23 .3.2.1.0.23.22............... 循环调整if(temp==0x1f) //当20 (0010 0000)再减1时其实际值是0X1F(0001 1111 )temp=temp&0xf0+0x09; //舍弃低四位的值将其个位置9if(temp==0x0f)temp=0x09;}DS1302Write(0x84,temp);DS1302Write(0x8e,0x80); //写保护启动}void keyscan(){if(key0==0){delay(2);if(key0==0){ //分减更改Set_MIN(0);while(!key0);}}if(key1==0){delay(2);if(key1==0){ //分加更改Set_MIN(1);while(!key1);}}if(key2==0){delay(2);if(key2==0)Set_HR(0); //时减更改while(!key2);}if(key3==0){delay(2);if(key3==0)Set_HR(1); //时加更改while(!key3);}}。

时钟芯片DS1302 的程序

时钟芯片DS1302 的程序

函 数 名:W1302()
功 能:往DS1302写入数据
说 明:先写地址,后写命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址, ucData: 要写的数据
返 回 值:无
设 计:zhaojunjie 日 期:2002-03-19
***********************************************************************/
uchar RTOutputByte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; /*相当于汇编中的 RRC */
函 数 名:R1302()
功 能:读取DS1302某地址的数据
说 明:先写地址,后读命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址
返 回 值:ucData :读取的数据
设 计:zhaojunjie 日 期:2002-03-19
{
T_IO = ACC0; /*相当于汇编中的 RRC */
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
时钟芯片DS1302 的程序(jyh.h头文件)

DS1302中文资料,带源代码

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时钟芯片C51源代码源程序

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);}。

IO口实时时钟芯片DS1302的应用实例行业信息

IO口实时时钟芯片DS1302的应用实例行业信息

学习课件
11
表示要进行写操作,为1表示进行读操作,控制字节总是 从最低位开始输出。
2)在控制指令字输入后的下一个SCLK时钟的上升沿 时数据被写入DS1302,数据输入从低位即位0开始。同 样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降 沿读出DS1302的数据,读出数据时从低位0位至高位7。
sbit T_RST = P1^2;
//设置实时时钟复位线引脚 //
sbit ACC0=ACC^0;
//定义ACC的位,利用ACC操作速度最快
学习课件
18
sbit ACC7=ACC^7; uchar time1[6]; char counter[3]; uchar sec,min,hou,day,mon,yea; void Init1302(void); void v_W1302(uchar ucAddr, uchar ucDa); uchar uc_R1302(uchar ucAddr); void get_time(void); void set_time(void); /*********往DS1302写入1Byte数据**************/ void v_WTInputByte(uchar ucDa) {
HR
0 10DATE 0 0 10M
DATE MONTH
周寄存器 8AH 8BH
1-7
年寄存器 8CH 8DH
0-99
0000 10YEAR
0
DAY
YEAR
学习课件
10
其中CH:时钟停止位;为0时振荡器工作;为1时振 荡器停止;AP=1时为下午模式,为0时上午模式DS1302 的控制字节说明
1)DS1302的控制字节的最高有效位(位7)必须是逻 辑1,如果它为0,则不能把数据写入到DS1302中:位6如 果为0,则表示存取日历时钟数据,为1表示存取RAM数 据;位5至位1指示操作单元的地址:最低有效位(位0)为0

DS1302头文件

DS1302头文件

DS1302头⽂件#ifndef _DS1302_H_#define _DS1302_H_sbit DS1302_CLK = P2^1; //实时时钟时钟线引脚sbit DS1302_IO = P2^2; //实时时钟数据线引脚sbit DS1302_RST = P2^3; //实时时钟复位线引脚#define AM(X) X#define PM(X) (X+12) // 转成24⼩时制#define DS1302_SECOND 0x80#define DS1302_MINUTE 0x82#define DS1302_HOUR 0x84#define DS1302_DAY 0x86#define DS1302_MONTH 0x88#define DS1302_WEEK 0x8A#define DS1302_YEAR 0x8C#define DS1302_RAM(X) (0xC0+(X)*2) //⽤于计算 DS1302_RAM 地址的宏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 week_value[2];unsigned char DateString[9];unsigned char TimeString[9];}SYSTEMTIME; //定义的时间类型void DS1302InputByte(unsigned char d) //实时时钟写⼊⼀字节(内部函数){unsigned char i;for(i=8; i>0; i--){DS1302_IO = d&0x01; //相当于汇编中的 RRCDS1302_CLK = 1;DS1302_CLK = 0;d =d >> 1;}}unsigned char DS1302OutputByte(void) //实时时钟读取⼀字节(内部函数){unsigned char i,a;for(i=8; i>0; i--){a=a>>1;if(DS1302_IO)a=a|0X80;DS1302_CLK = 1;DS1302_CLK = 0;}return(a);}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;}unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据{unsigned char ucData;DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(ucAddr|0x01); // 地址,命令ucData = DS1302OutputByte(); // 读1Byte数据DS1302_CLK = 1;DS1302_RST = 0;return(ucData);}void DS1302_GetTime(SYSTEMTIME *Time) //将压缩BCD码转换成⼗进制形式{unsigned char ReadValue;ReadValue = Read1302(DS1302_SECOND);Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);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_MONTH);Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_WEEK);Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_YEAR);Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);}void DateToStr(SYSTEMTIME *Time){Time->DateString[0] = Time->Year/10 + '0';Time->DateString[1] = Time->Year%10 + '0';Time->DateString[2] = '-';Time->DateString[3] = Time->Month/10 + '0';Time->DateString[4] = Time->Month%10 + '0';Time->DateString[5] = '-';Time->DateString[6] = Time->Day/10 + '0';Time->DateString[7] = Time->Day%10 + '0';Time->week_value[0] = Time->Week%10 + '0'; //星期的数据另外放到 week_value[]数组⾥Time->week_value[1] = '\0';Time->DateString[8] = '\0'; //字符串末尾加 '\0' ,判断结束字符}void TimeToStr(SYSTEMTIME *Time){Time->TimeString[0] = Time->Hour/10 + '0';Time->TimeString[1] = Time->Hour%10 + '0';Time->TimeString[2] = ':';Time->TimeString[3] = Time->Minute/10 + '0';Time->TimeString[4] = Time->Minute%10 + '0';Time->TimeString[5] = ':';Time->TimeString[6] = Time->Second/10 + '0';Time->TimeString[7] = Time->Second%10 + '0';Time->TimeString[8] = '\0';}void Set_DS1302(SYSTEMTIME *Time){unsigned char time_date[7];unsigned char num;time_date[0] = Time->Second;time_date[1] = Time->Minute;time_date[2] = Time->Hour;time_date[3] = Time->Day;time_date[4] = Time->Month;time_date[5] = Time->Week;time_date[6] = Time->Year;for(num=0;num<7;num++) //将⼗进制数转换成压缩BCD码形式{time_date[num] = time_date[num]/10*16+time_date[num]%10; }Write1302(0x8E,0x00); //允许写Write1302(DS1302_SECOND,time_date[0]); //秒Write1302(DS1302_MINUTE,time_date[1]); //分Write1302(DS1302_HOUR, time_date[2]); //时Write1302(DS1302_DAY, time_date[3]); //⽇Write1302(DS1302_MONTH, time_date[4]); //⽉Write1302(DS1302_WEEK, time_date[5]); //周Write1302(DS1302_YEAR, time_date[6]); //年Write1302(0x8E,0x80); //禁⽌写}#endif。

stm32驱动DS1302

stm32驱动DS1302

stm32驱动DS1302//DS1302.H#ifndef __DS1302_H#define __DS1302_H#include "stm32f10x.h"//*****************DS1302控制命令*******************#define RdSec 0x81#define RdMin 0x83#define RdHour 0x85#define RdDate 0x87#define RdMonth 0x89#define RdWeek 0x8b#define RdYear 0x8d#define RdControl 0x8f#define RdTrickleCharge 0x91#define RdClockBurst 0xbf#define WrSec 0x80#define WrMin 0x82#define WrHour 0x84#define WrDate 0x86#define WrMonth 0x88#define WrWeek 0x8a#define WrYear 0x8c#define WrControl 0x8e#define WrTrickleCharge 0x90#define WrClockBurst 0xbe//对应IO口配置#define DS1302_IORCC RCC_APB2Periph_GPIOC //DS18B20对应IO的时钟#define DS1302_PORT GPIOC#define DS1302_SCK_PIN GPIO_Pin_15 //定义DS18B20对应的IO口#define DS1302_IO_PIN GPIO_Pin_13#define DS1302_CE_PIN GPIO_Pin_14#define DS1302_CLRSCK() (GPIOC->BRR = DS1302_SCK_PIN) //寄存器操作IO状态#define DS1302_SETSCK() (GPIOC->BSRR = DS1302_SCK_PIN)#define DS1302_CLRIO() (GPIOC->BRR = DS1302_IO_PIN)#define DS1302_SETIO() (GPIOC->BSRR = DS1302_IO_PIN) #define DS1302_CLRCE() (GPIOC->BRR = DS1302_CE_PIN)#define DS1302_SETCE() (GPIOC->BSRR = DS1302_CE_PIN) #define DS1302_READ_SDA() (GPIO_ReadInputDataBit(DS1302_PORT, DS1302_IO_PIN)) //定义时间的结构体typedef struct{u8 year;u8 month;u8 date;u8 week;u8 hour;u8 min;u8 sec;}TIME_TypeDef;//内部函数void DS1302_Write8bit(u8 code);u8 DS1302_Read8bit(void);//外部函数void delay_us(u8 us);void RTC_init (void);u8 DS1302_ReadByte(u8 con);void DS1302_WriteByte(u8 con,u8 code);void DS1302_WrintTime(TIME_TypeDef* time);void DS1302_ReadTime(TIME_TypeDef* time);void DS1302_IO_OUT(void);void DS1302_IO_IN(void);u8 NumT oBCD(u8 Num);u8 BCDT oNum(u8 BCD);void time_set();#endif /* __DS1302_H *///DS1302.C#include "stm32f10x.h"#include "DS1302.h"TIME_TypeDef rtc_time={0};//DS1302初始化函数void RTC_init (void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(DS1302_IORCC, ENABLE );GPIO_InitStructure.GPIO_Pin = (DS1302_SCK_PIN | DS1302_IO_PIN | DS1302_CE_PIN);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_Init(DS1302_PORT, &GPIO_InitStructure);DS1302_WriteByte(WrControl,0x00); //关闭写保护,可以写入数据delay_us(10);if(DS1302_ReadByte(RdTrickleCharge) != 0xA6){delay_us(10);DS1302_WriteByte(WrTrickleCharge,0xA6);}delay_us(10);DS1302_WriteByte(WrControl,0x80); //开启写保护,禁止写入数据}//DS1302?8bitvoid DS1302_Write8bit(u8 code){u8 i;DS1302_IO_OUT();DS1302_CLRSCK();for(i=0;i<8;i++){delay_us(5);if(code&0x01) (DS1302_SETIO());else (DS1302_CLRIO());delay_us(5);DS1302_SETSCK();delay_us(5);DS1302_CLRSCK();code = code >> 1;}}//DS1302?8bitu8 DS1302_Read8bit(void){u8 i,code;DS1302_IO_IN();code=0;DS1302_CLRSCK();delay_us(5);for(i=0;i<8;i++){code = code >>1;if(DS1302_READ_SDA()) code = code|0x80; delay_us(5);DS1302_SETSCK();delay_us(5);DS1302_CLRSCK();}return code;}//读DS1302指定的1Byteu8 DS1302_ReadByte(u8 con){u8 code;DS1302_CLRCE(); //关闭DS1302delay_us(5);DS1302_CLRSCK();delay_us(5);//DS13CLK =0;DS1302_SETCE(); //使能DS1302delay_us(5);DS1302_Write8bit(con); //读代码code=DS1302_Read8bit(); //返回读取的数字delay_us(5);DS1302_SETSCK();delay_us(5);DS1302_CLRCE(); //关闭DS1302return code;}//?DS13021Bytevoid DS1302_WriteByte(u8 con,u8 code){DS1302_CLRCE(); //关闭DS1302delay_us(5);DS1302_CLRSCK();delay_us(5);//DS13CLK =0;DS1302_SETCE(); //使能DS1302delay_us(5);DS1302_Write8bit(con); //写控制命令DS1302_Write8bit(code); //写入数据delay_us(5);DS1302_SETSCK();delay_us(5);DS1302_CLRCE(); //关闭DS1302}//写入时间void DS1302_WrintTime(TIME_TypeDef* time) {DS1302_WriteByte(WrControl,0x00); //关闭写保护DS1302_WriteByte(WrYear,time->year);DS1302_WriteByte(WrMonth,time->month); DS1302_WriteByte(WrDate,time->date);DS1302_WriteByte(WrWeek,time->week);DS1302_WriteByte(WrHour,time->hour);DS1302_WriteByte(WrMin,time->min);DS1302_WriteByte(WrSec,time->sec);DS1302_WriteByte(WrControl,0x80); //开启写保护,禁止写入数据}//读出时间void DS1302_ReadTime(TIME_TypeDef* time){time->year = DS1302_ReadByte(RdYear);time->month = DS1302_ReadByte(RdMonth);time->date = DS1302_ReadByte(RdDate);time->week = DS1302_ReadByte(RdWeek);time->hour = DS1302_ReadByte(RdHour);time->min = DS1302_ReadByte(RdMin);time->sec = DS1302_ReadByte(RdSec);}void delay_us(u8 us){while(us--){__NOP();}}void DS1302_IO_OUT(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = DS1302_IO_PIN ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_Init(DS1302_PORT, &GPIO_InitStructure);void DS1302_IO_IN(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = DS1302_IO_PIN ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_Init(DS1302_PORT, &GPIO_InitStructure);}//**数值转化为BCD码u8 NumT oBCD(u8 Num){return (Num/10)<<4 | (Num%10);}//***BCD码转化为数值u8 BCDT oNum(u8 BCD){return ((BCD&0x70)>>4)*10 + (BCD&0x0F);}void time_set(){rtc_time.year=NumToBCD(14);rtc_time.month=NumT oBCD(3);rtc_time.date=NumToBCD(12);rtc_time.hour=NumToBCD(21);rtc_time.min=NumToBCD(23);rtc_time.week=NumToBCD(3);rtc_time.sec=NumToBCD(30);DS1302_WrintTime(&rtc_time);// DS1302_ReadTime(&rtc_time);// rt_kprintf("20%d年%d月%d日星期%d\r\n",BCDT oNum(rtc_time.year),BCDToNum(rtc_time.month ),BCDT oNum(rtc_time.date),r tc_time.week);//rt_kprintf("%d : %d : %d\r\n",BCDT oNum(rtc_time.hour),BCD ToNum(rtc_time.min),BCDToNu m(rtc_time.sec));// rt_thread_delay( RT_TICK_PER_SECOND*5); /* sleep 0.5 second and switch to other thread */。

DS1302时钟和RAM数据区存数据

DS1302时钟和RAM数据区存数据
#define CFG_TC_DISABLED0x00//Disabled(TCS<>1010 or DS=00 or RS=00)
//RAM命令
#define CMD_RAM_BASE0xC0//RAM0~RAM30<<1地址需左移一位
#define CMD_RAM_BURST0xFE//连续读取
#define CFG_UNPROTECT0x00//写保护控制位CONTROLbit7允许写入
//涓流充电控制常量
#define CFG_TC_D1R20xA5//high 1 Diode +2K Resistors
#define CFG_TC_D2R80xAB//low 2 Diodes+8K Resistors
//时钟配置常量
#define CFG_CLOCK_HALT0x80//停止时钟控制位SECONDbit7
#define CFG_12_240x80//12/24小时值选择位HOURbit7
#define CFG_AM_PM0x20//AP/PM位HOURbit5
#define CFG_PROTECT0x80//写保护控制位CONTROLbit7不能写入
Writer1302(SECW,Second&0x7f);//启动Writer1302(SECW,0x00);//启动
Writer1302(CONTROL,0X80);//8E//禁止写
}
/************************DS1302里面存数据******************************/
#define DS1302_DAT_L()DS1302_DAT = 0
//CLK管脚定义

DS1302菜鸟级讲解

DS1302菜鸟级讲解
第十:爆发寄存器?(Burst Mode)地址字节:0x92 这个寄存器的功能可以用软件来模拟,无视他把。
12.4 DS1302 的 RAM DS1302 真的很厚道,还设立了 31 个字节的 RAM 空间,RAM 空间的开始地址字节是 0x94。RAM 空间可以让使用着任意发挥,你可以把它当做外存储器,但是前提 DS1302 必须一直供电。要访问任意空间也很简单,如下表:
再重申一次,读一个字节和写一个字节是不一样,在 写一个字节 的时候,AVR 的 IO 口一 直保持输出状态,相反的在 读一个字节的时候 AVR 的 IO 口先是输出状态,然后是输入状 态,且必须改变时钟信号的顺序。(补充一点题外话,我在编辑时序的时候,由于疏忽了一 点“小错误”,后果却是很严重。)
12.3 DS1302 时钟|日期|控制|爆发寄存器 在介绍 DS1302 的时序图中不都是,先地址字节,然后数据字节码?那么地址字 节和数据字节又有什么关系呢?(看看下面的图)
我们一个一个寄存器来看吧:
第一:秒钟寄存器 地址字节;0x80 其实呀,我很佩服该芯片的设计人员,将芯片设计得很贴心,为什么呢?因为秒钟寄存 器,除了记 录秒钟以外,还控制了 DS1302 的时钟开关(晶振开始工作,或者晶振禁止 工作)。该位第 7 位 CH,当写入逻辑 1 时 DS1302 停止工作,时间的计时保持最后一次 的状态,如果写入逻辑 0 DS1302 则开始工作,时间从最后一次状态中继续计时。
慧净小店: 开发板超市:/hlmcu
慧争电子免费共享资料、欢迎复制共享、没有版权。 HJ-2G 多功能 AVR/51 二合一开发板学习笔记
上面的图说明了每个寄存器的定义和地址字节,而每个地址字节的 LSB 可以是 0 或者 1,逻辑 0 代 表写,逻辑 1 代表读。如果忽略每个地址字节的 LSB,十六进制则是 0x80+i,而 i 每一次累加 2。

DS1302芯片C语言程序

DS1302芯片C语言程序

#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:00unsigned 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 char table[]={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程序-stm32

ds1302程序-stm32

/****************************************************************************** * @ File name --> <strong><font color="#FF0000">ds1302</font></strong>.c* @ Author --> By@ Sam Chan* @ Version --> V1.0* @ Date --> 08 - 23 - 2012* @ Brief --> 时钟芯片DS1302驱动** @ Copyright (C) 20*** @ All rights reserved******************************************************************************* ** File Update* @ Version --> V1.0.1* @ Author --> By@ Sam Chan* @ Date --> 10 - 20 - 2013* @ Revise --> A、增加对STM32控制的移植支持* @ --> B、增加对内置的RAM操作相关函数* @ --> C、增加检测DS1302是否存在,是否第一次上电检测函数* @ --> D、增加对DS1302内置的锂电池充电寄存器参数设置函数和结构体*******************************************************************************/ #include "ds1302.h"/****************************************************************************** 定义变量******************************************************************************/ #define Date TimeValue.date#define Min TimeValue.minute#define Sec TimeValue.second#define Hour TimeValue.hour#define Week TimeValue.week#define Month TimeValue.month#define Year TimeValue.yearTime_Typedef TimeValue; //定义时间数据指针void Time_Init(){TimeValue.date=24;TimeValue.hour=6;TimeValue.minute=12;TimeValue.month=5;TimeValue.second=0;TimeValue.week=2;TimeValue.year=16;}Charge_Typedef ChargeValue; //定义充电寄存器/****************************************************************************** * Function Name --> GPIO初始化* Description --> none* Input --> none* Output --> none* Reaturn --> none******************************************************************************/void DS1302_GPIOInit(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //开启GPIOC外设时钟/* 初始化GPIOC */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);}/****************************************************************************** * Function Name --> DS1302写入一个字节数据* Description --> none* Input --> dat:要写入的数据* Output --> none* Reaturn --> none******************************************************************************/ void DS1302_Write_Byte(u8 dat){u8 i;DS1302_SDA_OUT(); //设置为输出口for(i=0;i<8;i++){DS1302_SCL = 0; //时钟线拉低if(dat & 0x01) DS1302_SDA = 1; //数据线放上数据,先发低位else DS1302_SDA = 0;dat >>= 1; //数据右移一位DS1302_SCL = 1; //发送数据,上升沿有效}}/****************************************************************************** * Function Name --> DS1302读出一个字节数据* Description --> none* Input --> none* Output --> none* Reaturn --> 读到的数据******************************************************************************/ unsigned DS1302_Read_Byte(){u8 ReData=0x00;u8 i;DS1302_SDA_IN(); //设置为输入口for(i=0;i<8;i++){if(DS1302_IN_SDA == 1){ ReData |= 0x80; } //读出一位数据是“1”DS1302_SCL = 0; //时钟线拉低ReData >>= 1; //数据右移一位,先读取低位,数据补“0”DS1302_SCL = 1; //上升沿读取数据}return(ReData); //返回读取到的数据}/****************************************************************************** * Function Name --> 向DS1302某地址写入数据* Description --> none* Input --> add:要操作的地址* dat:要写入的数据* Output --> none* Reaturn --> none******************************************************************************/ void DS1302_Write_Data(u8 add,u8 dat){DS1302_RST = 0; //复位脚拉低DS1302_SCL = 0; //时钟线拉低DS1302_RST = 1; //复位脚拉高DS1302_Write_Byte(add); //写入要操作地址DS1302_Write_Byte(dat); //写入数据//delay_us(5);DS1302_RST = 0;DS1302_SCL = 0;}* Function Name --> 从DS1302某地址读取数据* Description --> none* Input --> add:要操作的地址* Output --> none* Reaturn --> 要读取的寄存器的数值******************************************************************************/ unsigned DS1302_Read_Data(u8 add){u8 Temp;DS1302_RST = 1;DS1302_Write_Byte(add); //写入要操作地址Temp = DS1302_Read_Byte(); //开始读取数据DS1302_RST = 0;return(Temp); //返回读取到的数据}/****************************************************************************** * Function Name --> 主电源对备用电池充电设置* Description --> 如果备用电池接的是可充电的锂电池或者其他可充电电池的时候,* 可以打开DS1302的充电电路,利用主供电对电池进行充电,免的换电池的麻烦* Input --> *CHG_dat:寄存器控制指针* Output --> none* Reaturn --> none******************************************************************************/ void DS1302_Charge_Manage(Charge_Typedef* CHG_dat){u8 CHG_Value;CHG_Value = (CHG_dat->TCSx << 4) | (CHG_dat->DSx << 2) | CHG_dat->RSx;DS1302_WP_Disable(); //取消写保护DS1302_Write_Data(Trickle_Charger_Address,CHG_Value);DS1302_WP_Enable(); //打开写保护}/****************************************************************************** * Function Name --> DS1302内置的RAM读写操作* Description --> none* Input --> *pBuff:读写数据存放区* WRadd:读写起始地址,范围在RAM_Address0 ~ RAM_Address28之间,最后一位地址有其他用途* num:读写字节数据的数量,范围在1 ~ 28之间* RW:读写判断位。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
void DS1302_SetProtect(bit flag) //是否写保护
{
if(flag)
Write_DS1302(0x8E,0x10);
else
Write_DS1302(0x8E,0x00);
}
uchar tran_input(uchar value)//输入数据入转换函数
ri=Tran_Output((Read_DS1302(0x87)));//日
shi=Tran_Output((Read_DS1302(0x85)));//时
fen=Tran_Output((Read_DS1302(0x83)));//分
miao=Tran_Output((Read_DS1302(0x81)));//秒
sbit scl=P3^2; // DS1302 同步时钟位 将P3^2改为你实际连接的单片机引脚
sbit sda=P3^3; // DS 1302 数据位 将P3^2改为你实际连接的单片机引脚
sbit rst=P3^4; // DS 1302 使能端 将P3^2改为你实际连接的单片机引脚
/*------------------------------------------------*/
#ifndef __DS1302_H__
#define __DS1302_H__
#define uchar unsigned char
uchar nian,yue,ri,shi,fen,miao,xingqi; //定义 年 月 日 时 分 秒 星期。
DS1302_SetTime(0x86,ri);//设置日
DS1302_SetTime(0x84,shi);//设置时
DS1302_SetTime(0x82,fen);//设置分
DS1302_SetTime(0x80,miao);//设置秒
DS1302_SetTime(0x8a,xingqi);//设置星期
}
}
uchar Read_DS1302(uchar Addr)//读取DS1302某地址的数据
{
unsigned char ucData;
rst = 0;
scl = 0;
rst = 1;
DS1302_InputByte(Addr|0x01); // 地址,命令
{
DS1302_SetProtect(0);
Write_DS1302(Address, tran_input(value));
}
void Init_DS1302(void)//初始化芯片
{
uint i;
for(i=0;i<5000;i++); // 初始化芯片必需延时,时间可以自行设定。
/*=======================================================*/
/*将文件保存为DS1302.H */
/*------------------------------------------------*/
/* ----------------七星电脑-----------------------*/
xingqi=Tran_Output((Read_DS1302(0x8b)));//星期
}
sjsd() //设定时间一个二极管加2K电阻充电。
{
DS1302_SetTime(0x8c,nian);//设置年 只取后2位
DS1302_SetTime(0x88,yue);//设置月
Write_DS1302(0x90,0xa5);//设置充电
}
#endif
{
return ((value/10)*16) | (value%10);
}
uchar Tran_Output(uchar value) //读出数据转换
{
return (((value/16)*10)+(value%16));
}
void DS1302_SetTime(uchar Address, uchar value) // 设置时间函数
ucData = DS1302_OutputByte();// 读1Byte数据
scl = 1;
rst = 0;
return(ucData);
}
void Write_DS1302(uchar Addr,uchar ucDa) //Addr: DS1302地址, ucData: 要写的数据
uchar DS1302_OutputByte(void) //读取1302数据
{
uchar value,i;
value=0;
for (i=8;i>0;i--){ value= value>>1;
if (sda==1){ value= value|0x80;}
scl=1;scl=0; }
{
rst = 0;
scl = 0;
rst = 1;
DS1302_InputByte(Addr); // 地址,命令
DS1302_InputByte(ucDa); // 写1Byte数据
scl = 1;
rst = 0;
uchar Second=Read_DS1302(0x81); //如果读取的秒数大于60秒 将秒设为1秒,CH位只要为1,读出的秒数肯定大于60。
if (Second>0x60)
{
DS1302_SetTime(0x8c,11);//设置年 只取后2位
DS1302_SetTime(0x88,11);//设置月
Write_DS1302(0x90,0xa5);//设置充电
}
}
void hqtm() // 读1302时间
{
nian=Tran_Output((Read_DS1302(0x8d)));//年 只取后2位
yue=Tran_Output((Read_DS1302(0x89)));//月
/* -------------TEL:15852371943-------------------*/
/* --- ------- ----------------*/
/* --------------适用于: DS1302 ------------------*/
DS1302_SetTime(0x86,3);//设置日
DS1302_SetTime(0x84,18);//设置时
DS1302_SetTime(0x82,53);//设置分
DS1302_SetTime(0x80,0);//设置秒
DS1302_SetTime(0x8a,4);//设置星期
return value;
}
void DS1302_InputByte(uchar value)//写入数据到1302
{
uchar i;
for (i=8;i>0;i--)
{
sda=value&0x01;
scl=1;
scl=0;
value=Leabharlann alue>>1;
相关文档
最新文档