ds1302时钟程序详解,ds1302程序流程图(C程序)

合集下载

ds1302的12864液晶按键可调显示实时时钟程序(word文档良心出品)

ds1302的12864液晶按键可调显示实时时钟程序(word文档良心出品)

一.绪言1.在信息显示技术中,人们发现了信息数字化的重要作用和意义。

数字化的信息更加准确,同一性,更易传输和识别。

很多信息可以直接由数字表示,从而数字化信息显示又成为信息显示的又一个重要内容。

又从数字化显示发展到字符显示,它把人类特有的语言文字用于显示,这种显示与数字显示合在一起用途更广用量更大。

在这同时,人们还希望用图形和图像进行显示,且显示的内容为五彩缤纷,并且可以实时活动和具有三维立体效果。

这些在二十世纪尾声时都已经陆续实现。

LCD的计算机器,半导体发光数码管显示(LED)的汽车计价器,商场的大屏幕广告。

这零零总总的各类显示正为你做着各种各样的服务,相信在不久的将来显示技术的发展将会为人类做出更大的贡献。

Ds1302时钟芯片现在流行的串行时钟电路很多,如DS1302、 DS1307、PCF8485等。

这些电路的接口简单、价格低廉、使用方便,被广泛地采用。

本文介绍的实时时钟电路DS1302是DALLAS公司的一种具有涓细电流充电能力的电路,主要特点是采用串行数据传输,可为掉电保护电源提供可编程的充电功能,并且可以关闭充电功能。

采用普通32.768kHz晶振。

(一)设计任务本课题采用ds1302的时钟芯片为主要的的设计来源,采用显示是1cd1602的图形点阵液晶显示。

,(二)提出方案及方案论证在设计中,我主要是考虑ds1302的时间显示问题,因为网上也有ds1302的读写和显示程序,但是至于怎样才能显示详细信息,我提出了两个方案,一个是LCD1602来显示,一个是LCD12864,其中1602是个字符型的点阵,而1CD12864是个图形的点阵,相比之下12864能够更好显示数据,而CPU都采用89C52的单片机(三)原理说明:原理其实很简单,LCD12864的各种指令先进行宏定义和ds1302的读写指令也进行宏定义,从ds1302的读出数据显示在lcd上(二)程序流程图(三)C51程序设计,重要的代码要有注释。

ds1302程序及原理图

ds1302程序及原理图

