?? rtc.c
字號(hào):
//-------------------------------------------------------------------
// rtc.c
// 功能:實(shí)現(xiàn)對(duì)PCF8563的讀取,用于C8051F020中,使用C8051F020的SMBus功能
// 使用查詢方式讀取和寫入數(shù)據(jù)
// 說明:本例程中對(duì)SMBus的操作使用的是查詢的方式進(jìn)行的,還可以采用中斷的方式
// 可以參考其它相關(guān)的例程
// 版本: Rev1.0
//
//------------------------------------------------------------------
// 修改記錄
// 版本 時(shí)間 人員 內(nèi)容
// 1.0 07/05/03 scj 移植程序
//
//
//------------------------------------------------------------------
#include "rtc.h"
#include "F020.h"
BYTE code MYHTAB[]="0123456789ABCDEF";
//..................................................................
// 全局變量定義
//..................................................................
xdata BYTE CurrentTime[8]; // 實(shí)時(shí)時(shí)鐘時(shí)間
xdata char CurrentTimeString[17]; // 當(dāng)前時(shí)間的字符串形式
extern void Dlyms(WORD ms);
//----------------------------------------------------------------------
// 功能描述:從某一地址連續(xù)讀n個(gè)字節(jié)
// 其中:n 的低4位(B3B2B1B0)為長度(0表示16)
// 過程:寫器件地址,讀寄存器內(nèi)容
//----------------------------------------------------------------------
void I2RD(BYTE addr,BYTE *pBuf,BYTE n) // 從某一地址連續(xù)讀n個(gè)字節(jié)
{
BYTE i; // 循環(huán)變量
BYTE slave; // 器件和頁地址
BYTE datu;
// 計(jì)算地址
// 計(jì)算長度
n&=0x0F; // n=長度
if(n==0) n=16; // n=0 表示16字節(jié)
/////////////////////////////////////////////////////////////////////
// 首先寫寄存器地址
slave=DEVICE_WADD; // 求器件地址(0110 c2c1c0 1)
SI=0;
STO=0;
STA=1; // 發(fā)送起始條件
while(!SI) {} // 等待起始條件發(fā)送
datu=SMB0STA;
STA=0; // 清零起始條件
SMB0DAT=slave; // 發(fā)送器件地址
SI=0;
while(!SI) {} // 等待器件地址發(fā)送完畢
datu=SMB0STA;
SMB0DAT=addr; // 發(fā)送寄存器地址
SI=0;
while(!SI) {} // 等待寄存器地址發(fā)送完畢
datu=SMB0STA;
//////////////////////////////////////////////////////////////////////
// 發(fā)送讀命令
slave = DEVICE_RADD;
STO=0;
STA=1; // 發(fā)送起始條件
SI=0;
while(!SI) {} // 等待起始條件發(fā)送
datu=SMB0STA;
STA=0; // 清零起始條件
SMB0DAT=slave; // 發(fā)送器件地址
SI=0;
while(!SI) {} // 等待器件地址發(fā)送完畢
datu=SMB0STA;
////////////////////////////////////////////////////////////////////
// 讀數(shù)據(jù)
for(i=0;i<n-1;i++){
AA=1; // 收到字節(jié)后發(fā)送ACK
SI=0;
while(!SI) {}
datu=SMB0STA;
datu=SMB0DAT;
pBuf[i]=datu;
}
AA=0; // 最后一個(gè)字節(jié),發(fā)送NACK
SI=0;
while(!SI) {}
datu=SMB0STA;
datu=SMB0DAT;
pBuf[i]=datu; // 讀出最后一個(gè)字節(jié)
///////////////////////////////////////////////////////////////////
// 發(fā)送停止
SI=0;
STO=1; // 置位停止條件
while(!SI) {}
SI=0;
return; // 返回
}
//----------------------------------------------------------------------
// 功能:向某一個(gè)地址寫入數(shù)據(jù)
// 其中:n表示長度
//----------------------------------------------------------------------
void I2WR(BYTE addr,BYTE *pBuf,BYTE n) // 向某一地址連續(xù)寫n個(gè)字節(jié)
{ //
BYTE i; // 循環(huán)變量
BYTE slave; // SLAVE地址
BYTE datu;
slave=DEVICE_WADD; // 求器件地址(0110 c2c1c0 0)
n&=0x0F; // n=長度
if(n==0) n=16; // n=0 表示16字節(jié)
SI=0;
STO=0;
STA=1; // 發(fā)送起始條件
while(!SI) {} // 等待發(fā)送條件結(jié)束
datu=SMB0STA; // 數(shù)據(jù)狀態(tài)
STA=0; // 發(fā)送條件結(jié)束
SMB0DAT=slave; // 發(fā)送器件地址
SI=0; // 恢復(fù)為高電平SCL
while(!SI) {} // 等待發(fā)送完畢
datu=SMB0STA; // 數(shù)據(jù)狀態(tài)
SMB0DAT=slave; // 發(fā)送寄存器地址
SI=0; // 恢復(fù)為高電平SCL
for(i=0;i<n;i++){ // 開始讀取數(shù)據(jù)
while(!SI) {} // 等待發(fā)送完畢
datu=SMB0STA; // 數(shù)據(jù)狀態(tài)
datu=pBuf[i];
SMB0DAT=datu; // 發(fā)送數(shù)據(jù)字節(jié)
SI=0;
}
while(!SI) {} // 最后一個(gè)字節(jié)發(fā)送完畢
STO=1; // 結(jié)束條件
SI=0;
// while(!SI) {}
datu=SMB0STA;
// SI=0;
Dlyms(10); // 延時(shí)
return; // 返回
}
//.................................................................
// 功能: 從PCF8563T中讀取當(dāng)前時(shí)間,并返回時(shí)間字符串的指針
// 輸入?yún)?shù):無
// 輸出參數(shù): char *:指向時(shí)間字符串存儲(chǔ)指針,外部函數(shù)不允許修改該緩沖區(qū)內(nèi)容
//.................................................................
const char *GetNowTime()
{
// 從PCF8563中讀出當(dāng)前時(shí)間
I2RD(REG_SECD,CurrentTime,8);
CurrentTimeString[0]=MYHTAB[(CurrentTime[RTC_HOUR]>>4)&0x03];
CurrentTimeString[1]=MYHTAB[CurrentTime[RTC_HOUR]&0x0F];
CurrentTimeString[2]=':';
CurrentTimeString[3]=MYHTAB[(CurrentTime[RTC_MINU]>>4)&0x07];
CurrentTimeString[4]=MYHTAB[CurrentTime[RTC_MINU]&0x0F];
CurrentTimeString[5]=0x20;
// 年
CurrentTimeString[6]=(CurrentTime[RTC_MON]&0x80)?MYHTAB[1]:MYHTAB[2];
CurrentTimeString[7]=(CurrentTime[RTC_MON]&0x80)?MYHTAB[9]:MYHTAB[0];
CurrentTimeString[8]=MYHTAB[(CurrentTime[RTC_YEAR]>>4)&0x0F];
CurrentTimeString[9]=MYHTAB[CurrentTime[RTC_YEAR]&0x0F];
// 月
CurrentTimeString[10]='/';
CurrentTimeString[11]=MYHTAB[(CurrentTime[RTC_MON]>>4)&0x01];
CurrentTimeString[12]=MYHTAB[CurrentTime[RTC_MON]&0x0F];
// 日
CurrentTimeString[13]='/';
CurrentTimeString[14]=MYHTAB[(CurrentTime[RTC_DAY]>>4)&0x03];
CurrentTimeString[15]=MYHTAB[CurrentTime[RTC_DAY]&0x0F];
CurrentTimeString[16]=0;
return &CurrentTimeString[0];
}
// 設(shè)置當(dāng)前時(shí)間
// 年/月/日/周/小時(shí)/分/秒
void SetNowTime(BYTE y2k,BYTE year,BYTE month,BYTE day,BYTE hour,BYTE min,BYTE sec)
{
BYTE datu;
CurrentTime[RTC_DW] = 0x00;
CurrentTime[RTC_YEAR] = year;
CurrentTime[RTC_MON] = (y2k==0x19)?month|0x80:month&0x7F;
CurrentTime[RTC_DAY] = day;
CurrentTime[RTC_HOUR] = hour|0x80;
CurrentTime[RTC_MINU] = min;
CurrentTime[RTC_SECD] = (sec>0x59)?0x59:sec;
// 設(shè)置當(dāng)前時(shí)間
I2WR(REG_SECD,CurrentTime,7);
}
/*
// 設(shè)置當(dāng)前秒
void SetCurrentSec(BYTE sec)
{
CurrentTime[RTC_SECD]= sec;
I2WR(REG_SC,&CurrentTime[RTC_SECD],1);
}
*/
// 檢測(cè)時(shí)鐘芯片是否從掉電狀態(tài)啟動(dòng)
bit IsFromFail()
{
BYTE datu;
I2RD(REG_SECD,&datu,1);
if(datu&0x80)
{// 發(fā)生調(diào)電事件,復(fù)位器件
datu = 0;
I2WR(REG_CONTRL1,&datu,0);
return 1;
}
else
{
return 0;
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -