DS1302時鍾基礎使用(含代碼)


了解其管腳

  • X1 X2 32.768KHz 晶振管腳
  • GND 地
  • RST 復位腳
  • I/O 數據輸入/輸出引腳,具有三態
  • SCLK 串行時鍾
  • Vcc1,Vcc2(備用電源供電) 電源供電管腳

DS1302 的寄存器及片內RAM

控制寄存器用於存放DS1302的控制命令字,DS1302的RST引腳回到高電平后寫入的第一個字就為控制命令。它用於對DS1302讀寫過程進行控制,它的格式如下:

  • D7:固定為1
  • D6:RAM/CK位,=1片內RAM,=0日歷、時鍾寄存器選擇位。
  • D5~D1:地址位,用於選擇進行讀寫的日歷、時鍾寄存器或片內RAM。對日歷、時鍾寄存器或片內RAM的選擇見表。
  • D0: 讀寫選擇,=0寫,=1讀

日歷 時鍾寄存器

寫保護寄存器

  • 用於初始化時鍾

void Ds1302Init()
{
	uchar n;
	Ds1302Write(0x8E,0X00);		 //禁止寫保護,就是關閉寫保護功能
	for (n=0; n<7; n++)//寫入7個字節的時鍾信號:分秒時日月周年
	{
		Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);	
	}
	Ds1302Write(0x8E,0x80);		 //打開寫保護功能
}

寄存器說明

數據輸出輸入

在控制指令字輸入后的下一個SCLK時鍾的上升沿時,數據被寫入DS1302,數據輸入從低位即位0開始。同樣,在緊跟8位的控制指令字后的下一個SCLK脈沖的下降沿讀出DS1302的數據,讀出數據時從低位0位到高位7。

單字節讀和寫

  • DS1302是通過SPI串行總線跟單片機通信的,當進行一次讀寫操作時最少得讀寫兩個字節,第一個字節是控制字節,就是一個命令,告訴DS1302是讀還是寫操作,是對RAM還是對CLOK寄存器操作。第二個字節就是要讀或寫的數據了。
  • 單字節讀寫:只有在SCLK為低電平時,才能將CE置為高電平。所以在進行操作之前先將SCLK置低電平,然后將CE置為高電平,接着開始在IO上面放入要傳送的電平信號,然后跳變SCLK。數據在SCLK上升沿時,DS1302讀寫數據,在SCLK下降沿時,DS1302放置數據到IO上
  • 不懂看代碼

void Ds1302Write(uchar addr, uchar dat)
{
	uchar n;
	RST = 0;
	_nop_();

	SCLK = 0;//先將SCLK置低電平。
	_nop_();
	RST = 1; //然后將RST(CE)置高電平。
	_nop_();

	for (n=0; n<8; n++)//開始傳送八位地址命令
	{
		DSIO = addr & 0x01;//數據從低位開始傳送
		addr >>= 1;
		SCLK = 1;//數據在上升沿時,DS1302讀取數據
		_nop_();
		SCLK = 0;
		_nop_();
	}
	for (n=0; n<8; n++)//寫入8位數據
	{
		DSIO = dat & 0x01;
		dat >>= 1;
		SCLK = 1;//數據在上升沿時,DS1302讀取數據
		_nop_();
		SCLK = 0;
		_nop_();	
	}	
		 
	RST = 0;//傳送數據結束
	_nop_();
}

/*******************************************************************************
* 函 數 名         : Ds1302Read
* 函數功能		   : 讀取一個地址的數據
* 輸    入         : addr
* 輸    出         : dat
*******************************************************************************/