/**************************************************;文件名:DS1302.c;功能:设置时间,然后将时间读出显示在数码管上;硬件描述:PORTD口接数码管的8个笔段; PORTA 0~2及PORTE 0~2分别接6位数码管的位;RC3接SCK,RC4接SDA,RC2接RST*/#include "pic.h"#define uchar unsigned char#define uint unsigned int#define Hidden 16__CONFIG(HS&WDTDIS&LVPDIS); //配置文件,设置为HS方式振荡,禁止看门狗,低压编程关闭ucharDispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x8 6,0x8E,0xFF};uchar BitTab[]={0xfb,0xfd,0xfe};uchar DispBuf[6];#define LSB 0x01#define WrEnDisCmd 0x8e //写允许/禁止指令代码#define WrEnDat 0x00 //写允许数据#define WrDisDat 0x80 //写禁止数据#define OscEnDisCmd 0x80 //振荡器允许/禁止指令代码#define OscEnDat 0x00 //振荡器允许数据#define OscDisDat 0x80 //振荡器禁止数据#define WrMulti 0xbe //写入多个字节的指令代码#define WrSingle 0x84 //写入单个字节的指令代码#define RdMulti 0xbf //读出多个字节的指令代码#define cClk RC3 //与时钟线相连的PIC16F877A芯片的管脚#define cDat RC4 //与数据线相连的PIC16F877A芯片的管脚#define cRst RC2 //与复位端相连的PIC16F877A芯片的管脚#define SCL_CNT TRISC3 //SCL管脚控制位#define SDA_CNT TRISC4 //SDA管脚控制位#define RST_CNT TRISC2 //RST管脚控制位void mDelay(uint DelayTime){ uint temp;for(;DelayTime>0;DelayTime--){ for(temp=0;temp<270;temp++){;}}}void interrupt Disp(){ static uchar dCount; //用作显示的计数器if(TMR1IF==1&&TMR1IE==1)//Timer 1 inetrrupt{TMR1H=-(8000/256);TMR1L=-(8000%256); //重置定时初值}PORTA|=0x07; //关前面的显示PORTE|=0X07; //关前面的显示PORTD=DispTab[DispBuf[dCount]]; //显示第i位显示缓冲区中的内容if(dCount<3)PORTE&=BitTab[dCount]; //第1~3位是由PORTE控制的elsePORTA&=BitTab[dCount-3]; //第4~6位是由PORTA的低3位控制的dCount++;if(dCount==6)dCount=0;TMR1IF=0; //清中断标志}//数码管位 1 2 3 4 5 6//引脚RE0 RE1 RE2 RA2 RA1 RA0//根据这个表,只要改变PORTA&=0xfe,即可点亮任意一个数码管//例:PORTA&=0xfd //点亮第5位数码管// PORTE&=0xfe //点亮第3位数码管void uDelay(uchar i){ for(;i>0;i--){;}}void SendDat(uchar Dat){ uchar i;for(i=0;i<8;i++){cDat=Dat&LSB; //数据端等于tmp数据的末位值Dat>>=1;cClk=1;uDelay(1);cClk=0;}}/*写入1个或者多个字节,第1个参数是相关命令#define WrMulti 0xbe //写入多个字节的指令代码#define WrSingle 0x84 //写入单个字节的指令代码第2个参数是待写入的值第3个参数是待写入数组的指针*/void WriteByte(uchar CmdDat,uchar Num,uchar *pSend){uchar i=0;SDA_CNT=0; //数据端设为输出cRst=0;uDelay(1);cRst=1;SendDat(CmdDat);for(i=0;i<Num;i++){ SendDat(*(pSend+i));}cRst=0;}/*读出字节,第一个参数是命令#define RdMulti 0xbf //读出多个字节的指令代码第2个参数是读出的字节数,第3个是指收数据数组指针*/void RecByte(uchar CmdDat,uchar Num,uchar *pRec){uchar i,j,tmp;SDA_CNT=0; //数据端设为输出cRst=0; //复位引脚为低电平uDelay(1);cClk=0;uDelay(1);cRst=1;SendDat(CmdDat); //发送命令SDA_CNT=1; //数据端设为输入for(i=0;i<Num;i++){ for(j=0;j<8;j++){ tmp>>=1;if(cDat)tmp|=0x80;cClk=1;uDelay(1);cClk=0;}*(pRec+i)=tmp;}uDelay(1);cRst=0;}/*当写保护寄存器的最高位为0时,允许数据写入寄存器。

DS1302时钟芯片 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时钟芯片51单片机c语言程序

DS1302时钟芯片51单片机c语言程序

#ifndef __DS1302_H__#define __DS1302_H__#define uchar unsigned char#define uint unsigned int#includesbit SCLK = P3^2;sbit IO = P2^4;sbit RST = P3^3;#define R_Second 0x81#define W_Second 0x80#define R_Minute 0x83#define W_Minute 0x82#define R_Hour 0x85#define W_Hour 0x84h#define R_Day 0x87#define W_Day 0x86_n_#define R_Month 0x89澝儙#define W_Month 0x88 #define R_Week 0x8B#define W_Week 0x渢#define R_Year 0x8D#define W_Year 0x8C?^•#define R_Control 0xu _簭_•void DS1302_Write_Byte(uchar Date;?void Write_DS1302(uchar Adr,uchar Date;uchar Read_DS1302(uchar Adr;void Init_DS1302(;'#endifW燊/************************************************************** 函數名稱 _Z_k謃?缧?_恄漀騋单字节写葅发亽輸入參數:写的字节U輸出參數 -_无M;1,?備<5%注:**************************************************************/F _void DS1302_Write_Byte(uchar Date{琿彆 uchar i;G for(i = 0;i < 8;i++{ if(Date & 0x01IO = 1;else_鞺穢齄 IO = 0;O _ SCLK = 1;3┋SCLK = 0;}诰搕謃鋃乓莗れ擾葞U/************************************************************** : uchar DS1302_Read_Byte(•函數功能:单字节读恳輸入參數蛈w{-无E轆儡:|3?o读出的数据備注:**************************************************************/ uchar DS1302_Read_Byte(!b{uchar i,Temp = 0;for(i = 0;i < 8;i++{ Temp = Temp >> 1;(_eTemp = Temp | 0x80;SCLK = 1;}return Temp;Y仞_Gv'€+枊瞒~0壇糪f?_6篢2擺Pz;函數功能:写数据輸入參數 &率郷骋確_F澼 G?_弒]u_q无蘤窓膠注巓钌鑪**************************************************************/v嗣趉{藁mSCLK = 0;RST = 1;DS1302_Write_Byte(Adr;濒 DS1302_Write_Byte(Date;i Mc}n/************************************************************** 殧泛曋ㄖ嬪i: uchar Read_DS1302(uchar Adr齙鳑扼蝊_╛嵖??>輸入參數檟_范:U?T啃禈輸出參數:读出的数据拥&__ 注:_**************************************************************/ uchar Read_DS1302(uchar Adr{uchar Temp = 0;RST = 0;4_RST = 1;DS1302_Write_Byte(Adr;Temp = DS1302_Read_Byte(;RST = 0;潵擾?_獐衉}悱qG_?帶燙ㄚ負焉/************************************************************** 函數名稱:_函數功能陕鮛€_kE_P_w?鋃DS1302o齙:无?輸出參數: U _?眶備注:@_2•蒧void Init_DS1302(癬窥Q_u瞪I _%~唼? _镈 Write_DS1302(W_Month,0x09;中_# 疴FWrite_DS1302(W_Minute,0x11;Write_DS1302(W_Second,0x23;Write_DS1302(W_Control,0x80;_Ts}<。

