輕松學(xué)PIC之DS1302時(shí)鐘篇
出處:maychang 發(fā)布于:2011-08-31 11:40:07
大家好,通過前一期的學(xué)習(xí),我們已經(jīng)對(duì)ICD2 仿真燒寫器和增強(qiáng)型PIC 實(shí)驗(yàn)板的使用方法及學(xué)習(xí)方式有所了解與熟悉,學(xué)會(huì)了如何用單片機(jī)來控制發(fā)光管、繼電器、蜂鳴器、按鍵、數(shù)碼管、RS232串口、步進(jìn)電機(jī)、溫度傳感器、I2C 總線、SPI 總線等資源,體會(huì)到了學(xué)習(xí)板的易用性與易學(xué)性,這一期我們將介紹市面上常見的時(shí)鐘芯片DS1302 的應(yīng)用。
一、DS1302時(shí)鐘芯片簡(jiǎn)介
DS1302 是DALLAS 公司推出的涓流充電時(shí)鐘芯片,內(nèi)含一個(gè)實(shí)時(shí)時(shí)鐘/ 日歷和31 字節(jié)靜態(tài)RAM,可以通過串行接口與單片機(jī)進(jìn)行通信。實(shí)時(shí)時(shí)鐘/ 日歷電路提供秒、分、時(shí)、日、星期、月、年的信息,每個(gè)月的天數(shù)和閏年的天數(shù)可自動(dòng)調(diào)整,時(shí)鐘操作可通過AM/PM 標(biāo)志位決定采用24 或12 小時(shí)時(shí)間格式。DS1302 與單片機(jī)之間能簡(jiǎn)單地采用同步串行的方式進(jìn)行通信,僅需三根I/O 線:復(fù)位(RST)、I/O 數(shù)據(jù)線、串行時(shí)鐘(SCLK)。時(shí)鐘/RAM 的讀/寫數(shù)據(jù)以一字節(jié)或多達(dá)31 字節(jié)的字符組方式通信。
DS1302 工作時(shí)功耗很低,保持?jǐn)?shù)據(jù)和時(shí)鐘信息時(shí),功耗小于1mW。
1. DS1302 的內(nèi)部結(jié)構(gòu)
DS1302 的外部引腳功能說明如圖1 所示。

圖1 DS1302封裝圖
DS1302 的內(nèi)部結(jié)構(gòu)如圖2 所示,主要組成部分為:移位寄存器、控制邏輯、振蕩器、實(shí)時(shí)時(shí)鐘以及RAM。雖然數(shù)據(jù)分成兩種,但是對(duì)單片機(jī)的程序而言,其實(shí)是一樣的,就是對(duì)特定的地址進(jìn)行讀寫操作。

圖2 DS1302的內(nèi)部結(jié)構(gòu)圖
DS1302 含充電電路,可以對(duì)作為后備電源的可充電電池充電,并可選擇充電使能和串入的二極管數(shù)目,以調(diào)節(jié)電池充電電壓。不過對(duì)我們目前而言,需要熟悉的是和時(shí)鐘相關(guān)部分的功能,對(duì)于其它參數(shù)請(qǐng)參閱數(shù)據(jù)手冊(cè)。
2. DS1302 的工作原理
DS1302 工作時(shí)為了對(duì)任何數(shù)據(jù)傳送進(jìn)行初始化,需要將復(fù)位腳(RST)置為高電平且將8 位地址和命令信息裝入移位寄存器。數(shù)據(jù)在時(shí)鐘(SCLK)的上升沿串行輸入,前8 位指定訪問地址,命令字裝入移位寄存器后,在之后的時(shí)鐘周期,讀操作時(shí)輸出數(shù)據(jù),寫操作時(shí)輸出數(shù)據(jù)。時(shí)鐘脈沖的個(gè)數(shù)在單字節(jié)方式下為8+8(8 位地址+8 位數(shù)據(jù)),在多字節(jié)方式下為8 加多可達(dá)248 的數(shù)據(jù)。
3. DS1302 的寄存器和控制命令
對(duì)DS1302 的操作就是對(duì)其內(nèi)部寄存器的操作,DS1302 內(nèi)部共有12 個(gè)寄存器,其中有7 個(gè)寄存器與日歷、時(shí)鐘相關(guān),存放的數(shù)據(jù)位為BCD 碼形式。
此外,DS1302 還有年份寄存器、控制寄存器、充電寄存器、時(shí)鐘突發(fā)寄存器及與RAM 相關(guān)的寄存器等。
時(shí)鐘突發(fā)寄存器可性順序讀寫除充電寄存器以外的寄存器。日歷、時(shí)間寄存器及控制字如表1 所示。
表1 日歷、時(shí)鐘寄存器與控制字對(duì)照表