uchar Ds1302Read(uchar addr)
{
	uchar n,dat,dat1;
	RST = 0;
	_nop_();

	SCLK = 0;//先將SCLK置低電平。
	_nop_();
	RST = 1;//然后將RST(CE)置高電平。
	_nop_();

	for(n=0; n<8; n++)//開始傳送八位地址命令
	{
		DSIO = addr & 0x01;//數據從低位開始傳送
		addr >>= 1;
		SCLK = 1;//數據在上升沿時,DS1302讀取數據
		_nop_();
		SCLK = 0;//DS1302下降沿時,放置數據
		_nop_();
	}
	_nop_();
	for(n=0; n<8; n++)//讀取8位數據
	{
		dat1 = DSIO;//從最低位開始接收
		dat = (dat>>1) | (dat1<<7);
		SCLK = 1;
		_nop_();
		SCLK = 0;//DS1302下降沿時,放置數據
		_nop_();
	}

	RST = 0;
	_nop_();	//以下為DS1302復位的穩定時間,必須的。
	SCLK = 1;
	_nop_();
	DSIO = 0;
	_nop_();
	DSIO = 1;
	_nop_();
	return dat;	
}


至於其他什么涓流充電選擇那些,詳情看文檔:https://files.cnblogs.com/files/guguobao/DS1302中文手冊.pdf

最后附上單片機代碼

  • ds1302.c
#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時鍾初始化2016年5月7日星期六12點00分00秒。---//
//---存儲順序是秒分時日月周年,存儲格式是用BCD碼---//
uchar TIME[7] = {0, 0, 0x12, 0x07, 0x05, 0x06, 0x16};

/*******************************************************************************
* 函 數 名         : Ds1302Write
* 函數功能		   : 向DS1302命令(地址+數據)
* 輸    入         : addr,dat
* 輸    出         : 無
*******************************************************************************/

void Ds1302Write(uchar addr, uchar dat)
{
	uchar n;
	RST = 0;
	_nop_();

	SCLK = 0;//先將SCLK置低電平。
	_nop_();
	RST = 1; //然后將RST(CE)置高電平。
	_nop_();

	for (n=0; n<8; n++)//開始傳送八位地址命令
	{
		DSIO = addr & 0x01;//數據從低位開始傳送
		addr >>= 1;
		SCLK = 1;//數據在上升沿時,DS1302讀取數據
		_nop_();
		SCLK = 0;
		_nop_();
	}
	for (n=0; n<8; n++)//寫入8位數據
	{
		DSIO = dat & 0x01;
		dat >>= 1;
		SCLK = 1;//數據在上升沿時,DS1302讀取數據
		_nop_();
		SCLK = 0;
		_nop_();	
	}	
		 
	RST = 0;//傳送數據結束
	_nop_();
}

/*******************************************************************************
* 函 數 名         : Ds1302Read
* 函數功能		   : 讀取一個地址的數據
* 輸    入         : addr
* 輸    出         : dat
*******************************************************************************/

uchar Ds1302Read(uchar addr)
{
	uchar n,dat,dat1;
	RST = 0;
	_nop_();

	SCLK = 0;//先將SCLK置低電平。
	_nop_();
	RST = 1;//然后將RST(CE)置高電平。
	_nop_();

	for(n=0; n<8; n++)//開始傳送八位地址命令
	{
		DSIO = addr & 0x01;//數據從低位開始傳送
		addr >>= 1;
		SCLK = 1;//數據在上升沿時,DS1302讀取數據
		_nop_();
		SCLK = 0;//DS1302下降沿時,放置數據
		_nop_();
	}
	_nop_();
	for(n=0; n<8; n++)//讀取8位數據
	{
		dat1 = DSIO;//從最低位開始接收
		dat = (dat>>1) | (dat1<<7);
		SCLK = 1;
		_nop_();
		SCLK = 0;//DS1302下降沿時,放置數據
		_nop_();
	}

	RST = 0;
	_nop_();	//以下為DS1302復位的穩定時間,必須的。
	SCLK = 1;
	_nop_();
	DSIO = 0;
	_nop_();
	DSIO = 1;
	_nop_();
	return dat;	
}