ds1302实时时钟C程序

ds1302实时时钟C程序

/*********************************************************************//* ds1302实时时钟C程序*//*会员经典作品已经测试成功//**************/ziliao/file/ds1302c.rar 点此链接下载本例的代码*****/#include < reg52.h>#include#define uchar unsigned charsbit T_CLK = P3^4; /*实时时钟时钟线引脚*/sbit T_IO = P3^3; /*实时时钟数据线引脚*/sbit T_RST = P3^2; /*实时时钟复位线引脚*///sbit OE=P3^6;sbit ACC0=ACC^0;sbit ACC7=ACC^7;uchar time[8]=" : : ";uchar min,hou,day,mon,yea;void Init1302(void);void v_W1302(uchar ucAddr, uchar ucDa);uchar uc_R1302(uchar ucAddr);void v_BurstW1302T(uchar *pSecDa);void v_BurstR1302T(uchar *pSecDa);void v_BurstW1302R(uchar *pReDa);void v_BurstR1302R(uchar *pReDa);void v_Set1302(uchar *pSecDa);void v_Get1302(uchar ucCurtime[]);void donetime(void);void bcd_int(uchar i);void SetTime(void);/********************************************************************** 名称: v_RTInputByte* 说明:* 功能: 往DS1302写入1Byte数据* 调用:* 输入: ucDa 写入的数据* 返回值: 无***********************************************************************/ void v_WTInputByte(uchar ucDa){uchar i;//OE=0;ACC= ucDa;for(i=8; i>0; i--){T_IO = ACC0; //*相当于汇编中的RRCT_CLK = 1;T_CLK = 0;ACC =ACC>> 1;}// OE=1;}/********************************************************************** 名称: uchar uc_RTOutputByte* 说明:* 功能: 从DS1302读取1Byte数据* 输入:* 返回值: ACC***********************************************************************/ uchar uc_RTOutputByte(void){uchar i;//OE=0;for(i=8; i>0; i--){ACC = A CC>>1; //*相当于汇编中的RRCACC7 = T_IO;T_CLK = 1;T_CLK = 0;}//OE=1;return(ACC);}/********************************************************************** 名称: v_W1302* 说明: 先写地址,后写命令/数据* 功能: 往DS1302写入数据* 调用: v_RTInputByte()* 输入: ucAddr: DS1302地址, ucDa: 要写的数据* 返回值: 无***********************************************************************/ void v_W1302(uchar ucAddr, uchar ucDa){//OE=0;T_CLK = 0;T_RST = 1;v_WTInputByte(ucAddr); /* 地址,命令*/v_WTInputByte(ucDa); /* 写1Byte数据*/T_CLK = 1;T_RST =0;//OE=1;}/********************************************************************** 名称: uc_R1302* 说明: 先写地址,后读命令/数据* 功能: 读取DS1302某地址的数据* 调用: v_RTInputByte() , uc_RTOutputByte()* 输入: ucAddr: DS1302地址* 返回值: ucDa :读取的数据***********************************************************************/ uchar uc_R1302(uchar ucAddr){uchar ucDa;//OE=0;T_RST = 0;T_CLK = 0;T_RST = 1;v_WTInputByte(ucAddr); /* 地址,命令*/ucDa = uc_RTOutputByte(); /* 读1Byte数据*/T_CLK = 1;T_RST =0;// OE=1;}/********************************************************************** 名称: 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_WTInputByte(0xbe); //* 0xbe:时钟多字节写命令for (i=8;i>0;i--) //*8Byte = 7Byte 时钟数据+ 1Byte 控制{v_WTInputByte(*pSecDa);//* 写1Byte数据pSecDa++;}T_CLK = 1;T_RST =0;} *//********************************************************************** 说明: 先写地址,后读命令/数据(时钟多字节方式)* 功能: 读取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_WTInputByte(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_WTInputByte(0xfe); //* 0xbe:时钟多字节写命令for (i=31;i>0;i--) //*31Byte 寄存器数据{v_WTInputByte(*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 = 1;v_WTInputByte(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: 初始时间地址。

