基于51单片机的DS1302实时时钟程序

DS1302概述

DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能。

工作原理

DS1302 是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.0V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后备电源双电源引脚,同时提供了对后备电源进行涓细电流充电的能力。基于51单片机的DS1302实时时钟程序_第1张图片
DS1302引脚图

管脚描述

Vcc1:主电源;Vcc2:备份电源。

当内Vcc2>Vcc1+0.2V时,由Vcc2
向DS1302供电,当Vcc2< Vcc1时,由Vcc1向DS1302供电。

SCLK:串行时钟,输入,控制数据的输入与输出;

I/O:三线接口时的双向数据线;

RST为复位引脚,在读、写数据期间,必须为高,

X1 X2为32.768Hz晶振管脚,为芯片提容供时钟脉冲。

基于51单片机的DS1302实时时钟程序_第2张图片
DS1302典型工作电路

本例程序原理图

(其中其他引脚我用作其他芯片,在这里可以不理会。)
基于51单片机的DS1302实时时钟程序_第3张图片

程序如下

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

程序效果图

基于51单片机的DS1302实时时钟程序_第4张图片

你可能感兴趣的:(51单片机,单片机,c语言)