一位RD/W 為“0”時(shí)表示進(jìn)行寫操作,為“1”時(shí)表示讀操作。
DS1302 內(nèi)部寄存器列表如表2 所示。
DS1302 內(nèi)部的RAM 分為兩類,一類是單個(gè)RAM 單元,共31 個(gè),每個(gè)單元為一個(gè)8 位的字節(jié),其命令控制字為COH~FDH,其中奇數(shù)為讀操作,偶數(shù)為寫操作;再一類為突發(fā)方式下的RAM,此方式下可性讀寫所有的RAM 的31 個(gè)字節(jié),命令控制字為FEH(寫)、FFH(讀)。
表2 DS14302內(nèi)部主要寄存器分布表

我們現(xiàn)在已經(jīng)知道了控制寄存器和RAM 的邏輯地址,接著就需要知道如何通過外部接口來訪問這些資源。單片機(jī)是通過簡(jiǎn)單的同步串行通訊與DS1302通訊的,每次通訊都必須由單片機(jī)發(fā)起,無論是讀還是寫操作,單片機(jī)都必須先向DS1302 寫入一個(gè)命令幀,位BIT7 固定為1,BIT6 決定操作是針對(duì)RAM 還是時(shí)鐘寄存器,接著的5 個(gè)BIT 是RAM或時(shí)鐘寄存器在DS1302 的內(nèi)部地址,一個(gè)BIT表示這次操作是讀操作抑或是寫操作。
物理上,DS1302 的通訊接口由3 個(gè)口線組成,即RST,SCLK,I/O。其中RST 從低電平變成高電平啟動(dòng)數(shù)據(jù)傳輸過程,SCLK 是時(shí)鐘線,I/O 是數(shù)據(jù)線。具體的讀寫時(shí)序參考圖3,但是請(qǐng)注意,無論是哪種同步通訊類型的串行接口,都是對(duì)時(shí)鐘信號(hào)敏感的,而且一般數(shù)據(jù)寫入有效是在上升沿,讀出有效是在下降沿(DS1302 正是如此的,但是在芯片手冊(cè)里沒有明確說明),如果不是特別確定,則把程序設(shè)計(jì)成這樣:平時(shí)SCLK 保持低電平,在時(shí)鐘變動(dòng)前設(shè)置數(shù)據(jù),在時(shí)鐘變動(dòng)后讀取數(shù)據(jù),即數(shù)據(jù)操作總是在SCLK 保持為低電平的時(shí)候,相鄰的操作之間間隔有一個(gè)上升沿和一個(gè)下降沿。

圖3 DS1302的命令字結(jié)構(gòu)
通過前文的原理介紹,我們已經(jīng)對(duì)DS1302 時(shí)鐘芯片的特性以及工作原理有了大致地了解,但當(dāng)我們拿到一個(gè)時(shí)鐘器件時(shí)要正確地應(yīng)用它還是一時(shí)不知如何下手,比如我們要做一個(gè)簡(jiǎn)單的時(shí)間顯示,需要怎么辦呢?首先,時(shí)鐘芯片與單片機(jī)的連接非常簡(jiǎn)單,一般來說,我們只需要將IIC 器件的復(fù)位“RST”、數(shù)據(jù)“I/O”、時(shí)鐘“SCLK”端與單片機(jī)的I/O 口相連,就可以進(jìn)行時(shí)間、日期數(shù)據(jù)的寫入或讀取了。現(xiàn)在,我們來一起看一個(gè)使用DS1302 做時(shí)間顯示的例子,通過一個(gè)實(shí)例,相信會(huì)給大家?guī)硪粋€(gè)感性的認(rèn)識(shí)。
首先, 我們來看一下增強(qiáng)型PIC 實(shí)驗(yàn)板上DS1302 器件的接口電路,因?yàn)槲覀冃枰獙④浖陀布嘟Y(jié)合進(jìn)行考慮如何來編程,完成該實(shí)驗(yàn)的硬件原理圖如圖4 所示,U2 為實(shí)驗(yàn)板上DS1302 芯片,“I/O”
與單片機(jī)的RB5 口相連,“SCLK”與單片機(jī)RB6 相連,“RST”與單片機(jī)RB7 相連,七段數(shù)碼管D5、D7、D8 組成了顯示單元,字形碼的數(shù)據(jù)通過RC 口送入,各數(shù)碼管的顯示片選信號(hào)分別不同的RA 口進(jìn)行控制。