51单片机DS1302日历时钟程序

51单片机DS1302日历时钟程序
v_W1302(0x88,0x01); //设置月
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); //设置年

时钟芯片ds1302程序

这是对DS1302编程最常见的操作,有很好的参考价值!我们通过本例程可以了解 DS1302时钟芯片的基本原理和使用 ,理解并掌握DS1302时钟芯片,驱动程序的编写以及实现数字字符在数码管中的显示。

#include<reg52.h>#include <intrins.h>sbit SCK=P3^6; //时钟引脚sbit SDA=P3^4; //数据端口sbit RST = P3^5;// DS1302复位sbit LS138A=P2^2;sbit LS138B=P2^3;sbit LS138C=P2^4;bit ReadRTC_Flag;//定义读DS1302标志unsigned char l_tmpdate[7]={0,0,12,15,5,3,8};//秒分时日月周年08-05-15 12:00:00 unsigned char l_tmpdisplay[8];code unsigned char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年最低位读写位code unsigned char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};code unsigned chartable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//共阴数码管 0-9 '-' '熄灭‘表/******************************************************************/ /* 函数声明 *//******************************************************************/void Write_Ds1302_byte(unsigned char temp);void Write_Ds1302( unsigned char address,unsigned char dat );unsigned char Read_Ds1302 ( unsigned char address );void Read_RTC(void);//read RTCvoid Set_RTC(void); //set RTCvoid InitTIMER0(void);//inital timer0/******************************************************************/ /* 主函数 *//******************************************************************/ void main(void){InitTIMER0(); //初始化定时器0Set_RTC(); //写入时钟值,如果使用备用电池时候,不需要没每次上电写入,此程序应该屏蔽while(1){if(ReadRTC_Flag){ReadRTC_Flag=0;Read_RTC();l_tmpdisplay[0]=l_tmpdate[2]/16; //数据的转换,因我们采用数码管0~9的显示,将数据分开l_tmpdisplay[1]=l_tmpdate[2]&0x0f;l_tmpdisplay[2]=10; //加入"-"l_tmpdisplay[3]=l_tmpdate[1]/16;l_tmpdisplay[4]=l_tmpdate[1]&0x0f;l_tmpdisplay[5]=10;l_tmpdisplay[6]=l_tmpdate[0]/16;l_tmpdisplay[7]=l_tmpdate[0]&0x0f;}}}/******************************************************************/ /* 定时器0初始化 *//******************************************************************/ void InitTIMER0(void){TMOD|=0x01;//定时器设置 16位TH0=0xef;//初始化值TL0=0xf0;ET0=1;TR0=1;EA=1;}/******************************************************************/ /* 写一个字节 *//******************************************************************/ void Write_Ds1302_Byte(unsigned char temp){unsigned char i;for (i=0;i<8;i++) //循环8次写入数据{SCK=0;SDA=temp&0x01; //每次传输低字节temp>>=1; //右移一位SCK=1;}}/******************************************************************/ /* 写入DS1302 *//******************************************************************/ void Write_Ds1302( unsigned char address,unsigned char dat ){RST=0;_nop_();SCK=0;_nop_();RST=1;_nop_(); //启动Write_Ds1302_Byte(address); //发送地址Write_Ds1302_Byte(dat); //发送数据RST=0; //恢复}/******************************************************************/ /* 读出DS1302数据 *//******************************************************************/unsigned char Read_Ds1302 ( unsigned char address ){unsigned char i,temp=0x00;RST=0;_nop_();_nop_();SCK=0;_nop_();_nop_();RST=1;_nop_();_nop_();Write_Ds1302_Byte(address);for (i=0;i<8;i++) //循环8次读取数据{if(SDA)temp|=0x80; //每次传输低字节SCK=0;temp>>=1; //右移一位_nop_();_nop_();_nop_();SCK=1;}RST=0;_nop_(); //以下为DS1302复位的稳定时间_nop_();RST=0;SCK=0;_nop_();_nop_();_nop_();_nop_();SCK=1;_nop_();_nop_();SDA=0;_nop_();_nop_();SDA=1;_nop_();_nop_();return (temp); //返回}/******************************************************************/ /* 读时钟数据 *//******************************************************************/ void Read_RTC(void) //读取日历{unsigned char i,*p;p=read_rtc_address; //地址传递for(i=0;i<7;i++) //分7次读取秒分时日月周年{l_tmpdate[i]=Read_Ds1302(*p);p++;}}/******************************************************************//* 设定时钟数据 *//******************************************************************/ void Set_RTC(void) //设定日历{unsigned char i,*p,tmp;for(i=0;i<7;i++){ //BCD处理tmp=l_tmpdate[i]/10;l_tmpdate[i]=l_tmpdate[i]%10;l_tmpdate[i]=l_tmpdate[i]+tmp*16;}Write_Ds1302(0x8E,0X00);p=write_rtc_address; //传地址for(i=0;i<7;i++) //7次写入秒分时日月周年{Write_Ds1302(*p,l_tmpdate[i]);p++;}Write_Ds1302(0x8E,0x80);}/******************************************************************/ /* 定时器中断函数 *//******************************************************************/ void tim(void) interrupt 1 using 1//中断,用于数码管扫描{static unsigned char i,num;TH0=0xf5;TL0=0xe0;P0=table[l_tmpdisplay[i]]; //查表法得到要显示数字的数码段switch(i){case 0:LS138A=0; LS138B=0; LS138C=0; break;case 1:LS138A=1; LS138B=0; LS138C=0; break;case 2:LS138A=0; LS138B=1; LS138C=0; break;case 3:LS138A=1; LS138B=1; LS138C=0; break;case 4:LS138A=0; LS138B=0; LS138C=1; break;case 5:LS138A=1; LS138B=0; LS138C=1; break;case 6:LS138A=0; LS138B=1; LS138C=1; break;case 7:LS138A=1; LS138B=1; LS138C=1; break;}i++;if(i==8){i=0;num++;if(10==num) //隔段时间读取1302的数据。

