51单片机DS1302日历时钟程序
- 格式:doc
- 大小:65.50 KB
- 文档页数:9
采用51单片机控制的DS1302时钟程序/*********************************************************************/ /* 实时时钟模块时钟芯片型号:DS1302 *//*//*********************************************************************/ sbit T_CLK = P2^7; /*实时时钟时钟线引脚 */sbit T_IO = P1^4; /*实时时钟数据线引脚 */sbit T_RST = P1^5; /*实时时钟复位线引脚 *//******************************************************************** ** 名称: v_RTInputByte* 说明:* 功能: 往DS1302写入1Byte数据* 调用:* 输入: ucDa 写入的数据* 返回值: 无***********************************************************************/ void v_RTInputByte(uchar ucDa){uchar i;ACC = ucDa;for(i=8; i>0; i--){T_IO = ACC0; /*相当于汇编中的 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 */ACC7 = 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: 初始时间地址。
#include <reg52.h>#include <intrins.h>#include <string.h>#define uint unsigned int#define uchar unsigned charsbit led = P2^3;//led代替闹铃sbit IO = P1^3; //定义1302管脚//6sbit SCLK = P1^4;//7sbit RST = P1^5; //5sbit RS = P2^2;//定义1602管脚sbit RW = P2^1;sbit EN = P2^0;sbit key1=P3^4;//选择//调时键盘sbit key2=P3^5;//加sbit key3=P3^6;//减sbit key4=P3^7;//确定sbit key11=P1^6;//选择//闹钟键盘sbit key22=P1^7;//加sbit key33=P3^0;//减sbit key44=P3^1;//确定uchar x1=0,x;int hour=8,minute=0;//闹钟的初始时间8:00uchar DateTime[9]; //秒,分,时,日,周,月,年 address,uchar lcd1[]={"DATE 00-00-00 "};uchar lcd2[]={"TIME 00:00:00 "};/***************延时*************/void delayms(uchar x)//延时毫秒程序{ uchar i,j;for(i=x;i>0;i--)for(j=110;j>0;j--);}void delayus(uchar x)//延时微秒程序{ uchar i;for(i=0;i<x;i++);}/********1302的驱动程序***********///写入数据,dat:要写入的数据void DS1302WriteByte(uchar dat){uchar i;SCLK=0;//初始时钟线置为0delayus(2);for(i=0;i<8;i++)//开始传输8个字节的数据{IO=dat&0x01;//取最低位,注意DS1302的数据和地址都是从最低位开始传输的delayus(2);SCLK=1;//时钟线拉高,制造上升沿,SDA的数据被传输delayus(2);SCLK=0;//时钟线拉低,为下一个上升沿做准备dat>>=1;//数据右移一位,准备传输下一位数据}}/********1302的驱动程序**********///功能: 读取数据,dat:读取的数据uchar DS1302ReadByte(){ uchar i;uchar dat;delayus(2);for(i=0;i<8;i++){dat>>=1;//要返回的数据左移一位if(IO==1)//当数据线为高时,证明该位数据为1dat|=0x80;//要传输数据的当前值置为1,若不是,则为0SCLK=1;//拉高时钟线delayus(2);SCLK=0;//制造下降沿delayus(2);}return dat;//返回读取出的数据/16*10+dat%16}/*********1302的驱动程序*********///从cmd相应地址中读取一个字节的数据uchar DS1302Read(uchar cmd)//cmd:要写入的控制字节,dat:读取的数据{uchar dat;RST=0;//初始CE线置为0SCLK=0;//初始时钟线置为0RST=1;//初始CE置为1,传输开始DS1302WriteByte(cmd);//传输命令字,要读取的时间/日历地址dat=DS1302ReadByte();//读取要得到的时间/日期SCLK=1;//时钟线拉高RST=0;//读取结束,CE置为0,结束数据的传输return dat;//返回得到的时间/日期}/**********1302的驱动程序*********///向cmd相应地址中写一个字节的数据void DS1302Write(uchar cmd, uint dat)//cmd:要写入的控制字,dat:要写入的数据{RST=0; //初始CE线置为0SCLK=0; //初始时钟线置为0RST=1; //初始CE置为1,传输开始DS1302WriteByte(cmd); //传输命令字,要写入的时间/日历地址DS1302WriteByte(dat); //写入要修改的时间/日期SCLK=1; //时钟线拉高RST=0; //读取结束,CE置为0,结束数据的传输}/*************初始化ds1302********///给1302写入日期和时钟的值void chushihuaDS1302(void){DS1302Write(0x8e,0x00);//写保护关DS1302Write(0x80,0x10); //初始秒DS1302Write(0x82,0x02);//初始分钟DS1302Write(0x84,0x15); //初始为24小时模式,初始时DS1302Write(0x86,0x01); //1日DS1302Write(0x88,0x08);//8月DS1302Write(0x8c,0x13);//2013年DS1302Write(0x8a,0x04);//星期4// DS1302Write(0x90,0x01); //充电//DS1302Write(0xc0,0xf0); //初始化一次标示//DS1302Write(0x8e,0x80);//写保护开}/************以下是1602的程序******************//******************************///向1602内写命令void write_order(uchar order){RS=0;P0=order;delayms(5);EN=1;delayms(5);EN=0;}/******************************///向1602内写数据void write_date(uchar date){RS=1;P0=date;delayms(5);EN=1;delayms(5);EN=0;}/******************************///lcd1602的初始化void chushihuaLCD1602(){ EN=0;write_order(0x38);write_order(0x0c);write_order(0x06);write_order(0x01);}/*************其他操作*****************/void gettime(){ uchar i,n;for(i=0,n=1;i<7,n<15;i++,n=n+2){ DateTime[i]=DS1302Read(0x80+n);delayus(1);}}void zhuanhuan(){ gettime();lcd1[5]=((DateTime[6]>>4)+0x30);lcd1[6]=((DateTime[6]&0x0f)+0x30);delayus(2);//年lcd1[14]=((DateTime[5]>>4)+0x30);lcd1[15]=((DateTime[5]&0x0f)+0x30);delayus(2);//周lcd1[11]=((DateTime[3]>>4)+0x30);lcd1[12]=((DateTime[3]&0x0f)+0x30);delayus(2);//日lcd1[8]=((DateTime[4]>>4)+0x30);lcd1[9]=((DateTime[4]&0x0f)+0x30);delayus(2);//月lcd2[5]=((DateTime[2]>>4)+0x30);lcd2[6]=((DateTime[2]&0x0f)+0x30);delayus(2);//时lcd2[8]=((DateTime[1]>>4)+0x30);lcd2[9]=((DateTime[1]&0x0f)+0x30);delayus(2);//分lcd2[11]=((DateTime[0]>>4)+0x30);lcd2[12]=((DateTime[0]&0x0f)+0x30);delayus(2);//秒if(DateTime[7]==DateTime[2] & DateTime[8]==DateTime[1]){led = 1;delayms(150);led = 0;}/**/}/***********************/void jianpan() //键盘调时{ uchar x2,address,max,min;int item;if(key1==0){ delayms(10);if(key1==0){ x1++;if(x1>=7) x1=1;switch(x1){ case 1: lcd2[15]='Y';x2=1;address=0x8c; max=99;min=0;break;//年case 2: lcd2[15]='M';x2=2;address=0x88; max=12;min=1;break;//月case 3: lcd2[15]='D';x2=3;address=0x86; max=31;min=1;break;//天case 4: lcd2[15]='H';x2=4;address=0x84; max=23;min=0;break;//时case 5: lcd2[15]='F';x2=5;address=0x82; max=59;min=0;break;//分case 6: lcd2[15]='W';x2=6;address=0x8A; max=7;min=1;break;//周}}while(!key1);}item=(DS1302Read(address+1)/16)*10 + (DS1302Read(address+1))%16;if(key2==0){ delayms(10);if(key2==0){ if(x2==1) {item++;}else if(x2==2) {item++;}else if(x2==3) {item++;}else if(x2==4) {item++;}else if(x2==5) {item++;}else if(x2==6) {item++;}}while(!key2);}if(key3==0){ delayms(10);if(key3==0){ if(x2==1) {item--;}else if(x2==2) {item--;}else if(x2==3) {item--;}else if(x2==4) {item--;}else if(x2==5) {item--;}else if(x2==6) {item--;}}while(!key3);}if(key4==0){ delayms(10);if(key4==0){ lcd2[15]=' ';x1=0;x2=0;}while(!key4);}//led=0;delayms(5000);led=1;if(item>max) item=min;if(item<min) item=max;DS1302Write(0x8e,0x00);//允许写操作delayms(10);DS1302Write(address,(item/10)*16+item%10); //写入DS1302 //转成BCD码delayms(20);DS1302Write(0x8e,0x80);//写保护,禁止写操作}void naozhong()//设定闹钟{ uchar da,xiao,i;if(key11==0){ delayms(10);if(key11==0){ x++;if(x>=4) x=1;switch(x){case 2: lcd2[13]='H';i=1;da=23;xiao=0;lcd2[14]=((hour>>4)+0x30);lcd2[15]=((hour&0x0f)+0x30);delayus(2);break;//时case 1: lcd2[13]='M';i=2;da=59;xiao=0;lcd2[14]=((minute>>4)+0x30);lcd2[15]=((minute&0x0f)+0x30);delayus(2);break;//分case 3: lcd2[13]=' ';lcd2[14]=' ';lcd2[15]=' ';x=0;i=0;break;}}while(!key11);}if(key22==0){ delayms(10);if(key22==0){ if(i==1){ hour=((hour/16)*10)+(hour%16);hour++;if(hour>da) hour=xiao;hour=(hour/10)*16+hour%10;lcd2[14]=((hour>>4)+0x30);lcd2[15]=((hour&0x0f)+0x30);delayus(2);}else if(i==2){ minute=((minute/16)*10)+(minute%16);minute++;if(minute>da) minute=xiao;minute=(minute/10)*16+minute%10;lcd2[14]=((minute>>4)+0x30);lcd2[15]=((minute&0x0f)+0x30);delayus(2);}}while(!key22);}if(key33==0){ delayms(10);if(key33==0){ if(i==1){ hour=((hour/16)*10)+(hour%16);hour--;if(hour<xiao) hour=da;hour=(hour/10)*16+hour%10;lcd2[14]=((hour>>4)+0x30);lcd2[15]=((hour&0x0f)+0x30);delayus(2);}else if(i==2){ minute=((minute/16)*10)+(minute%16);minute--;if(minute<xiao) minute=da;minute=(minute/10)*16+minute%10;lcd2[14]=((minute>>4)+0x30);lcd2[15]=((minute&0x0f)+0x30);delayus(2);}}while(!key33);}DateTime[7]=hour;DateTime[8]=minute;}/**/void wzd0() interrupt 0//外部中断0{jianpan();//}void wzd1() interrupt 2//外部中断1{naozhong();}void main(){uchar k;EA=1;EX0=1;IT0=1;PX0=1;EX1=1;IT1=1;PX1=0;RW=0;led=0;chushihuaLCD1602();if( (DS1302Read(0x81) & 0x80) ) chushihuaDS1302();//chushihuaDS1302();while(1){zhuanhuan();write_order(0x80);//lcd的第一行for(k=0;k<16;k++){ write_date(lcd1[k]);delayus(2);}write_order(0x80+0x40);//lcd的第二行for(k=0;k<16;k++){ write_date(lcd2[k]);delayus(2);}}}。
51单⽚机ds1302实时时钟程序#ifndef __DS1302_H_#define __DS1302_H_//---包含头⽂件---//#include#include//---重定义关键词---//#ifndefuchar#define uchar unsigned char#endif#ifndefuint#define uint unsigned int#endif//---定义ds1302使⽤的IO⼝---//sbit DSIO=P3^4;sbit RST=P3^5;sbit SCLK=P3^6;//---定义全局函数---//void Ds1302Write(ucharaddr, uchardat); uchar Ds1302Read(ucharaddr);void Ds1302Init();void Ds1302ReadTime();//---加⼊全局变量--//extern uchar TIME[7]; //加⼊全局变量#endif #include"ds1302.h"//---DS1302写⼊和读取时分秒的地址命令---////---秒分时⽇⽉周年最低位读写位;-------//uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};//---DS1302时钟初始化2013年1⽉1⽇星期⼆12点00分00秒。
---////---存储顺序是秒分时⽇⽉周年,存储格式是⽤BCD码---//uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01, 0x02, 0x13};/************************************************************************ * 函数名: Ds1302Write* 函数功能: 向DS1302命令(地址+数据)* 输⼊: addr,dat* 输出: ⽆************************************************************************* void Ds1302Write(ucharaddr, uchardat){uchar n;RST = 0;_nop_();SCLK = 0;//先将SCLK置低电平。
#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit lcdws=P2X; 〃1602 管脚定义sbit Icde n=P2P;sbit Icdrs=P2A2;sbit key仁卩2人3; //闹钟设置键sbit key2=P2A4;sbit key3=P1A5;〃功能键定义sbit key4=P1A6;〃增大键定义sbit key5=P1A7;〃减小键定义uchar shi,fen,miao,ashi,afen,amiao,year,month,day,week; uchar s1num=0,s1num2=0,temp;bit flag;float f_temp;uint i,d;uchar code table2[]={0x20,0x20,0x2e,0x20,0xdf,0x43};uchar code table[]="20 - - ";uchar code table1[]=" : : ";sbit ds=P1A0;//ds18b20 信号线sbit beep=P1A4; // 蜂鸣器管脚定义sbit ACC_7 = ACCA7; //位寻址寄存器定义sbit SCLK = P1A2; // DS1302 时钟信号sbit DIO= P1A1; // DS1302 数据信号sbit CE = P1A3;//地址、数据发送子程序//void delay2(uint ms)// {// uchar t;// while(ms--); for(t=0;t<120;t++);//}// void playmusic()// {// uint i2=0,j2,k2;// while(jiepai[i2]!=0||song[i2]!=0)// {// for(j2=0;j2<jiepai[i2]*20;j2++)// {// beep=~beep;// for(k2=0;k2<song[i2]/3;k2++);// }// delay2(10);// i2++;// }// }void write_1302( uchar addr,uchar dat ) {uchar i,temp;CE=0; SCLK=0;//CE 引脚为低,数据传送中止// 清零时钟总线CE = 1; //CE 引脚为高,逻辑控制有效// 发送地址for ( i=8; i>0; i-- ) // 循环8 次移位{SCLK = 0; temp = addr;DIO = (bit)(temp&0x01);addr >>= 1;SCLK = 1;}// 发送数据for ( i=8; i>0; i-- ){SCLK = 0; temp = dat;DIO = (bit)(temp&0x01);dat >>= 1;SCLK = 1;}CE = 0;}// 数据读取子程序uchar Read1302 ( uchar addr ){unsigned char i,temp,dat1,dat2;CE=0;SCLK=0;CE = 1;// 发送地址for ( i=8; i>0; i-- ){SCLK = 0; temp = addr;DIO = (bit)(temp&0x01);addr >>= 1;// 每次传输低字节// 右移一位// 循环8 次移位// 每次传输低字节// 右移一位SCLK = 1;}// 读取数据 for ( i=8; i>0; i-- ){ACC_7=DIO; SCLK = 1; ACC>>=1; SCLK = 0;}CE=0;dat1=ACC; dat2=dat1/16;// 十六进制转十进制 dat1=dat1%16; dat1=dat1+dat2*10; return (dat1);}// 初始化 DS1302void Initial(void) // 初始化 1302 {write_1302 (0x8e,0x00);write_1302 (0x80,0x56); write_1302 (0x82,0x58); write_1302 (0x84,0x23); write_1302 (0x86,0x30); write_1302 (0x88,0x09); write_1302 (0x8c,0x10); write_1302 (0x8a,0x01); write_1302 (0x8e,0x80);void delay(uint z)// 延时 1ms{uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--);}void write_com(uchar com)//1602 写命令 {lcdrs=0; lcden=0; P0=com; delay(5); lcden=1; delay(5); lcden=0;}void write_data(uchar date)//1602 写数据{ lcdrs=1; lcden=0; P0=date; delay(5); lcden=1; delay(5); lcden=0;}void dsreset(void) //DS18B20 ,初始化函数{ uint i; ds=0; i=103; while(i>0)i--; ds=1; i=4; while(i>0)i--;}// 数据进制转换2010 年 09 月 30 日 23 点 58 分 56 秒 星期一// 允许写保护 // 秒位初始化 // 分钟初始化 // 小时初始化 // 日初始化// 月初始化 // 年初始化 // 日期始化 // 禁止写保护bit tempreadbit(void)// 读1 位数据函数{ uint i; bit dat; ds=0;i++; ds=1;i++;i++;//i++ 起到延时作用dat=ds; i=8;while(i>0)i--; return(dat);}uchar tempread(void) // 读一个字节数据函数{uchar i,j,dat; dat=0; for(i=1;i<=8;i++) {j=tempreadbit(); dat=(j<<7)|(dat>>1);} return(dat);void tempwritebyte(uchar dat) // 向DS18B20 写一个字节数据函数{ uint i;uchar j;bit testb; for(j=1;j<=8;j++){ testb=dat&0x01; dat=dat>>1; if(testb)// 写1 { ds=0; i++;i++; ds=1;i=8;while(i>0)i--;}else{ds=0; // 写0i=8;while(i>0)i--;ds=1; i++;i++;}}}void tempchange(void) //DS18B20 开始获取温度并转换{dsreset();delay(1);tempwritebyte(0xcc);tempwritebyte(0x44);}uint get_temp() // 获取温度{uchar a,b;dsreset();delay(1);tempwritebyte(0xcc);tempwritebyte(0xbe); a=tempread(); // 读高8 位b=tempread(); // 读低8 位temp=b;temp<<=8; // 两个字节组合成1 个字节temp=temp|a;f_temp=temp*0.0625;temp=f_temp*10+0.5;f_temp=f_temp+0.05; // 温度在寄存器中为12 位,分辨率为0.0625人return temp;}void display(uchar addr,uchar dat){ write_com(0x80+0x40+addr); write_data(0x30+dat);delay(5);}void dis_temp(uint t){uchar i;i=t/100; display(10,i); i=t%100/10;display(11,i);i=t%100%10; display(13,i);}void init()// 初始化程序{uchar num;flag=1;lcden=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80); for(num=0;num<15;num++){ write_data(table[num]); delay(5);}write_com(0x80+0x40); for(num=0;num<8;num++){ write_data(table1[num]); delay(5);} write_com(0x80+0x40+10); for(num=0;num<6;num++){write_data(table2[num]); delay(10);}}void di()// 蜂鸣器响函数{beep=0;delay(100);beep=1;}void write_sfm(uchar add,uchar date){uchar shi,ge; shi=date/10;ge=date%10; write_com(0x80+0x40+add); write_data(0x30+shi);write_data(0x30+ge);}void write_nyrz(uchar add,uchar date)// 显示年,月,日,周{ uchar shi,ge;shi=date/10;ge=date%10; write_com(0x80+add); write_data(0x30+shi);write_data(0x30+ge);}void display_week(uchar we){write_com(0x80+12);switch(we){case 1: write_data('M');delay(5); write_data('O');delay(5);write_data('N'); break;case 2: write_data('T');delay(5); write_data('U');delay(5);write_data('E'); break;case 3: write_data('W');delay(5);write_data('E');delay(5);write_data('D');break;case 4: write_data('T');delay(5);write_data('H');delay(5);write_data('U');break;case 5: write_data('F');delay(5);write_data('R');delay(5);write_data('T');break;case 6: write_data('S');delay(5);write_data('A');delay(5);write_data('T');break;case 7: write_data('S');delay(5);write_data('U');delay(5);write_data('N');break;}}void keyscan()// 按键设置{if(key3==0)// 功能键按下{flag=0;delay(5);if(key3==0){s1num++;while(!key3);di();switch(s1num)// 光标闪烁定位{case 1:write_com(0x80+0x40+7);// 定位到秒的位置write_com(0x0f);break;case 2:write_com(0x80+0x40+4);// 定位到分的位置write_com(0x0f);break;case 3:write_com(0x80+0x40+1);// 定位到小时的位置write_com(0x0f);break;case 4:write_com(0x80+0x0e);// 定位到星期的位置if(s1num!=0)// 只有功能键按下后,增大, {if(key4==0)// 增大建{delay(5); if(key4==0){while(!key4); di();switch(s1num){case 1: miao++;if(miao==60) miao=0;write_sfm(6,miao); //write_1302(write_second ,miao);write_com(0x80+0x40+7); break;case 2: fen++;if(fen==60) fen=0;write_com(0x0f); break;case 5:write_com(0x80+0x9);// write_com(0x0f); break; case 6:write_com(0x80+0x6);// write_com(0x0f); break; case 7:write_com(0x80+0x3);// write_com(0x0f); break; case 8: s1num=0;// 复位,时钟走 write_com(0x0c); flag=1;write_1302 (0x8e,0x00); write_1302 (0x80,miao); write_1302 (0x82,fen); write_1302 (0x84,shi); write_1302 (0x86,day); write_1302 (0x88,month); write_1302 (0x8c,year); write_1302 (0x8a,week); write_1302 (0x8e,0x80); break;定位到日的位置定位到月的位置 定位到年的位置 // 允许写保护 // 秒位初始化 // 分钟初始化 // 小时初始化 // 日初始化// 月初始化 // 年初始化 // 日期始化 //禁止写Y增小建才有效write_sfm(3,fen);//write_1302(write_minute,fen);write_com(0x80+0x40+4);break;case 3: shi++;if(shi==24) shi=0;write_sfm(0,shi);write_com(0x80+0x40+1);break;case 4: week++;if(week==8)week=1;display_week(week);write_com(0x80+14);break;case 5: day++; if(day==31) day=1;write_nyrz(8,day);write_com(0x80+9); break;case 6: month++; if(month==13)month=1; write_nyrz(5,month);write_com(0x80+6); break;case 7: year++; if(year==99) year=0;write_nyrz(2,year);write_com(0x80+3); break;}}}if(key5==0)// 减小键{delay(5);if(key5==0){while(!key5);di();switch(s1num){case 1: miao--;if(miao==-1) miao=59;write_sfm(6,miao);write_com(0x80+0x40+7);break;case 2: fen--;if(fen==-1) fen=59;write_sfm(3,fen);write_com(0x80+0x40+4);break;case 3: shi--;if(shi==-1) shi=23;write_sfm(0,shi);write_com(0x80+0x40+1);break;case 4: week--;if(week==-1) week=7;display_week(week);write_com(0x80+14); break;case 5: day--;if(day==0) day=31;write_nyrz(8,day);write_com(0x80+9); break;case 6: month--;if(month==0) month=12;write_nyrz(5,month);write_com(0x80+6); break;case 7: year--;if(year==-1) year=99;write_nyrz(2,year);write_com(0x80+3); break;} }}}}void set_alarm(){if(key1==0)// 功能键按下{delay(5);if(key1==0){while(!key1);flag=0;s1num2++;write_sfm(6,amiao);write_com(0x80+0x40+7);write_sfm(3,afen);write_com(0x80+0x40+4);write_sfm(0,ashi);write_com(0x80+0x40+1);di();switch(s1num2)// 光标闪烁定位{case 1:write_com(0x80+0x40+7);// 定位到秒的位置write_com(0x0f);break;case 2:write_com(0x80+0x40+4);// 定位到分的位置write_com(0x0f); break;case 3:write_com(0x80+0x40+1);// 定位到小时的位置write_com(0x0f); break;case 4: s1num2=0;// 复位,时钟走write_com(0x0c);flag=1;write_1302(0x8e,0x00);// 允许写保护write_1302 //(0x8e,0x80);break;if(s1num2!=0)// 只有功能键按下后,增大,增小建才有效{ if(key2==0)// 增大建{delay(5);if(key2==0){while(!key2);di();switch(s1num2){case 1: amiao++;if(amiao==60) amiao=0;write_sfm(6,amiao);write_com(0x80+0x40+7);break;case 2: afen++;if(afen==60)afen=0; write_sfm(3,afen);write_com(0x80+0x40+4);break;case 3: ashi++;if(ashi==24)ashi=0; write_sfm(0,ashi);write_com(0x80+0x40+1);break;}}}WWWWWW-nma-()八-cdwsuainip-nfconfigurafiono 八CDmpchangeo 八fo r (ll'10v 0〒)宀dislCDmp(ge匚 empo)-w h =e 3宀keyscanoy 、^M ffl Bw h i -e ((k ey l QO QO k e y 2QO QO k e y 3QO QO k e y 4QO QO key 5)QO QO ((f e n u u a f e n )QO QO (s h ll'u a s h i )))beep"八if(f-agu") 宀miaouReach302(0X81)7/和引^wriCDlsfm(6ymiao)八fenuReach302(0X83)0和引Vwmelsfm(3fen=shll'Read」3o2(ox85)0 和引亠£4wriCDlsfm(Qshi)八dayuReach302(0X87)0和引mwriCDlnyrzGday)八monfhuReach302(0X89)7/和引出 w r i CD l n yrz(5 -monfh)八year"Reach302(0x8d)y/ 和引<wriCDlnyrz(2yyear)八weekuReacH302(0x8b)y/disp-aylweek(week)八e-sewrite_1302(0x80,0x80);// 时钟振荡器停止}set_alarm();WWW}}。
#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); //充电。
//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);}}}}。