圖4 硬件原理圖
對(duì)于單機(jī)軟件的編程,我們使用MPLab IDE 軟件來進(jìn)行C 語(yǔ)言編程,它是我們的編程環(huán)境,同時(shí)我們可以通過使用ICD2 仿真燒寫器和增強(qiáng)型PIC 實(shí)驗(yàn)板連接進(jìn)行程序的仿真調(diào)試和燒寫步驟,具體的操作步驟,我們已經(jīng)在前幾期做了詳細(xì)的說明和介紹,在此就不再重復(fù)說明,讀者朋友可以參閱以前的文章或直接登陸我們的網(wǎng)站查看資料。現(xiàn)在我們可以輸入程序代碼進(jìn)行調(diào)試了,我們?cè)贛PLab IDE 軟件中新建工程,加入源程序代碼,同時(shí)進(jìn)行芯片型號(hào)的選擇和配置位的設(shè)置,我們實(shí)驗(yàn)所用的芯片型號(hào)為PIC16F877A。編寫的程序代碼如下,其中程序流程圖如圖5 所示,實(shí)際運(yùn)行效果如圖6 所示。

圖5 軟件流程

圖6 DS1302 實(shí)驗(yàn)演示圖
二、軟件代碼
/*************************************************/
/*DS1302 讀寫演示程序 */
/* 目標(biāo)器件:PIC16F877A */
/* 晶振:4.0MHZ */
/* 編譯環(huán)境:MPLAB V7.51 */
/**************************************************/
#include<pic.h>
#define i_o RB5
#define sclk RB6
#define rst RB7
unsigned char time_rx @ 0x30;
// 定義接收寄存器
static volatile bit time_rx7 @ (unsigned)&time_rx*8+7;
// 接收寄存器的位
/***************************************************
子函數(shù)定義
**************************************************/
void port_init(); // 申明引腳初始化函數(shù)
void ds1302_init(); // 申明DS1302 初始化函數(shù)
void set_time(); // 申明設(shè)置時(shí)間函數(shù)
void get_time(); // 申明讀取時(shí)間函數(shù)
void display(); // 申明顯示函數(shù)
void time_write_1(unsigned char time_tx);
// 申明寫一個(gè)字節(jié)函數(shù)
unsigned char time_read_1();
// 申明讀一個(gè)字節(jié)函數(shù)
void delay(); // 申明延時(shí)函數(shù)
/***************************************************
時(shí)間和日期存放表
**************************************************/
const char table[]={0x00,0x30,0x12,0x8,0x3,0x06,0x06,0x00};
char table1[7];
/**************************************************
共陰LED 段碼表
**************************************************/
const char table2[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
void main()
{
port_init(); // 調(diào)用引腳初始化函數(shù)
TRISC =0x00;
ds1302_init(); // 調(diào)用DS1302 初始化函數(shù)
set_time(); // 調(diào)用設(shè)置時(shí)間函數(shù)
while(1)
{
get_time(); // 調(diào)用取時(shí)間函數(shù)
display(); // 調(diào)用顯示函數(shù)
}
}
void ds1302_init() // DS1302 初始化函數(shù)子程序
{
sclk=0; // 拉低時(shí)鐘信號(hào)
rst =0; // 復(fù)位DS1302
rst=1; // 使能DS1302
time_write_1(0x8e); // 發(fā)控制命令
time_write_1(0); // 允許寫DS1302
rst=0; // 復(fù)位
}
void set_time() // 設(shè)置時(shí)間函數(shù)子程序
{
int i; // 定義循環(huán)變量
rst=1; // 使能DS1302
time_write_1(0xbe); // 時(shí)鐘多字節(jié)寫命令
for(i=0;i<8;i++) // 連續(xù)寫8 個(gè)字節(jié)數(shù)據(jù)
{
time_write_1(table[i]); // 調(diào)用寫一個(gè)字節(jié)函數(shù)
delay();
}
rst=0; // 復(fù)位
}
void get_time() // 讀取時(shí)間函數(shù)子程序
{
int i; // 設(shè)置循環(huán)變量
rst=1; // 使能DS1302
time_write_1(0xbf); // 發(fā)送多字節(jié)讀取命令
for(i=0;i<7;i++) // 連續(xù)讀取7 個(gè)字節(jié)數(shù)據(jù)
{
table1[i]=time_read_1();
// 調(diào)用讀取1 個(gè)字節(jié)數(shù)據(jù)的函數(shù)
delay();
}
rst=0; // 復(fù)位DS1302
}
void time_write_1(unsigned char time_tx)
{
int j; // 設(shè)置循環(huán)變量
for(j=0;j<8;j++) // 連續(xù)寫8bit
{
i_o=0; // 先設(shè)置數(shù)據(jù)為0
sclk=0; // 時(shí)鐘信號(hào)拉低
if(time_tx&0x01) // 判斷待發(fā)送的數(shù)據(jù)位是0 或1
{
i_o=1; // 待發(fā)送數(shù)據(jù)位是1
}
time_tx=time_tx》1; // 待發(fā)送的數(shù)據(jù)右移1 位
sclk=1; // 拉高時(shí)鐘信號(hào)
}
sclk=0; // 寫完一個(gè)字節(jié),拉低時(shí)鐘信號(hào)
}
unsigned char time_read_1()
{
int j; // 設(shè)置循環(huán)變量
TRISB5=1; // 設(shè)置數(shù)據(jù)口方向?yàn)檩斎?/FONT>
for(j=0;j<8;j++) // 連續(xù)讀取8bit
{
sclk=0; // 拉低時(shí)鐘信號(hào)
time_rx=time_rx》1; // 接收寄存器右移1 位
time_rx7=i_o;
// 把接收到的數(shù)據(jù)放到接收寄存器的位sclk=1; // 拉高時(shí)鐘信號(hào)
}
TRISB5=0; // 恢復(fù)數(shù)據(jù)口方向?yàn)檩敵?/FONT>
sclk=0; // 拉低時(shí)鐘信號(hào)
return(time_rx); // 返回讀取到的數(shù)據(jù)
}
void port_init()
{
TRISA=0x00; // 設(shè)置A 口全輸出
TRISC=0X00; // 設(shè)置C 口全輸出
TRISB=0x00;
}
void display() // 顯示子程序
{
int i; // 定義查表變量
i=table1[0]&0x0f; // 求秒的個(gè)位
PORTC=table2[i]; // 送C 口顯示
PORTA=0xFD; // 點(diǎn)亮秒的個(gè)位
delay(); // 延長(zhǎng)一段時(shí)間,保證亮度
i=table1[0]&0xf0; // 求秒的十位
i=i》4; // 右移4 位
PORTC=table2[i]; // 送C 口顯示
PORTA=0xFE; // 點(diǎn)亮秒的十位
delay(); // 延長(zhǎng)一段時(shí)間,保證亮度
i=table1[1]&0x0f; // 求分的個(gè)位
PORTC=table2[i]&0x7f;
// 送C 口顯示,并顯示小數(shù)點(diǎn)
PORTA=0xF7; // 點(diǎn)亮分的個(gè)位
delay(); // 延時(shí)一定時(shí)間,保證亮度
i=table1[1]&0xf0; // 求分的十位
i=i》4;
PORTC=table2[i]; // 送C 口顯示
PORTA=0xFB; // 點(diǎn)亮分的十位
delay(); // 延長(zhǎng)一段時(shí)間,保證亮度
i=table1[2]&0x0f; // 求時(shí)的個(gè)位
PORTC=table2[i]&0x7f;
// 送C 口顯示,并加上小數(shù)點(diǎn)
PORTA=0xDF; // 點(diǎn)亮?xí)r的個(gè)位
delay(); // 延時(shí)一定時(shí)間,保證亮度
i=table1[2]&0xf0; // 求時(shí)的十位
i=i》4;
PORTC=table2[i]; // 送C 口顯示
PORTA=0xEF; // 點(diǎn)亮?xí)r的十位
delay(); // 延長(zhǎng)一段時(shí)間,保證亮度
}
void delay() // 延時(shí)程序
{
int i; // 定義整形變量
for(i=100;i--;); // 延時(shí)
}
看到這里,相信你現(xiàn)在已經(jīng)可以完成一些簡(jiǎn)單的電子鐘實(shí)驗(yàn),DS1302 的原理與使用我們講到這里。
增強(qiáng)型PIC 實(shí)驗(yàn)板系統(tǒng)資源豐富,可做實(shí)驗(yàn)有:6 位LED 數(shù)碼管、8 路LED、直控鍵盤、蜂鳴器喇叭、繼電器試驗(yàn)、I2C 總線接口、SPI 總線接口、160X 液晶、128X64 液晶、紅外接收頭接口、步進(jìn)電機(jī)驅(qū)動(dòng)接口、AD 模/ 數(shù)轉(zhuǎn)換接口、串行時(shí)鐘芯片DS1302、溫度傳感器DS18B20 接口、RS232 串口通訊、外擴(kuò)展接口以便外接更多的實(shí)驗(yàn)資源。
版權(quán)與免責(zé)聲明
凡本網(wǎng)注明“出處:維庫(kù)電子市場(chǎng)網(wǎng)”的所有作品,版權(quán)均屬于維庫(kù)電子市場(chǎng)網(wǎng),轉(zhuǎn)載請(qǐng)必須注明維庫(kù)電子市場(chǎng)網(wǎng),http://hbjingang.com,違反者本網(wǎng)將追究相關(guān)法律責(zé)任。
本網(wǎng)轉(zhuǎn)載并注明自其它出處的作品,目的在于傳遞更多信息,并不代表本網(wǎng)贊同其觀點(diǎn)或證實(shí)其內(nèi)容的真實(shí)性,不承擔(dān)此類作品侵權(quán)行為的直接責(zé)任及連帶責(zé)任。其他媒體、網(wǎng)站或個(gè)人從本網(wǎng)轉(zhuǎn)載時(shí),必須保留本網(wǎng)注明的作品出處,并自負(fù)版權(quán)等法律責(zé)任。
如涉及作品內(nèi)容、版權(quán)等問題,請(qǐng)?jiān)谧髌钒l(fā)表之日起一周內(nèi)與本網(wǎng)聯(lián)系,否則視為放棄相關(guān)權(quán)利。
- MOSFET在UPS電源中的應(yīng)用解析2026/4/17 11:17:06
- SMT連接器焊接缺陷分析2026/4/17 10:57:47
- MOSFET在汽車電子中的應(yīng)用要求2026/4/16 14:02:53
- 通信設(shè)備電源管理IC應(yīng)用解析2026/4/16 13:55:54
- 通信設(shè)備連接器選型與設(shè)計(jì)2026/4/16 13:50:06
- 高速PCB阻抗控制核心實(shí)操規(guī)范
- 高速數(shù)字系統(tǒng)(如DDR、SerDes)中的信號(hào)完整性濾波
- MOSFET在UPS電源中的應(yīng)用解析
- 電源管理IC在物聯(lián)網(wǎng)設(shè)備中的應(yīng)用
- SMT連接器焊接缺陷分析
- MOSFET在汽車電子中的應(yīng)用要求
- 通信設(shè)備電源管理IC應(yīng)用解析
- 通信設(shè)備連接器選型與設(shè)計(jì)
- PCB電磁兼容性(EMC)設(shè)計(jì)核心實(shí)操規(guī)范
- 物聯(lián)網(wǎng)節(jié)點(diǎn)低功耗設(shè)計(jì):信號(hào)鏈中的濾波與功耗管理