DS1302+AT89S51单片机时钟C程序(六位共阳数码管显示)

DS1302+AT89S51单片机时钟C程序(六位共阳数码管显示)DS1302+A T89S51单片机时钟C程序(六位共阳数码管显示)//DS1302时钟芯片程序#include#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;uchara[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); } }}}。

ds1302实时时钟程序说明

下面是DS1302内部寄存器的地址的说明。
DS1302实时时钟在数码管上进行实时显示的程序
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit rst=P2^4;
sbit io=P2^0;
}
write_ds1302(0x8e,0x80); //进行写保护
}
void read_rtc()
{
uchar i;
for(i=0;i<7;i++)
{
time_data[i]=read_ds1302(read_add[i]);
}
}
void time_pros()
{
disp[0]=time_data[6]%16;//将BCD码(这里与十六进制没有区别)进行十位个位的分离
{
j=time_data[i]/10;//十位5
time_data[i]%=10;//各位8
time_data[i]=time_data[i]+j*16;
}
write_ds1302(0x8e,0x00);//去除写保护
for(i=0;i<7;i++)
{
write_ds1302(write_add[i],time_data[i]);
disp[1]=time_data[6]/16;
disp[2]=17;
disp[3]=time_data[5]%16;
disp[4]=time_data[5]/16;
disp[5]=17;

ds1302实时时钟c程序加仿真原理图

#ifndef _1602_yejing_#define _1602_yejing_#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit lcden=P3^4;sbit lcdrs=P3^5;void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write_com(uchar com) {lcdrs=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_data(uchar date){lcdrs=1;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void write_lcd(uchar x,char *cha){ uchar length,i=0;write_com(x);for(length=0;cha[length]!=0;length++);for(i=0;i<length;i++){write_data(cha[i]);delay(5);}}void write_bcd(uchar cha){uchar ch1,ch2;ch1=(cha&0x0f)+'0';ch2=((cha>>4)&0x0f)+'0';write_data(ch2);write_data(ch1);}void write_fd(float t)//显示float型函数{ uchar s1,s2,s3,s4;uint tt;tt=t*100;s1=tt/1000;s1+=0x30;s2=tt%1000/100;s2+=0x30;s3=tt%1000%100/10;s3+=0x30;s4=tt%10;s4+=0x30;write_data(s1);write_data(s2);write_data(46);write_data(s3);write_data(s4);}void init(){lcden=0;write_com(0x38);//设置16*2显示write_com(0x0c);//设置开显示,不显示光标write_com(0x06);//写一个字符后地址指针加1write_com(0x01);//显示清0,数据指针清0}#endif/**************************************************************************THE REAL TIMER DS1302 DRIVER LIBCOPYRIGHT (c) 2010 BY ZYK.-- ALL RIGHTS RESERVED --File Name: DS1302.hAuthor: ZHANG YUAN KECreated: 2010/06/21Modified: NORevision: 1.0***************************************************************************/ #ifndef _DS1302_2010_06_21_#define _DS1302_2010_06_21_sbit SCLK = P1^6; //实时时钟时钟线引脚sbit DIO = P1^7; //实时时钟数据线引脚sbit CE = P1^5; //实时时钟复位线引脚sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;char sec,min,hour,day,mon,week,year;char *tab[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat",};void write_1302(uchar add,uchar dat){uchar i;ACC=add;CE=0;SCLK=0;CE=1;for(i=0;i<8;i++){DIO=ACC0;SCLK=1;SCLK=0;ACC>>=1;}ACC=dat;for(i=0;i<8;i++){DIO=ACC0;SCLK=1;SCLK=0;ACC>>=1;}CE=0;}uchar read_1302(uchar add){uchar i;ACC=add;CE=0;SCLK=0;CE=1;for(i=8;i>0;i--) // 为什么不能for(i=0;i<8;i++) 又为什么用我写的函数不能改时间!!!!!!!!!!!!{DIO=ACC0;SCLK=1;ACC>>=1;SCLK=0;}for(i=8;i>0;i--){ ACC>>=1;ACC7=DIO;SCLK=1;SCLK=0;}return(ACC);CE=0;}void inputbyte(uchar d) //实时时钟写入一字节(内部函数){uchar i;ACC=d;for(i=8;i>0;i--){DIO=ACC0; //相当于汇编中的RRCSCLK=1;SCLK=0;ACC>>=1;}}uchar outputbyte() //实时时钟读取一字节(内部函数){uchar i;for(i=8; i>0; i--){ACC=ACC>>1; //相当于汇编中的RRCACC7=DIO;SCLK=1;SCLK=0;}return(ACC);}void write_1302(uchar add,uchar dat) //ucAddr: DS1302地址, ucData: 要写的数据{CE=0;SCLK=0;CE=1;inputbyte(add); // 地址,命令inputbyte(dat); // 写1Byte数据CE=0;}uchar read_1302(uchar add) //读取DS1302某地址的数据{uchar dat;CE=0;SCLK=0;CE=1;inputbyte(add); // 地址,命令dat=outputbyte(); // 读1Byte数据CE=0;return(dat);}void setprotect(bit flag){if(flag)write_1302(0x8e,0x80);elsewrite_1302(0x8e,0x00);}void gettime_1302(){sec=read_1302(0x81);min=read_1302(0x83);hour=read_1302(0x85);day=read_1302(0x87);mon=read_1302(0x89);week=read_1302(0x8b);year=read_1302(0x8d);}void stop_time(bit flag) // 是否将时钟停止{unsigned char dat;dat=read_1302(0x81);setprotect(0);if(flag)write_1302(0x80, dat|0x80);elsewrite_1302(0x80, dat&0x7F);}void init_1302(){uchar second=read_1302(0x81);if(second&0x80)write_1302(0x80,0);}/****************************************************************************** **void BurstWrite1302(unsigned char *pWClock) //往DS1302写入时钟数据(多字节方式) {unsigned char i;Write1302(0x8e,0x00); // 控制命令,WP=0,写操作?DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(0xbe); // 0xbe:时钟多字节写命令for (i = 8; i>0; i--) //8Byte = 7Byte 时钟数据+ 1Byte 控制{DS1302InputByte(*pWClock); // 写1Byte数据pWClock++;}DS1302_CLK = 1;DS1302_RST = 0;}void BurstRead1302(unsigned char *pRClock) //读取DS1302时钟数据(时钟多字节方式) {unsigned char i;DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(0xbf); // 0xbf:时钟多字节读命令for (i=8; i>0; i--){*pRClock = DS1302OutputByte(); // 读1Byte数据pRClock++;}DS1302_CLK = 1;DS1302_RST = 0;}******************************************************************************* */#endif#include "1602.h"#include "DS1302.h"sbit set=P3^2;sbit jia1=P3^0;sbit jian1=P3^1;uchar bcdtoasc(uchar cha){return ((cha/16)*10+(cha%16));}uchar asctobcd(uchar cha){return ((cha/10)*16+(cha%10));}void disp_week(){ switch(week){case 1:{write_lcd(0xcd,tab[0]); break;}case 2:{write_lcd(0xcd,tab[1]); break;}case 3:{write_lcd(0xcd,tab[2]); break;}case 4:{write_lcd(0xcd,tab[3]); break;}case 5:{write_lcd(0xcd,tab[4]); break;}case 6:{write_lcd(0xcd,tab[5]); break;}case 7:{write_lcd(0xcd,tab[6]); break;}}}void disp_time(){write_com(0x87);write_bcd(year);write_com(0x8a);write_bcd(mon);write_com(0x8d);write_bcd(day);write_com(0xc5);write_bcd(hour);write_com(0xc8);write_bcd(min);write_com(0xcb);write_bcd(sec);disp_week();}void keyscan(){jia1=1;jian1=1;stop_time(1);if(set==0){delay(10);if(set==0) {delay(200); slect++;}if(slect==8) {slect=0; stop_time(0);write_com(0x0c);} }if(slect){switch(slect){ case 1:{write_com(0xcb);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);sec=read_1302(0x81);sec=sec&0x7f;sec=bcdtoasc(sec);sec+=1;if(sec==60)sec=0;sec=asctobcd(sec);write_1302(0x80,sec);write_com(0x0c);write_bcd(sec);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);sec=read_1302(0x81);sec=sec&0x7f;sec=bcdtoasc(sec);sec-=1;if(sec<0)sec=59;sec=asctobcd(sec);write_1302(0x80,sec);write_com(0x0c);write_bcd(sec);}}break;}case 2:{write_com(0xc8);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);min=read_1302(0x83);min=bcdtoasc(min);min+=1;if(min==60)min=0;min=asctobcd(min);write_1302(0x82,min);write_com(0x0c);write_bcd(min);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);min=read_1302(0x83);min=bcdtoasc(min);min-=1;if(min<0)min=59;min=asctobcd(min);write_1302(0x82,min);write_com(0x0c);write_bcd(min);}}break;}case 3:{write_com(0xc5);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);hour=read_1302(0x85);hour=bcdtoasc(hour);hour+=1;if(hour==24)hour=0;hour=asctobcd(hour);write_1302(0x84,hour);write_com(0x0c);write_bcd(hour);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);hour=read_1302(0x85);hour=bcdtoasc(hour);hour-=1;if(hour<0)hour=23;hour=asctobcd(hour);write_1302(0x84,hour);write_com(0x0c);write_bcd(hour);}}break;}case 4:{write_com(0x8d);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);mon=read_1302(0x89);year=read_1302(0x8d);day=read_1302(0x87);day=bcdtoasc(day);day+=1;year=bcdtoasc(year);if(year%4==0){if(mon==2){if(day==29)day=1;}else if(day==30)day=1;}else{ switch(mon){case 1:{if(day==32)day=1;break;}case 2:{if(day==30)day=1;break;}case 3:{if(day==32)day=1;break;}case 4:{if(day==31)day=1;break;}case 5:{if(day==32)day=1;break;}case 6:{if(day==31)day=1;break;}case 7:{if(day==32)day=1;break;}case 8:{if(day==32)day=1;break;}case 9:{if(day==31)day=1;break;}case 0x10:{if(day==32)day=1;break;}case 0x11:{if(day==31)day=1;break;}case 0x12:{if(day==32)day=1;break;}}if(mon==1|mon==3|mon==5|mon==7|mon==8|mon==0x10|mon==0x12) if(day==32)day=0; */if(mon==4|mon==6|mon==9|mon==0x11){if(day==31)day=1;}else if(day==32)day=1;}day=asctobcd(day);write_1302(0x86,day);write_com(0x0c);write_bcd(day);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);day=read_1302(0x87);day=bcdtoasc(day);day-=1;if(day<1){ mon=read_1302(0x89);year=read_1302(0x8d);switch(mon){ case 0x01: {day=31; break;}case 0x02: {day=29; break;}case 3: {day=31; break;}case 4: {day=30; break;}case 5: {day=31; break;}case 6: {day=30; break;}case 7: {day=31; break;}case 8: {day=31; break;}case 9: {day=30; break;}case 0x10: {day=31; break;}case 0x11: {day=30; break;}case 0x12: {day=31; break;}}year=bcdtoasc(year);if(year%4==0)if(mon==2)day=28;}day=asctobcd(day);write_1302(0x86,day);write_com(0x0c);write_bcd(day);}}break;}case 5:{write_com(0x8a);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);mon=read_1302(0x89);mon=bcdtoasc(mon);mon+=1;if(mon==13)mon=1;mon=asctobcd(mon);write_1302(0x88,mon);write_com(0x0c);write_bcd(mon);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);mon=bcdtoasc(mon);mon-=1;if(mon<1)mon=12;mon=asctobcd(mon);write_1302(0x88,mon);write_com(0x0c);write_bcd(mon);}}break;}case 6:{write_com(0x87);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);year=read_1302(0x8d);year=bcdtoasc(year);year+=1;if(year==100)year=0;year=asctobcd(year);write_1302(0x8c,year);write_com(0x0c);write_bcd(year);}}if(jian1==0){delay(10);if(jian1==0){ delay(200);year=read_1302(0x8d);year=bcdtoasc(year);year-=1;if(year<0)year=99;year=asctobcd(year);write_com(0x0c);write_bcd(year);}}break;}case 7:{write_com(0xcd);write_com(0x0d);if(jia1==0){delay(10);if(jia1==0){delay(200);week=read_1302(0x8b);week=bcdtoasc(week);week+=1;if(week==8)week=1;week=asctobcd(week);write_1302(0x8a,week);write_com(0x0c);disp_week();/* switch(week){case 1:{write_lcd(0xcd,tab[0]); break;}case 2:{write_lcd(0xcd,tab[1]); break;}case 3:{write_lcd(0xcd,tab[2]); break;}case 4:{write_lcd(0xcd,tab[3]); break;}case 5:{write_lcd(0xcd,tab[4]); break;}case 6:{write_lcd(0xcd,tab[5]); break;}case 7:{write_lcd(0xcd,tab[6]); break;}} */}}if(jian1==0){delay(10);if(jian1==0){ delay(200);week=read_1302(0x8b);week=bcdtoasc(week);week-=1;if(week<1)week=7;week=asctobcd(week);write_1302(0x8a,week);write_com(0x0c);disp_week();/* switch(week){case 1:{write_lcd(0xcd,tab[0]); break;}case 2:{write_lcd(0xcd,tab[1]); break;}case 3:{write_lcd(0xcd,tab[2]); break;}case 4:{write_lcd(0xcd,tab[3]); break;}case 5:{write_lcd(0xcd,tab[4]); break;}case 6:{write_lcd(0xcd,tab[5]); break;}case 7:{write_lcd(0xcd,tab[6]); break;} } */}}break; }}}}main(){init();init_1302();write_lcd(0x80,"DATE:20 - -");write_lcd(0x80+0x40,"TIME: : :");while(1){gettime_1302();set=1;if(set==0){delay(10);if(set==0){delay(200);slect++;}}while(slect)keyscan();disp_time();delay(30);}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ds1302时钟程序详解,ds1302程序流程图(C程序)
ds1302时钟程序详解
DS1302 的控制字如图2所示。控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写
入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单
元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始
输出。

2.3 数据输入输出(I/O)
在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。
同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0
位到高位7。

2.4 DS1302的寄存器
DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式,其日历、
时间寄存器及其控制字见表1。

此外,DS1302 还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器
等。时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。 DS1302与RAM相关的寄存
器分为两类:一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0H~
FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写
所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。
ds1302程序流程图
3.2 DS1302实时时间流程
图4示出DS1302的实时时间流程。根据此流程框图,不难采集实时时间。下面结合流程图对DS1302的基
本操作进行编程:
根据本人在调试中遇到的问题,特作如下说明: DS1302 与微处理器进行数据交换时,首先由微处理

器向电路发送命令字节,命令字节最高位MSB(D7)必须为逻辑1,如果D7=0,则禁止写DS1302,即写保
护;D6=0,指定时钟数据,D6=1,指定RAM数据;D5~D1指定输入或输出的特定寄存器;最低位LSB(D
0)为逻辑0,指定写操作(输入), D0=1,指定读操作(输出)。 在DS1302的时钟日历或RAM进行数据
传送时,DS1302必须首先发送命令字节。若进行单字节传送,8位命令字节传送结束之后,在下2个SCL
K周期的上升沿输入数据字节,或在下8个SCLK周期的下降沿输出数据字节。 DS1302与RAM相关
的寄存器分为两类:一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C
0H~FDH,其中奇数为读操作,偶数为写操作;再一类为突发方式下的RAM寄存器,在此方式下可一次
性读、写所有的RAM的31个字节。 要特别说明的是备用电源B1,可以用电池或者超级电容器(0.1F
以上)。虽然DS1302在主电源掉电后的耗电很小,但是,如果要长时间保证时钟正常,最好选用小型充电
电池。可以用老式电脑主板上的3.6V充电电池。如果断电时间较短(几小时或几天)时,就可以用漏电较小
的普通电解电容器代替。100 μF就可以保证1小时的正常走时。DS1302在第一次加电后,必须进行初始
化操作。初始化后就可以按正常方法调整时间。

相关文档
最新文档