51单片机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);
采用51单片机控制的DS1302时钟程序

采用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: 初始时间地址。
基于ds1302和LCD1602的日历时钟51单片机程序

#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实时时钟程序

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置低电平。
51单片机万年历实验DS1302可按键设置时钟

*选择设置加 1。
* 注意
:
*******************************************************************************
/
#include<reg51.h> #include"lcd.h" #include"ds1302.h"
sbit K1=P3^1; sbit K2=P3^0; sbit K3=P3^2; sbit K4=P3^3;
LcdInit();
Ds1302Init();
while(1)
{
if(SetState==0)
{
Ds1302ReadTime();
}
else
{ if(K1==0)
//检测按键 K1 是否按下
{ Delay10ms(); //消除抖动
if(K1==0)
{
SetPlace++;
if(SetPlace>=7)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////以下是 主文件 main.c 的内容
void Int0Configuration();
void LcdDisplay();
unsigned char SetState,SetPlace; void Delay10ms(void); //误差 0us
/******************************************************************************
51单片机实战指南-使用DS1302设计数字时钟

YEAR
WP
0
0
0 0000
本章内容:
1
DS1302芯片介绍
22 封装的编程思想和结构体类型
3 2
DS1302读写操作的编程实现
4
DS1302读写实战
12.2.1 封装的编程思想
➢ 封装是面向对象编程三大特性(封装、继承、多态)之一 ➢ 核心思想就是尽可能地隐藏内部的细节,只保留一些对外接
口使之与外部发生联系 ➢ 就C语言而言,封装的体现就是函数的编写(小封装)和模
} DS1302_CE = 0;
//传送数据结束
return dat;
}
12.3.2 读写函数的封装-DS1302WriteByte
/* 发送一个字节到DS1302通信总线上 */
void DS1302WriteByte(unsigned char dat)
{
unsigned char i;
for (i=0; i<8; i++)
bit 5
bit 4
bit 3
bit 2
bit 1
bit 0
1
RAM/CK A4
A3
A2
A1
A0
R/W
寄存器名
秒寄存器 分钟寄存器 小时寄存器 日期寄存器 月份寄存器 星期寄存器 年份寄存器 控制寄存器
命令字
写操作 读操作
80H
81H
82H
83H
84H
85H
86H
87H
88H
89H
8AH 8BH
8CH 8DH
12.4 DS1302读写实战-ds1302.c
void mai时间后会刷新显示
基于单片机DS1302的时钟万年历(带闹钟)

#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}}。
51单片机DS1302日历时钟程序

v_W1302(0x86,0x13); //设置日
v_W1302(0x84,0x18); //设置小时
v_W1302(0x82,0x05); //设置分
v_W1302(0x80,0x00); //启动晶振,设置秒
v_W1302(0x8e,0x80); //使能
v_W1302(0x80,second);
}
if(key0_count==2)
{
minute ++;
if(60==minute)
minute = 0;
write_add(0x40+7,minute);
v_W1302(0x82,minute);
}
if(key0_count==3)
{
hour ++;
if(24==hour)
uchar reverse(uchar c);
void keyscan();
void init();
void RTC_initial ();
void wr_1302(uchar wr_data);
uchar rd_1302(void);
uchar uc_R1302(uchar ucAddr);
void v_W1302(uchar ucAddr, uchar ucDa);
delay(1);
}
}
void RTC_initial ()
{
v_W1302(0x8e,0x00); //使能
v_W1302(0x80,0x80); //停止晶振
v_W1302(0x90,0x00); //关闭充电
v_W1302(0x8c,0x07); //设置年
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
write_cmd_1602(0x80+add);
write_data_1602(shi+0x30);
delay(5);
write_data_1602(ge+0x30);
}
//键盘扫描函数
void keyscan()
{
key4 = 0;
if(0==key0) //第一个键被按下
{
delay(5); //消抖
*名称: uc_R1302
*说明:先写地址,后读命令/数据
*功能:读取DS1302某地址的数据
*调用: v_RTInputByte() , uc_RTOutputByte()
*输入: ucAddr: DS1302地址
*返回值: ucDa :读取的数据
***********************************************************************/
uchar key0_count;//按键0被按的次数(0~3)
uchar flag;
char hour,minute,second;
uchar table_date[] = "2009-4-12Mon";
uchar table_time[] = "00:00:00";
/******函数申明********/
}
if(1==key0_count)
{
flag = 0;
write_cmd_1602(0x80+0x40+11);//将地址指针指向秒的位置
write_cmd_1602(0x0f); //显示光标并闪烁
delay(5);
}
if(2==key0_count)
{
flag = 0;
write_cmd_1602(0x80+0x40+8);//将地址指针指向分的位置
if (c&0x40) chbuff=chbuff|0x02;
if (c&0x80) chbuff=chbuff|0x01;
return chbuff;
}
//向液晶写命令
void write_cmd_1602(uchar cmd)
{
lcdrs = 0; //低表示写命令,高表示写数据
delay(5);
dat7 = io_1302;
clk_1302 = 1;
_nop_();
_nop_();
clk_1302 = 0;
_nop_();
}
rst_1302 = 0;
return dat;
}
/********************************************************************
uchar uc_R1302(uchar add)
{
uchar temp= 0xff;
wr_1302(add);
temp = rd_1302();
return temp;
}
/********************************************************************
*名称: v_W1302
*说明:先写地址,后写命令/数据
*功能:往DS1302写入数据
*调用: v_RTInputByte()
*输入: ucAddr: DS1302地址, ucDa:要写的数据
*返回值:无
**********************************************************************/
delay(1);
}
}
void RTC_initial ()
{
v_W1302(0x8e,0x00); //使能
v_W1302(0x80,0x80); //停止晶振
v_W1302(0x90,0x00); //关闭充电
v_W1302(0x8c,0x07); //设置年
v_W1302(0x8a,0x06); //设置周
hour = 0;
write_add(0x40+4,hour);
v_W1302(0x84,hour);
}
}
}
if(0==key2) //第三个键被按下
{
delay(5); //消抖
if(0==key2)
{
while(!key2); //松手检测
flag = 0;
if(key0_count==1)
{
second --;
51单片机ds1302时钟芯片
#define uint unsigned int
#define uchar unsigned char
sbit lcdrs = P1^0;
sbit P1^2;
sbit key0 = P2^0;//功能键,选择时分秒
sbit key1 = P2^1;//加1键
v_W1302(0x88,0x01); //设置月
v_W1302(0x86,0x13); //设置日
v_W1302(0x84,0x18); //设置小时
v_W1302(0x82,0x05); //设置分
v_W1302(0x80,0x00); //启动晶振,设置秒
v_W1302(0x8e,0x80); //使能
{
second = uc_R1302(0x81);
minute = uc_R1302(0x83);
hour = uc_R1302(0x85);
write_add(0x40+10,second);
write_add(0x40+7,minute);
write_add(0x40+4,hour);
}
keyscan();
}
/*****************************
*功能:往DS1302写入1Byte数据
*输入: wr_data写入的数据
*返回值:无
*******************************/
void wr_1302(uchar wr_data)
{
uchar i = 0;
dat = wr_data;
if(0==key0)
{
key0_count ++;
if(4==key0_count)
{
key0_count = 0;
flag = 1;
}
while(!key0); //松手检测
flag = 0;
if(0==key0_count)
{
flag = 0;
write_cmd_1602(0x0c); //禁止显示光标并不让其闪烁
void v_W1302(uchar ucAddr, uchar ucDa)
{
wr_1302(ucAddr);
wr_1302(ucDa);
rst_1302 = 0;
clk_1302 = 0;
}
//1602液晶初始化
void init1602()
{
lcdrw = 0; //本程序只读不写,故将其置低
lcden = 0; //关闭1602
*功能:从DS1302读出1Byte数据
*返回值: dat
*******************************/
uchar rd_1302(void)
{
uchar i;
rst_1302 = 1;
clk_1302 = 1;
delay(5);
for(i=0;i<8;i++)
{
dat >>= 1;
rst_1302 = 1;
clk_1302 = 0;
delay(5);
for(i=0;i<8;i++)
{
io_1302 = dat0;
clk_1302 = 0;
_nop_();
clk_1302 = 1;
_nop_();
dat >>= 1;
}
//rst_1302 = 0;
}
/*****************************
主程序
#include <reg52.h>
#include <intrins.h>
#include "header.h"
/******主函数********/
void main()
{
RTC_initial();
init();
//init1602();
//while(1);
while(1)
{
if(flag)
v_W1302(0x80,second);
}
if(key0_count==2)
{
minute ++;
if(60==minute)
minute = 0;
write_add(0x40+7,minute);
v_W1302(0x82,minute);
}
if(key0_count==3)
{
hour ++;
if(24==hour)
write_cmd_1602(0x0f); //显示光标并闪烁
delay(5);
}
if(3==key0_count)
{
flag = 0;
write_cmd_1602(0x80+0x40+5);//将地址指针指向小时的位置
write_cmd_1602(0x0f); //显示光标并闪烁