DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能。
DS1302 是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.0V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后备电源双电源引脚,同时提供了对后备电源进行涓细电流充电的能力。
DS1302引脚图
Vcc1:主电源;Vcc2:备份电源。
当内Vcc2>Vcc1+0.2V时,由Vcc2
向DS1302供电,当Vcc2< Vcc1时,由Vcc1向DS1302供电。
SCLK:串行时钟,输入,控制数据的输入与输出;
I/O:三线接口时的双向数据线;
RST为复位引脚,在读、写数据期间,必须为高,
X1 X2为32.768Hz晶振管脚,为芯片提容供时钟脉冲。
DS1302.c
程序初始化设置时间为2020年4月5日 06时59分00秒 星期三
#include "DS1302.h"
/* ***************************************************** */
// 数组定义
/* ***************************************************** */
//DS1302读地址,秒分时日月星期年
unsigned char code DS1302_ReadAddr[7] = {0x81,0x83,0x85,0x87,0x89,0x8B,0x8D};
//DS1302写地址,秒分时日月星期年
unsigned char code DS1302_WriteAddr[7] ={0x80,0x82,0x84,0x86,0x88,0x8A,0x8C};
//DS1302初始化时间,202004050 131400 星期三
unsigned char TIME[7] = {0, 0x59, 0x06, 0x15, 0x04, 0x03, 0x20};
/* ***************************************************** */
/* ***************************************************** */
// 函数名称:DS1302_Write
// 函数功能: 向DS1302写入数据
// 入口参数:地址addr 数据dat
// 出口参数:无
/* ***************************************************** */
void DS1302_Write(u8 addr,u8 dat)
{
u8 i;
CE = 0; //禁止数据传输
_nop_();
SCLK = 0; //确保写数据前保持SCLK为低电平
_nop_();
CE = 1; //即上升沿时开启数据传输
_nop_();
for(i=0;i<8;i++)
{
DATA = addr & 0x01; //取数据最低位
addr >>= 1; //数据右移
SCLK = 1; //SCLK时钟上升沿时,DS1302读取数据
_nop_();
SCLK = 0; //为写入dat数据做准备
_nop_();
}
for(i=0;i<8;i++)
{
DATA = dat & 0x01; //取数据最低位
dat >>= 1; //数据右移
SCLK = 1; //SCLK时钟上升沿时,DS1302读取数据
_nop_();
SCLK = 0; //为写入dat数据做准备
_nop_();
}
CE = 0; //数据传输结束
_nop_();
}
/* ***************************************************** */
// 函数名称:DS1302_Read
// 函数功能: 读取任意地址的数据
// 入口参数:地址 addr
// 出口参数:数据 dat
/* ***************************************************** */
unsigned char DS1302_Read(u8 addr)
{
u8 i,temp,dat;
CE = 0;
_nop_();
SCLK = 0;
_nop_();
CE = 1;
_nop_();
for(i=0;i<8;i++)
{
DATA = addr & 0x01; //取数据最低位
addr >>=1;
SCLK = 1;
_nop_();
SCLK = 0;
_nop_();
}
_nop_();
for(i=0;i<8;i++)
{
temp = DATA;
dat = (dat>>1) | (temp<<7);
SCLK = 1;
_nop_();
SCLK = 0; //DS1302下降沿时,放置数据
_nop_();
}
CE = 0;
_nop_();
SCLK = 1;
_nop_();
DATA = 0;
_nop_();
return dat;
}
/* ***************************************************** */
// 函数名称:DS1302_Init
// 函数功能: 初始化DS1302
// 入口参数:无
// 出口参数:无
/* ***************************************************** */
void DS1302_Init(void)
{
u8 i;
DS1302_Write(0x8E,0x00); //禁止写保护
for(i=0;i<7;i++)
{
DS1302_Write(DS1302_WriteAddr[i],TIME[i]);
}
DS1302_Write(0x8E,0x80); //使能写保护
}
/* ***************************************************** */
// 函数名称:DS1302_ReadTime
// 函数功能: 读取时钟信息
// 入口参数:无
// 出口参数:无
/* ***************************************************** */
void DS1302_ReadTime(void)
{
u8 i;
for(i=0;i<7;i++)
{
TIME[i] = DS1302_Read(DS1302_ReadAddr[i]);
}
}
DS1302.H
#ifndef _DS1302_H_
#define _DS1302_H_
#include
#include
/* ***************************************************** */
// 宏定义
/* ***************************************************** */
#define u8 unsigned char
#define u16 unsigned int
/* ***************************************************** */
// 位定义
/* ***************************************************** */
//DS1302
sbit DATA = P3^7;
sbit CE = P3^5;
sbit SCLK = P3^6;
/* ***************************************************** */
// 定义全局函数
/* ***************************************************** */
void DS1302_Write(u8 addr,u8 dat);
unsigned char DS1302_Read(u8 addr);
void DS1302_Init(void);
void DS1302_ReadTime(void);
/* ***************************************************** */
// 定义全局变量
/* ***************************************************** */
extern u8 TIME[7];
#endif
主程序
main.c
数码显示采用74HC595 串行转并行显示。
#include
/* ***************************************************** */
// 位定义
/* ***************************************************** */
//74HC595
sbit smgSER = P3^4; // 595(14脚)SER 数据输入引脚
sbit RCK = P3^3; // 595(12脚)STCP 锁存时钟 1个上升沿所存一次数据
sbit SCK = P3^2; // 595(11脚)SHCP 移位时钟 8个时钟移入一个字节
/* ***************************************************** */
// 数组定义
/* ***************************************************** */
//位选数组
unsigned char Bit_Tab[] =
{0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//段选数组
unsigned char Disp_Tab[] =
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
///* ***************************************************** */
函数名称:DelayMS()
函数功能:毫秒延时
入口参数:延时毫秒数(ValMS)
出口参数:无
///* ***************************************************** */
//void DelayMS(u16 ValMS)
//{
// u16 uiVal,ujVal;
// for(uiVal = 0; uiVal < ValMS; uiVal++)
// for(ujVal = 0; ujVal < 120; ujVal++);
//}
/* ******************************************************************
* 函数名称:HC595_WrOneByte()
* 函数功能:向HC595中写入一个字节
* 入口参数:待写入HC595的一个字节(ucDat)
* 出口参数:无
/****************************************************************** */
void HC595_WrOneByte(unsigned char ucDat)
{
unsigned char i = 0;
//通过8循环将8位数据一次移入74HC595
for(i=0;i<8;i++)
{
smgSER = (bit)(ucDat & 0x80);
SCK = 0;
ucDat <<= 1;
SCK = 1;
}
//数据并行输出(借助上升沿)
RCK = 0;
_nop_();
_nop_();
RCK = 1;
}
/* ******************************************************************
* 函数名称:Datapro
* 函数功能:数据处理
* 入口参数:无
* 出口参数:无
/****************************************************************** */
void Datapro(void)
{
DS1302_ReadTime();
P2= Bit_Tab[0]; // 送位选数据
HC595_WrOneByte(Disp_Tab[TIME[2]/16]); // 送段选数据
HC595_WrOneByte(0x00); // 消除鬼影现象
P2 = Bit_Tab[1];
HC595_WrOneByte(Disp_Tab[TIME[2]&0x0f]);
HC595_WrOneByte(0x00);
P2= Bit_Tab[2];
HC595_WrOneByte(0x40);
HC595_WrOneByte(0x00);
P2 = Bit_Tab[3];
HC595_WrOneByte(Disp_Tab[TIME[1]/16]);
HC595_WrOneByte(0x00);
P2 = Bit_Tab[4];
HC595_WrOneByte(Disp_Tab[TIME[1]&0x0f]);
HC595_WrOneByte(0x00);
P2 = Bit_Tab[5];
HC595_WrOneByte(0x40);
HC595_WrOneByte(0x00);
P2 = Bit_Tab[6];
HC595_WrOneByte(Disp_Tab[TIME[0]/16]);
HC595_WrOneByte(0x00);
P2 = Bit_Tab[7];
HC595_WrOneByte(Disp_Tab[TIME[0]&0x0f]);
HC595_WrOneByte(0x00);
}
void main(void)
{
DS1302_Init();
while(1)
{
Datapro();
}
}