Ⅰ ds1302怎麼接單片機
DS1302晶元與51單片機的連接
DS1302電路圖
X1、X2:32.768KHz晶振接入引腳。(15分頻1HZ——1S定時,時鍾通用晶振)
GND:接地。
RET :復位引腳,低電平有效,操作時高電平。
I/O:數據輸入/輸出引腳,具有三態功能。
SCLK:串列時鍾輸入引腳。
Vcc1:工作電源引腳。
Vcc2:備用電源引腳。
Ⅱ 單片機中的DS1302編程時,它的讀、寫底層函數是干什麼用的,DS1302的初始化又是做什麼的
#include "ds1302.h"
void delaynus(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++);
}
void Write1302(unsigned char dat)
{
unsigned char i;
SCLK=0; //拉低SCLK,為脈沖上升沿寫入數據做好准備
delaynus(2); //稍微等待,使硬體做好准備
for(i=0;i<8;i++) //連續寫8個二進制位數據
{ DATA=dat&0x01; //取出dat的第0位數據寫入1302 低位在前,高位在後
delaynus(2); //稍微等待,使硬體做好准備
SCLK=1; //上升沿寫入數據
delaynus(2); //稍微等待,使硬體做好准備
SCLK=0; //重新拉低SCLK,形成脈沖
dat>>=1; //將dat的各數據位右移1位,准備寫入下一個數據位
} }
void WriteSet1302(unsigned char Cmd,unsigned char dat)
{
RST=0; //禁止數據傳遞
SCLK=0; //確保寫數居前SCLK被拉低
RST=1; //啟動數據傳輸
delaynus(2); //稍微等待,使硬體做好准備
Write1302(Cmd); //寫入命令字
Write1302(dat); //寫數據
SCLK=1; //將時鍾電平置於高電平狀態
RST=0; //禁止數據傳遞
}
unsigned char Read1302(void)
{
unsigned char i,dat;
delaynus(2); //稍微等待,使硬體做好准備
for(i=0;i<8;i++) //連續讀8個二進制位數據
{ dat>>=1;
if(DATA==1) //如果讀出的數據是1
dat|=0x80; //將1取出,寫在dat的最高位
SCLK=1; //將SCLK置於高電平,為下降沿讀出
delaynus(2); //稍微等待
SCLK=0; //拉低SCLK,形成脈沖下降沿
delaynus(2); //稍微等待
}
return dat; //將讀出的數據返回
}
unsigned char ReadSet1302(unsigned char Cmd)
{
unsigned char dat;
RST=0; //拉低RST
SCLK=0; //確保寫數居前SCLK被拉低
RST=1; //啟動數據傳輸
Write1302(Cmd); //寫入命令字
dat=Read1302(); //讀出數據
SCLK=1; //將時鍾電平置於已知狀態
RST=0; //禁止數據傳遞
return dat; //將讀出的數據返回
}
void Init_DS1302(void)
{
unsigned char flag;
flag= ReadSet1302(0x81);
if(flag&0x80) //判斷時鍾晶元是否關閉
{ WriteSet1302(0x8E,0x00); //根據寫狀態寄存器命令字,寫入不保護指令
WriteSet1302(0x80,((55/10)<<4|(55%10))); //根據寫秒寄存器命令字,寫入秒的初始值
WriteSet1302(0x82,((59/10)<<4|(59%10))); //根據寫分寄存器命令字,寫入分的初始值
WriteSet1302(0x84,((23/10)<<4|(23%10))); //根據寫小時寄存器命令字,寫入小時的初始值
WriteSet1302(0x86,((18/10)<<4|(18%10))); //根據寫日寄存器命令字,寫入日的初始值
WriteSet1302(0x88,((6/10)<<4|(6%10))); //根據寫月寄存器命令字,寫入月的初始值
WriteSet1302(0x8c,((9/10)<<4|(9%10))); //根據寫年寄存器命令字,寫入年的初始值
WriteSet1302(0x90,0xa5); //打開充電功能 選擇2K電阻充電方式
WriteSet1302(0x8E,0x80); //根據寫狀態寄存器命令字,寫入保護指令
}
}
Ⅲ 基於51單片機的數字時鍾為什麼用DS1302
你使用這樣的電路可以,前提是不掉電的情況下,而且精確度有待商榷,如果使用DS1302,內置時間寄存器,並可對時間進行校正,同時,如果對其加電池,那麼時間不會停止,一直走動,否則,按您的電路,你一關電,所有的時間你得重新設置。希望您明白我的意思。
Ⅳ 單片機和ds1302各自都怎麼工作
ds1302是時鍾晶元 主要是計算年、月、日和星期的,上電後他就自動計時,從他的初始時間開始計時。單片機就是負責去1302的相應寄存器中讀取時間和改寫時間(就是可以通過按鍵程序來設定時間),之後再負責顯示出來。
Ⅳ ds1302時鍾晶元工作原理
DS1302結構與工作原理
DS1302 是美國DALLAS公司推出的一種高性能、低功耗、帶RAM的實時時鍾,有計時的作用,和日常接觸的電子表,萬年歷差不多,可以對年月日、時分秒、星期計時。可以用單片機往DS1302裡面寫入時間進行時間設置,也可以用單片機從DS1302中讀取時間,讀出來的時間也可以放在液晶上顯示。這樣就可以實現一塊電子表的功能了。
DS1302引腳及功能:
X1,X2: 振盪源管腳,外接32.768KHz晶振
GND: 地
RST: 復位/片選線(通過置高電平來啟動所有的數據傳送。)
IO: 數據輸入輸出
SCLK: 串列時鍾
VCC1: 電池引腳
VCC2: 主電源引腳 (雙電源供電,在主電源關閉的情況下,有VCC1的電池供電,也能保持時鍾的連續運行)
DS1302的工作原理很簡單,它外接32768Hz的晶振提供震盪時鍾。晶元內部的電路對晶振頻率32768分頻後獲得周期為1S的秒信號,然後對秒信號計數,獲得分鍾、小時、天、星期、月、年等的數值。
實現方法:
DS1302的時間信息以寄存器的形式存儲在晶元內部。DS1302的通訊介面由3根線組成,即RST,SCLK,I/O。單片機與DS1302通訊,採用的是SPI通訊介面,只不過是半雙工了,只能分時進行收發。通過SPI介面,對相應的寄存器進行讀操作,可以獲得當前時間數值;寫操作,可以設定當前時間。
下面介紹怎麼對DS1302發號施令。
DS1302的命令位元組格式:
一個完整的通訊幀由由2位元組組成。第一位元組是控制位元組,第二位元組為數據位。控制字格式如下:
1.bit0:讀寫標志。高電平為讀,第二位元組(藍色圈內)會由DS1302輸出數據;低電平為寫,第二位元組由單片機輸出數據, DS1302接收;
2.bit1~5: 5位操作元地址,就是要對哪個寄存器進行操作。寄存器地址列表如圖2.1。(紅色圈內)
3.bit6:選擇RAM區或寄存器區。如果為0,則表示存取日歷時鍾數據,為1表示存取RAM數據;
4. bit7:必須是邏輯1,如果它為0,則不能把數據寫入DS1302中。
圖2.1
(CH:時鍾停止位;為0時振盪器工作;為1時振盪器停止;AP=1時為下午模式,為0時上午模式。圖2.1內還應該有第八個寄存器,地址為8E。它的bit7是需要重視的。bit7是一個保護位,如果這一位是1,那麼是禁止給任何其他的寄存器或者那31個位元組的RAM寫數據的。因此在寫數據之前,這一位必須先寫成0。)
因為是SPI介面,單片機與DS1302通訊也是上升沿發送(寫入1302數據),下降沿接收(讀取1302數據)。控制字總是從最低位開始輸出。在控制字指令輸入後的下一個SCLK時鍾的上升沿時,數據被寫入DS1302,數據輸入從最低位(0位)開始。同樣,在緊跟8位的控制字指令後的下一個SCLK脈沖的下降沿,讀出DS1302的數據。讀出的數據也是從最低位到最高位。數據讀寫時序如下圖:
Ⅵ 單片機 DS1302
/********************************************************************
*
* 名稱: DS1302_InputByte()
* 功能: 往DS1302寫入1Byte數據
* 輸入: ucDa 寫入的數據
***********************************************************************/
void DS1302_InputByte(unsigned char ucDa)
{
unsigned char i;
unsigned char temp;
temp = ucDa;
for(i=8; i>0; i--)
{
T_IO = temp&0x01;
T_CLK = 1;
T_CLK = 0;
temp = temp >> 1;
}
}
/********************************************************************
*
* 名稱: DS1302_OutputByte()
* 功能: 從DS1302讀取1Byte數據
***********************************************************************/
unsigned char DS1302_OutputByte(void)
{
unsigned char i;
unsigned char temp;
temp=0;
for(i=0; i<8;i++)
{
T_CLK = 0;
if(T_IO!=0) temp|=(1<<i);
T_CLK = 1;
}
return(temp);
}
/********************************************************************
*
* 名稱: DS1302_InputByte()
* 說明: 先寫地址,後寫命令/數據
* 功能: 往DS1302寫入數據
* 輸入: ucAddr: DS1302地址, ucDa: 要寫的數據
***********************************************************************/
void DS1302_W1302(unsigned char ucAddr, unsigned char ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
DS1302_InputByte(ucAddr); /* 地址,命令 */
DS1302_InputByte(ucDa); /* 寫1Byte數據*/
T_CLK = 1;
T_RST =0;
}
/********************************************************************
*
* 名稱: DS1302_R1302()
* 說明: 先寫地址,後讀命令/數據
* 功能: 讀取DS1302某地址的數據
* 輸入: ucAddr: DS1302地址
***********************************************************************/
unsigned char DS1302_R1302(unsigned char ucAddr)
{
unsigned char ucDa;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
DS1302_InputByte(ucAddr); /* 地址,命令 */
ucDa = DS1302_OutputByte(); /* 讀1Byte數據 */
T_CLK = 1;
T_RST =0;
return(ucDa);
}
/********************************************************************
*
* 名稱: DS1302_Get1302()
* 說明:
* 功能: 讀取DS1302當前時間
* 調用: DS1302_R1302()
* 輸入: ucCurtime: 保存當前時間地址。當前時間格式為: 秒 分 時 日 月 星期 年
***********************************************************************/
void DS1302_Get1302(unsigned char ucCurtime[])
{
unsigned char i;
unsigned char ucAddr = 0x81;
for (i=0;i<7;i++)
{
ucCurtime[i] = DS1302_R1302(ucAddr);/*格式為: 秒 分 時 日 月 星期 年 */
ucAddr += 2;
}
}
void delay(uint i)
{
uint k;
while(i--)
{
for(k=0;k<120;k++){;}
}
}
/********************************************************************
* 名稱: DS1302_Set1302()
* 功能: 設置時間
初始時間格式為: 秒 分 時 日 月 星期 年
***********************************************************************/
void DS1302_Set1302(void) interrupt 0
{
uchar b[7];
uchar *p;
uint k;
unsigned char Addr = 0x80;
DS1302_Get1302(b);
p=b;
DS1302_W1302(0x8e,0x00); /* 控制命令,WP=0,允許寫操作*/
while(k4==1)
{
if(k1==0)
{
delay(10);
while(k1==0);
p++;
}
else if(k2==0)
{
delay(10);
while(k2==0);
*p=*p++;
}
else if(k3==0)
{
delay(10);
while(k3==0);
*p=*p--;
}
if(*p=='\0')
p=b;
}
p=b;
for(k =7;k>0;k--)
{
DS1302_W1302(Addr,*p); /* 秒 分 時 日 月 星期 年 */
p++;
Addr +=2;
}
DS1302_W1302(0x8e,0x80); /* 控制命令,WP=1,防寫*/
}
用這個驅動試試。如果不行就是你數碼管出問題了
Ⅶ 既然單片機本身有定時器,為什麼還需要採用DS1302來定時呢,DS1302的優點是什麼呢
單片機的定時器用的是它自己的晶振,不是專門用來做電子鍾的,因其精度不高,而且操作麻煩!而且更正一點,DS1302不是用來定時的,它是一種時鍾晶元,內部有專用的寄存器用於存年月日時分秒,用的晶振也是另接的,高精度。當秒改變到一定量是,分會自動加一,寫程序比較簡單,而單片機要寫程序讓它加一。
Ⅷ 51單片機 外接DS1302
一個是單片機外接晶體,提供單片機工作頻率用,多是4M-20M的頻率。
一個專門的時鍾晶元DS1302專用外接晶體,這種晶體都比較准確穩定,來減少時鍾誤差。。
DS1302專用晶體頻率是32.768kHz,無法和單片機晶體通用。
Ⅸ 51單片機中DS1302晶元的引腳配置原理是什麼
CE和SCLK是DS1302晶元的信號線,但也是與單片機的PIO口連接的;
因此初始化CE和SCLK,也就是初始化單片機的PIO口了;
在代碼中,你可以去看看 DS1302_CE、DS1302_SCLK 的定義就明白了;
Ⅹ 單片機 DS1302時鍾讀寫問題
uchar read_Byte()
{
uchar i;
for(i = 8;i > 0;i--)
{
ACC = ACC >> 1;
ACC7 = ds1302_IO;
ds1302_SCLK = 1;
ds1302_SCLK = 0;
}
return(ACC);
}
是的,你要相信自己,然後多實踐,網上的東西只做一個參考,對不對還要由你自己來驗證。