/*******************************************************************************
* 函 數 名         : Ds1302Init
* 函數功能		   : 初始化DS1302.
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/

void Ds1302Init()
{
	uchar n;
	Ds1302Write(0x8E,0X00);		 //禁止寫保護,就是關閉寫保護功能
	for (n=0; n<7; n++)//寫入7個字節的時鍾信號:分秒時日月周年
	{
		Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);	
	}
	Ds1302Write(0x8E,0x80);		 //打開寫保護功能
}

/*******************************************************************************
* 函 數 名         : Ds1302ReadTime
* 函數功能		   : 讀取時鍾信息
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/

void Ds1302ReadTime()
{
	uchar n;
	for (n=0; n<7; n++)//讀取7個字節的時鍾信號:分秒時日月周年
	{
		TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
	}
		
}


  • ds1302.h
#ifndef __DS1302_H_
#define __DS1302_H_

//---包含頭文件---//
#include<reg52.h>
#include<intrins.h>

//---重定義關鍵詞---//
#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint 
#define uint unsigned int
#endif

//---定義ds1302使用的IO口---//
sbit DSIO=P3^4;
sbit RST=P3^5;
sbit SCLK=P3^6;

//---定義全局函數---//
void Ds1302Write(uchar addr, uchar dat);
uchar Ds1302Read(uchar addr);
void Ds1302Init();
void Ds1302ReadTime();

//---加入全局變量--//
extern uchar TIME[7];	//加入全局變量

#endif
  • main.c
/**************************************************************************************
*		              DS1302時鍾實驗												  *
實現現象:	具體接線操作請參考視頻
			下載程序后,數碼管顯示時鍾數據
注意事項:	注意將時鍾模塊的JP1302短接片短接,
			74HC595模塊的短接片JP595拔掉,
			NE555模塊的短接片J11拔掉。																			  
***************************************************************************************/

#include "reg52.h"			 //此文件中定義了單片機的一些特殊功能寄存器
#include "ds1302.h"	

typedef unsigned int u16;	  //對數據類型進行聲明定義
typedef unsigned char u8;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;


char num=0;
u8 DisplayData[8];
u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

/*******************************************************************************
* 函 數 名         : delay
* 函數功能		   : 延時函數,i=1時,大約延時10us
*******************************************************************************/
void delay(u16 i)
{
	while(i--);	
}


/*******************************************************************************
* 函 數 名         : datapros()
* 函數功能		   : 時間讀取處理轉換函數
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/

void datapros() 	 
{
   	Ds1302ReadTime();
	DisplayData[0] = smgduan[TIME[2]/16];				//時
	DisplayData[1] = smgduan[TIME[2]&0x0f];				 
	DisplayData[2] = 0x40;
	DisplayData[3] = smgduan[TIME[1]/16];				//分
	DisplayData[4] = smgduan[TIME[1]&0x0f];	
	DisplayData[5] = 0x40;
	DisplayData[6] = smgduan[TIME[0]/16];				//秒
	DisplayData[7] = smgduan[TIME[0]&0x0f];
}


/*******************************************************************************
* 函數名         :DigDisplay()
* 函數功能		 :數碼管顯示函數
* 輸入           : 無
* 輸出         	 : 無
*******************************************************************************/
void DigDisplay()
{
	u8 i;
	for(i=0;i<8;i++)
	{
		switch(i)	 //位選,選擇點亮的數碼管,
		{
			case(0):
				LSA=0;LSB=0;LSC=0; break;//顯示第0位
			case(1):
				LSA=1;LSB=0;LSC=0; break;//顯示第1位
			case(2):
				LSA=0;LSB=1;LSC=0; break;//顯示第2位
			case(3):
				LSA=1;LSB=1;LSC=0; break;//顯示第3位
			case(4):
				LSA=0;LSB=0;LSC=1; break;//顯示第4位
			case(5):
				LSA=1;LSB=0;LSC=1; break;//顯示第5位
			case(6):
				LSA=0;LSB=1;LSC=1; break;//顯示第6位
			case(7):
				LSA=1;LSB=1;LSC=1; break;//顯示第7位	
		}
		P0=DisplayData[i];//發送數據
		delay(100); //間隔一段時間掃描	
		P0=0x00;//消隱
	}		
}

/*******************************************************************************
* 函 數 名       : main
* 函數功能		 : 主函數
* 輸    入       : 無
* 輸    出    	 : 無
*******************************************************************************/
void main()
{	
	Ds1302Init();
	while(1)
	{
		datapros();	 //數據處理函數
		DigDisplay();//數碼管顯示函數		
	}		
}



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM