一、PCF8563
摘要:
PCF8563是PLILIPS公司生產(chǎn)的低功耗CMOS實(shí)時時鐘/日歷芯片,文中介紹了PCF8563的結(jié)構(gòu)、功能及工作原理。結(jié)合其在8051系統(tǒng)中的應(yīng)用實(shí)例,給出了PCF8563與8051單片機(jī)的硬件接口電路和C語言軟件編程程序,再結(jié)合linux簡單講解一下,先結(jié)全51不跑操作系統(tǒng),讓讀者對硬件有個好的理解,后面再結(jié)合操作系統(tǒng),讓各位對操作系統(tǒng)和整個流程有個清楚的認(rèn)識。
1 PCF8563簡介
PCF8563是PHILIPS公司生產(chǎn)的低功耗CMOS實(shí)時時鐘/日歷芯片,芯片最大總線速度為400kbits/s,每次讀寫數(shù)據(jù)后,其內(nèi)嵌的字地址寄存器器會自動產(chǎn)生增量。PCF8563可廣泛應(yīng)用于移動電話、便攜儀器、傳真機(jī)、電池電源等產(chǎn)品中。
PCF8563的引腳排列如圖1所示,各引腳功能說明如表1所列。
PCF8563有16個8位寄存器,其中包括:可自動增量的地址寄存器、內(nèi)置32.768kHz的振蕩器(帶有一個內(nèi)部集成電容)、分頻器(用于給實(shí)時時鐘RTC提供源時鐘)、可編程時鐘輸出、定時器、報警器、掉電檢測器和400kHz的I2C總線接口。
所有16個寄存器設(shè)計成可尋址的8位并行寄存器,但不是所有位都有用。當(dāng)一個RTC寄存器被讀時,所有計數(shù)器的內(nèi)容將被鎖存,因此,在傳送條件下,可以禁止對時鐘/日歷芯片的錯讀。
表2、表3所列為各寄存器概況及對應(yīng)的內(nèi)存地址和功能,同時列出了它們的BCD格式編碼。表中“——”表示無效位,“0”表示此位應(yīng)置邏輯。表3中的世紀(jì)位C=0指定世紀(jì)數(shù)為20XX,C=1指定世紀(jì)數(shù)為19XX。當(dāng)年寄存器中的99變00時,世紀(jì)位才會改變。
表1 PCF8563的管腳描述
符 號 | 管腳號 |
描 述 |
OSCI | 1 | 振蕩器輸入 |
OSCO | 2 | 振蕩器輸出 |
INT | 3 | 終端輸出(開漏:低電平有效) |
Vss | 4 | 地 |
SDA | 5 | 串行數(shù)據(jù)I/O |
SCL | 6 | 串行時鐘輸入 |
CLKOUT | 7 | 時鐘輸出(開漏) |
VDD | 8 | 正電源 |
2 I2C總線
2.1 I2C總線特性
I2C 總線用兩條線(SDA和SCL)在芯片和模塊間傳遞信息。SDA為串行數(shù)據(jù)線,SCL為串行時鐘線,這兩條線必須用一個上拉電阻與正電源相連,其數(shù)據(jù)只有在總線不忙時才可傳送。I2C總線的系統(tǒng)配置參見圖2,產(chǎn)生信號的設(shè)備是傳送器,接收信號的設(shè)備是接收器,控制信號的設(shè)備是主設(shè)備,受控制信號的設(shè)備是從設(shè)備。
表2 寄存器概況
地址 | 寄存器名稱 | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 |
00H | 控制/狀態(tài)寄存器1 | TEST | 0 | STOP | 0 | TESTC | 0 | 0 | 0 |
01H | 控制/狀態(tài)寄存器2 | 0 | 0 | 0 | TI/TP | AF | TF | AIE | TIE |
0DH | CLKOUT頻率寄存器 | FE | — | — | — | — | — | FD1 | FD0 |
0EH | 定時器控制寄存器 | TE | — | — | — | — | — | TD1 | TD0 |
0FH | 定時器倒計數(shù)數(shù)值寄存器 | 定時器倒計數(shù)數(shù)值 |
表3 BCD格式寄存器概況
地 址 | 寄存器名稱 | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 |
01H | 秒 | VL | 00~59BCD碼格式數(shù) | ||||||
03H | 分鐘 | - | 00~59BCD碼格式數(shù) | ||||||
04H | 小時 | - | - | 00~23BCD碼格式數(shù) | |||||
05H | 日 | - | - | 01~31BCD碼格式數(shù) | |||||
06H | 星期 | - | - | - | - | - | 0~6 | ||
07H | 月/世紀(jì) | C | - | - | 01~12BCD碼格式數(shù) | ||||
08H | 年 | 00~99BCD碼格式數(shù) | |||||||
09H | 分鐘報警 | AE | 00~59BCD碼格式數(shù) | ||||||
0AH | 小時報警 | AE | - | 00~23BCD碼格式數(shù) | |||||
0BH | 日報警 | AE | - | 01~31BCD碼格式數(shù) | |||||
0CH | 星期報警 | AE | - | - | - | - | 0~6 |
2.2 啟動和停止條件
總線不忙時,數(shù)據(jù)線和時鐘線保持在高電平。數(shù)據(jù)線(SDA)在下降沿而時鐘線(SCL)為高電平時,為起動條件(S);數(shù)據(jù)線在上升沿而時鐘線為高電平時為停止條件(P),參見圖3。
2.3 位傳送
每個時鐘脈沖傳送一個數(shù)據(jù)位,SDA線上的數(shù)據(jù)在時鐘脈沖高電平時應(yīng)保持穩(wěn)定,否則將成為控制信號,參見圖4。
2.4 標(biāo)志位
在起動條件和停止條件之間,傳送器傳送給接收器的數(shù)據(jù)數(shù)量沒有限制。在每個8位字節(jié)后加一個標(biāo)志位,傳送器便產(chǎn)生一個高電平的標(biāo)志位,這時主設(shè)備產(chǎn)生一個附加標(biāo)志位時鐘脈沖。
從接受器必須在接收到每個字節(jié)后產(chǎn)生一個標(biāo)志位,主接收器也必須在接收從傳送器傳送的每個字節(jié)后產(chǎn)生一個標(biāo)志位。在標(biāo)志位時鐘脈沖出現(xiàn)時,SDA線應(yīng)保持低電平(應(yīng)考慮起動和保持時間)。傳送器應(yīng)在從設(shè)備接收到最后一個字節(jié)時變?yōu)榈碗娖剑菇邮掌鳟a(chǎn)生標(biāo)志位,這時主設(shè)備即可產(chǎn)生停止條件。參見圖5。
2.5 I2C總線協(xié)議
用I2C 總線傳遞數(shù)據(jù)前,接收的設(shè)備應(yīng)先標(biāo)明地址,在I2C總線起動后,這個地址與第一個傳送字節(jié)一起被傳送出去。PCF8563可以作為一個從接收器或從傳送器,此時的時鐘信號線SCL只能輸入信號線,數(shù)據(jù)信號線SDA則為一條雙向信號線。PCF8563的從地址參見圖6。
3 應(yīng)用概述
圖7所示為PCF8563的具體應(yīng)用電路圖,對圖中石英晶片頻率的調(diào)整,筆者給出3種可行性方法,供參考:
方法1:定值OSCI電容。計算所需的電容平均值,用此值的定值電容,通電后在CLKOUT管腳上測出的頻率應(yīng)為32.768kHz,測出的頻率值偏差取決于石英晶片本身,電容偏差和器件之間的偏差平均為±5×10 -6。平均偏差可達(dá)5分鐘/年。
方法2:OSCI微調(diào)電容。可通過調(diào)整OSCI管腳的微調(diào)電容式振蕩器的頻率來獲得更高的精度,此時可測出通電時管腳CLKOUT上的信號頻率為32.768kHz。
方法3:OSCI輸出。直接測量管腳OSCI的輸出。
4 程序范例
以下的C語言源程序是用8051單片機(jī)的普通I/O口(如P0.0/P0.4)模擬實(shí)現(xiàn) PCF8563的I2C時鐘/日歷芯片的操作,有字節(jié)寫/讀兩種狀態(tài)。程序中從地址的讀地址為0A3H,寫地址為0A2H.所發(fā)送的數(shù)據(jù)字節(jié)為9個,發(fā)送的初始數(shù)據(jù)在rom_sed[9]中,rom_sed[9]定義了寄存器中當(dāng)前發(fā)送的值:控制/狀態(tài)寄存器1為0,控制/狀態(tài)寄存器2為0,秒寄存器為 0,分鐘寄存器55,小時寄存器為23,日寄存器為31,星期寄存器為6,月/世紀(jì)寄存器為0x12,年寄存器為0x99(即1999年12月31日23 點(diǎn)55分0秒),當(dāng)程序運(yùn)行一段時間(5分鐘)后,從地址寄存器 02H開始讀數(shù)據(jù),數(shù)據(jù)存放在rom_rec7中,發(fā)現(xiàn)變量rom_rec7變?yōu)?000年1月1日0點(diǎn)0分。若外轉(zhuǎn)帳電路有顯示,則時間可以顯示在面板上。
#include<d:.h>
#define byte unsigned char
sbit scl=0x81; //定義串行I/O口
sbit sda=0x80;
idata byte rom_sed[9];
idata byte rom_rec[7];
idata byte j,k;
bit flag,flag1;
void delay(void) //延時子程序
{data byte i;
for(i=0;i<6;i++);
}
void I_start(void) //發(fā)送I2C總線起始條件子程序
{sda=1;
;
scl=1;
delay();
sda=0;
delay();
scl=0;
;
}
void I_stop(void) //I2C總線停止條件子程序
{sda=0;
;
scl=1;
delay();
sda=1;
delay();
}
bit I_send(byte I_data) //字節(jié)數(shù)據(jù)傳送子程序
{data byte i;
for(i=0,i<8;i++)
{sda-(bit)(I_data&0x80);
I_data=I_data<<1;
;
scl=1;
delay();
scl=0;
}
;;
sda=1; ;; //ready for receiving ACK bit
scl=1; ;; //start receiving ack bit
flag=0;
if(sda= =0)flag=0;
else flag=1; //return(~I(xiàn)_clock());
scl=0;
return(flag);
}
byte I_receive(void) //字節(jié)數(shù)據(jù)接收子程序
{ data byte i;
byte I_data=0;
sda=1;
for(i=0;I<8;i++)
{ I_data*=2;
;
scl=0;
delay();
scl=1; ;;
if(sda= =1)I_data++;
;;
}
scl=0; ;;;
sda=0;
if(flag1= =0){;;scl=1;delay();scl=0;} //not last receic_byte ACK
else{sda=1; ;;scl=1;delay();scl=0;flag1=0;} //the last receive_byte ~ACK
return(I_data);
}
main() //主程序
{data byte i;
rom_sed[0]=0x00; rom_sed[1]=0x00;
rom_sed[2]=0x00; rom_sed[3]=0x55;
rom_sed[4]=0x23; rom_sed[5]=0x31;
rom_sed[6]=0x06; rom_sed[7]=0x92;
rom_sed[8]=0x99;
for(i=0;i<255;i++)delay();
I_start();
if(~I(xiàn)_send(rom_sed[i]));
else;
}
I_stop();
}
else;
}
else;
start: I_start();
if(~I(xiàn)_send(0xa2)) //pcf_write address
{if(~I(xiàn)_send(0x02)) //pcf_status register address
{I_start();
if(~I(xiàn)_send(0xa3)) //write status register
{for(i=0;i<7;i++)
{if(i= =6)flag1=1;
else flag1=0;
rom_rec[i]=I_receive();
switch(i)
{case 1:rom_rec[i]=rom_rec[i]&0x7f;break;
ease2:
case3:rom_rec[i]=rom_rec[i]&0x3f;break;
case4:rom_rec[i]=rom_rec[i]&0x07;break;
case5:rom_rec[i]=rom_rec[i]&0x9f;brealk;default:break;
}
}
I_stop()
}
}
}
goto start;
}
二、DS12C887
簡要介紹了美國 DALLAS 公司的新型時鐘日歷芯片 DS12C887 的功能特性
和內(nèi)部控制寄存器參數(shù),給出了 DS12C887 與 8031 單片機(jī)的電路連接圖,同時給
出了用 C51 編寫的初始化程序和獲取內(nèi)部時間的程序。
1 器件特性
DS12C887 實(shí)時時鐘芯片功能豐富,可
以用來直接代替 IBM PC 上的時鐘日歷芯片
DS12887,同時,它的管腳也和
MC146818B、DS12887 相兼容。
由于 DS12C887 能夠自動產(chǎn)生世紀(jì)、
年、月、日、時、分、秒等時間信息,其內(nèi)
部又增加了世紀(jì)寄存器,從而利用硬件電路
解決子“千年”問題;DS12C887 中自帶有鋰電
池,外部掉電時,其內(nèi)部時間信息還能夠保
持 10 年之久;對于一天內(nèi)的時間記錄,有
12 小時制和 24 小時制兩種模式。在 12 小時
制模式中,用 AM 和 PM 區(qū)分上午和下午;
時間的表示方法也有兩種,一種用二進(jìn)制數(shù)
表示,一種是用 BCD 碼表示;DS12C887 中
帶有 128 字節(jié) RAM,其中有 11 字節(jié) RAM
用來存儲時間信息,4 字節(jié) RAM 用來存儲
DS12C887 的控制信息,稱為控制寄存器,
113 字節(jié)通用 RAM 使用戶使用;此外用戶還
可對 DS12C887 進(jìn)行編程以實(shí)現(xiàn)多種方波輸
出,并可對其內(nèi)部的三路中斷通過軟件進(jìn)行
屏蔽。
2 引腳功能
DS12C887 的引腳排列如圖 1 所示,各管腳的功能說明如下:
GND、VCC:直流電源,其中 VCC 接+5V 輸入,GND 接地,當(dāng) VCC 輸入為+5V 時,用
戶可以訪問 DS12C887 內(nèi) RAM 中的數(shù)據(jù),并可對其進(jìn)行讀、寫操作;當(dāng) VCC 的輸入小于
+4.25V 時,禁止用戶對內(nèi)部 RAM 進(jìn)行讀、寫操作,此時用戶不能正確獲取芯片內(nèi)的時間信
息;當(dāng) VCC 的輸入小于+3V 時,DS12C887 會自動將電源發(fā)換到內(nèi)部自帶的鋰電池上,以保證
內(nèi)部的電路能夠正常工作。
MOT:模式選擇腳,DA12C887 有兩種工作模式,即 Motorola 模式和 Intel 模式,當(dāng) MOT
接 VCC 時,選用的工作模式是 Motorola 模式,當(dāng) MOT 接 GND 時,選用的是 Intel 模式。本
文主要討論 Intel 模式。
SQW:方波輸出腳,當(dāng)供電電壓 VCC 大于 4.25V 時,SQW 腳可進(jìn)行方波輸出,此時用
戶可以通過對控制寄存器編程來得到 13 種方波信號的輸出。
AD0~AD7:復(fù)用地址數(shù)據(jù)總線,該總線采用時分復(fù)用技術(shù),在總線周期的前半部分,出
現(xiàn)在 AD0~AD7 上的是地址信息,可用以選通 DS12C887 內(nèi)的 RAM,總線周期的后半部分出
現(xiàn)在 AD0~AD7 上的數(shù)據(jù)信息。
AS:地址選通輸入腳,在進(jìn)行讀寫操作時,AS 的上升沿將 AD0~AD7 上出現(xiàn)的地址信
息鎖存到 DS12C887 上,而下一個下降沿清除 AD0~AD7 上的地址信息,不論是否有效,
DS12C887 都將執(zhí)行該操作。
DS/RD:數(shù)據(jù)選擇或讀輸入腳,該引腳有兩種工作模式,當(dāng) MOT 接 VCC 時,選用
Motorola 工作模式,在這種工作模式中,每個總線周期的后一部分的 DS 為高電平,被稱為數(shù)
據(jù)選通。在讀操作中,DS 的上升沿使 DS12C887 將內(nèi)部數(shù)據(jù)送往總線 AD0~AD7 上,以供外
部讀取。在寫操作中,DS 的下降沿將使總線 AD0~AD7 上的數(shù)據(jù)鎖存在 DS12C887 中;當(dāng)
MOT 接 GND 時,選用 Intel 工作模式,在該模式中,該引腳是讀允許輸入腳,即 Read
Enable。
R/W:讀/寫輸入端,該管腳也有 2 種工作模式,當(dāng) MOT 接 VCC 時,R/W 工作在
Motorola 模式。此時,該引腳的作用是區(qū)分進(jìn)行的是讀操作還是寫操作,當(dāng) R/W 為高電平時
為讀操作,R/W 為低電平時為寫操作;當(dāng) MOT 接 GND 時,該腳工作在 Intle 模式,此時該作
為寫允許輸入,即 Write Enable。
CS:片選輸入,低電平有效。
IRQ:中斷請求輸入,低電平有效,該腳有效對 DS12C887 內(nèi)的時鐘、日歷和 RAM 中的
內(nèi)容沒有任何影響,僅對內(nèi)部的控制寄存器有影響,在典型的應(yīng)用中,RESET 可以直接接
VCC,這樣可以保證 DS12C887 在掉電時,其內(nèi)部控制寄存器不受影響。
在 DS12C887 內(nèi)有 11 字節(jié) RAM 用來存儲時間信息,4 字節(jié)用來存儲控制信息,其具體垢
地址及取值如表 1 所列。
由表 1 可以看出:DS12C887 內(nèi)部有控制寄存器的 A-B 等 4 個控制寄存器,用戶都可以在
任何時候?qū)ζ溥M(jìn)行訪問以對 DS12C887 進(jìn)行控制操作。
表 1 DS12C887 的存儲功能
取值范圍
地 址 功 能 取值范圍十進(jìn)制數(shù)
二進(jìn)制 BCD 碼
秒
0 0~59 00~3B 00~59
秒鬧鈴
1 0~59 00~3B 00~59
分
2 059 00~3B 00~59
分鬧鈴
3 0~59 00~3B 00~59
01~0C AM, 01~12AM,
12 小時模式 0~12
81~8C PM 81~92PM
4
24 小時模式 0~23 00~17 00~23
01~0C AM, 01~12AM,
時鬧鈴,12 小時制 1~12
81~8C PM 81~92PM
5
時鬧鈴,24 小時制 0~23 00~17 00~23
星期幾(星期天=1)
6 1~7 01~07 01~07
日
7 1~31 01~1F 01~31
月
8 1~12 01~0C 01~12
年
9 0~99 00~63 00~99
控制寄存器 A
10
控制寄存器 B
11
控制寄存器 C
12
控制寄存器 D
13
世紀(jì)
50 NA
0~99 19,20
3 應(yīng)用
在各種設(shè)備、家電、儀器、工業(yè)控制系統(tǒng)中,可以很容易地用 DS12C887 來組成時間獲取
單元,以實(shí)現(xiàn)各種時間的獲取。圖 2 是用 8031 單片機(jī)和 DS12C887 構(gòu)成的時間獲取電路圖,
其中 DS12C887 的基地址為 7F00H,相應(yīng)的程序采用 C51 語言編寫(以 Intel 工作模式為
例)。
由 8031 單片機(jī)和 DS12C887 構(gòu)
成的時間獲取電路的初始化程序如
下:
XBYTE[0x7F00+0x0B]=0x82;
XBYTE[0x7F00+0x0A]=0xA0;
XBYTE[0x7F00+0x0A]=0x20;
XBYTE[0x7F00+0x0B]=0x02;
/*所有的中斷禁止,24 小時制,
BCD 碼模式*/
以下均獲取時間程序:
unsigned char data t-century;
unsigned char data t-year;
unsigned char data t-month;
unsigned char data t-date;
unsigned char data t-week;
unsigned char data t-hour;
unsigned char data t-minute;
unsigned char data t-second;
if((XBYTE[7F00+0x0A]&0x80)!=0){
t-century=XBYTE[0x7F00+0x32];/*讀取世紀(jì)*/
t-year=XBYTE[Ox7F00+0x09];/*讀取年份*/
t-month=XBYTE[Ox7F00+0x08];/*讀取月份*/
t-date=XBYTE[Ox7F00+0x07];/*讀取日期*/
t-week=XBYTE[Ox7F00+0x06];/*讀取星期幾*/
t-hour=XBYTE[Ox7F00+0x04];/*讀取小時*/
t-minute=XBYTE[DS12887+0x02];/*讀取分鐘*/
t-second=XBYTE[Ox7F00+0x00];}/*讀取秒*/
三、linux下的驅(qū)動
module_init(pcf8563_init);
354 static int __init pcf8563_init(void)
355 {
356 return i2c_add_driver(&pcf8563_driver);
357 }
265 static struct i2c_driver pcf8563_driver = {
266 .driver = {
267 .name = "pcf8563",
268 },
269 .id = I2C_DRIVERID_PCF8563,
270 .attach_adapter = &pcf8563_attach,
271 .detach_client = &pcf8563_detach,
272 };
260 static int pcf8563_attach(struct i2c_adapter *adapter)
261 {
262 return i2c_probe(adapter, &addr_data, pcf8563_probe);
263 }
245 static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
246 {
247 return pcf8563_get_datetime(to_i2c_client(dev), tm);
248 }
249
250 static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
251 {
252 return pcf8563_set_datetime(to_i2c_client(dev), tm);
253 }
254
255 static const struct rtc_class_ops pcf8563_rtc_ops = {
256 .read_time = pcf8563_rtc_read_time,
257 .set_time = pcf8563_rtc_set_time,
258 };
259
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
