|
#include "config.h"
#include "p33FJ256MC710.h"
/* r8025N寄存器定義 */
#define RX8025_REG_SEC 0x00
#define RX8025_REG_MIN 0x01
#define RX8025_REG_HOUR 0x02
#define RX8025_REG_WDAY 0x03
#define RX8025_REG_MDAY 0x04
#define RX8025_REG_MONTH 0x05
#define RX8025_REG_YEAR 0x06
#define RX8025_REG_RAM 0x07//#define RX8025_REG_DIGOFF 0x07 8025
#define RX8025_REG_ALWMIN 0x08
#define RX8025_REG_ALWHOUR 0x09
#define RX8025_REG_ALWWDAY 0x0a
#define RX8025_REG_TMCNT0 0x0b//#define RX8025_REG_ALDMIN 0x0b
#define RX8025_REG_TMCNT1 0x0c//#define RX8025_REG_ALDHOUR 0x0c
/* 0x0d is reserved */
#define RX8025_REG_FLAG 0x0e//#define RX8025_REG_CTRL1 0x0e
#define RX8025_REG_CTRL 0x0f//#define RX8025_REG_CTRL2 0x0f
#define RX8025_BIT_FLAG_VDET (1<<0)//用于檢測(cè)溫度補(bǔ)償?shù)臓顟B(tài)
#define RX8025_BIT_FLAG_VLF (1<<1)//用于檢測(cè)電壓低的狀態(tài)
typedef struct strtime{
BYTE cSecond;
BYTE cMinute;
BYTE cHour;
BYTE cMonth;
BYTE cWeek;
BYTE cDay;
UINT16 sYear;
}strTIME;
BYTE rx8025_get_time(strTIME *get_time);
/* I2C定義 */
INT Time_Adjust(strTIME *dt);
BYTE is_leap_year(UINT16 year);
UINT16 bcd2bin(BYTE val);
BYTE bin2bcd(unsigned val);
VOID IdleI2C(VOID);
VOID StartI2C(VOID);
BYTE WriteI2C(BYTE byte);
VOID StopI2C(VOID);
VOID RestartI2C(VOID);
BYTE getsI2C(BYTE*, BYTE);
VOID NotAckI2C(VOID);
VOID InitI2C(VOID);
UINT16 ACKStatus(VOID);
BYTE getI2C(VOID);
VOID AckI2C(VOID);
UINT16 EEAckPolling(BYTE);
UINT16 putstringI2C(BYTE *wrptr,BYTE Write_Data_Length);
UINT32 TimeToMinute(strTIME *Time_Set);
UINT32 TimeToSecond(strTIME *Time_Set);
VOID MinuteToTime(UINT32 Minute,strTIME *T);
VOID SecondToTime(UINT32 SecondT,strTIME *T);
void TimeDir(strTIME *T);
/***********************************************************************
** Time: liwenjin 2012.10
** Function:讀取rx8025n內(nèi)部寄存器
** Input:
** Output:
** Attention
***********************************************************************/
UINT16 rx8025_read_regs(BYTE Add, BYTE ReadDatatLength,BYTE *Data)
{
BYTE ErrorCode;
// Add=Add<<4;//地址(高4位)加傳送模式00(低四位)
IdleI2C(); //Wait for bus Idle
StartI2C(); //Generate Start condition
WriteI2C(0x64); //發(fā)送寫(xiě)控制命令,0x64
IdleI2C(); //Wait for bus Idle
ErrorCode = ACKStatus(); //Return ACK Status
WriteI2C(Add); //Send High Address
IdleI2C(); //Wait for bus Idle
ErrorCode = ACKStatus(); //Return ACK Status
RestartI2C(); //Generate Restart
WriteI2C(0x65); //發(fā)送讀控制命令
IdleI2C(); //Wait for bus Idle
ErrorCode = ACKStatus(); //Return ACK Status
getsI2C(Data,ReadDatatLength); //Read Length number of bytes to Data
NotAckI2C(); //send Not Ack
StopI2C(); //Send Stop Condition
return(ErrorCode);
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function:寫(xiě)rx8025n內(nèi)部寄存器
** Input: ControlByte, Add, *wrptr.
** Output: None
** Attention:先發(fā)命令地址,再發(fā)地址,最后發(fā)數(shù)據(jù)
***********************************************************************/
INT rx8025_write_regs(BYTE Add,BYTE WriteDataLength,BYTE *wrptr)
{
BYTE ErrorCode;
// Add=Add<<4;//地址(高4位)加傳送模式00(低四位)
IdleI2C(); //wait for bus Idle
StartI2C(); //Generate Start condition
WriteI2C(0x64); //send controlbyte for a write,0x64h
IdleI2C(); //wait for bus Idle
ErrorCode = ACKStatus(); //Return ACK Status
WriteI2C(Add); //send low address
IdleI2C(); //wait for bus Idle
ErrorCode = ACKStatus(); //Return ACK Status
putstringI2C(wrptr,WriteDataLength); //send data
IdleI2C(); //wait for bus Idle
StopI2C(); //Generate Stop
return(ErrorCode);
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function:從8025N獲取時(shí)間
** Input:
** Output: None
** Attention:
***********************************************************************/
BYTE rx8025_get_time(strTIME *get_time)
{
BYTE date[7];
BYTE err;
err = rx8025_read_regs(RX8025_REG_SEC,7,date);
if (!err)return err; //err為0時(shí)表示錯(cuò)誤,err=1表示正常接收
get_time->cSecond =(BYTE)bcd2bin(date[RX8025_REG_SEC]&0x7f);
get_time->cMinute =(BYTE)bcd2bin(date[RX8025_REG_MIN]&0x7f);
get_time->cHour = bcd2bin(date[RX8025_REG_HOUR] & 0x3f);
get_time->cDay = bcd2bin(date[RX8025_REG_MDAY] & 0x3f);
get_time->cMonth= bcd2bin(date[RX8025_REG_MONTH] & 0x1f);
get_time->sYear= bcd2bin(date[RX8025_REG_YEAR]);
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function:校正8025N的時(shí)間
** Input:
** Output: None
** Attention:
***********************************************************************/
INT Time_Adjust(strTIME *dt)
{
BYTE date[7];
//該8025假定能被4整除是閏年,但2100年不是閏年(BUG)
date[RX8025_REG_SEC] = bin2bcd(dt->cSecond);
date[RX8025_REG_MIN] = bin2bcd(dt->cMinute);
date[RX8025_REG_HOUR] = bin2bcd(dt->cHour);
// date[RX8025_REG_WDAY] = bin2bcd(dt->cWeek);
date[RX8025_REG_MDAY] = bin2bcd(dt->cDay);
date[RX8025_REG_MONTH] = bin2bcd(dt->cMonth);
date[RX8025_REG_YEAR] = bin2bcd(dt->sYear% 100);
return rx8025_write_regs(RX8025_REG_SEC,7,date);
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function:BCD轉(zhuǎn)BIN
** Input:
** Output: None
** Attention:
***********************************************************************/
UINT16 bcd2bin(BYTE val)
{
return ((val&0x0f)+(val >> 4)*10);
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function:BIN轉(zhuǎn)BCD
** Input:
** Output: None
** Attention:
***********************************************************************/
BYTE bin2bcd(unsigned val)
{
return ((val / 10) << 4) + val % 10;
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function:判斷是否為閏年
** Input:
** Output: None
** Attention:
***********************************************************************/
BYTE is_leap_year(UINT16 year)
{
return (!(year % 4) && (year % 100)) || !(year % 400);
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function:初始化I2C(1)外設(shè)
** Input:
** Output: None
** Attention:Sets up Master mode, No slew rate control, 100Khz
***********************************************************************/
VOID InitI2C(VOID)
{
/*I2C2BRG=[(1/Fscl-PGD)*FCY]-2,當(dāng)Fsc1=100khz時(shí),1/fsc1=(1/100)*1000000=10000ns,PGD=130ns,即10000-130=9870
I2C2BRG=(9870*5.5296)/1000-2=52.5;*/
I2C2BRG = 0x0034;
//初始化IIC外設(shè),設(shè)為主模式, No Slew Rate
I2C2CONbits.I2CEN=0;// 禁止I2Cx 模塊
I2C2CONbits.DISSLW=1;//禁止斜率控制位
I2C2CONbits.SCLREL=1;//釋放SCLx時(shí)鐘
I2C2RCV = 0x0000;
I2C2TRN = 0x0000;
I2C2CONbits.I2CEN=1;// 使能 I2Cx 模塊,并將 SDAx 和 SCLx 引腳配置為串口引腳
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function:StartI2C()
** Input:
** Output: None
** Attention: Generates an I2C Start Condition
***********************************************************************/
VOID StartI2C(VOID)
{
//This function generates an I2C start condition and returns status
//of the Start.
I2C2CONbits.SEN = 1; //Generate Start COndition
while (I2C2CONbits.SEN); //Wait for Start COndition
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function: RestartI2C()
** Input:
** Output: None
** Attention:Generates a restart condition and optionally returns status
***********************************************************************/
VOID RestartI2C(VOID)
{
I2C2CONbits.RSEN = 1; //Generate Restart
while (I2C2CONbits.RSEN); //Wait for restart
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function: StopI2C()
** Input:
** Output: None
** Attention:Generates a bus stop condition
***********************************************************************/
VOID StopI2C(VOID)
{
I2C2CONbits.PEN = 1; //Generate Stop Condition
while (I2C2CONbits.PEN); //Wait for Stop
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function: WriteI2C()
** Input:
** Output: None
** Attention:rites a byte out to the bus
***********************************************************************/
BYTE WriteI2C(BYTE byte)
{
//This function transmits the byte passed to the function
while (I2C2STATbits.TRSTAT); //Wait for bus to be idle
I2C2TRN = byte; //Load byte to I2C2 Transmit buffer
if(I2C2STATbits.IWCOL) /* If write collision occurs,return -1 */
return 1;
else
{
while (I2C2STATbits.TBF); //wait for data transmission
}
return 0;
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function: IdleI2C()
** Input:
** Output: None
** Attention:Waits for bus to become Idle
***********************************************************************/
VOID IdleI2C(VOID)
{
while (I2C2STATbits.TRSTAT); //Wait for bus Idle
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function: ACKStatus()
** Input:
** Output: Acknowledge Status.
** Attention:Return the Acknowledge status on the bus
***********************************************************************/
UINT16 ACKStatus(VOID)
{
return (!I2C2STATbits.ACKSTAT); //Return Ack Status
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function: NotAckI2C()
** Input: None.
** Output: None.
** Attention:Generates a NO Acknowledge on the Bus
***********************************************************************/
VOID NotAckI2C(VOID)
{
I2C2CONbits.ACKDT = 1; //Set for NotACk
I2C2CONbits.ACKEN = 1;
while(I2C2CONbits.ACKEN); //wait for ACK to complete
I2C2CONbits.ACKDT = 0; //Set for NotACk
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function: AckI2C()
** Input: None.
** Output: None.
** Attention:Generates an Acknowledge.
***********************************************************************/
VOID AckI2C(VOID)
{
I2C2CONbits.ACKDT = 0; //Set for ACk
I2C2CONbits.ACKEN = 1;
while(I2C2CONbits.ACKEN); //wait for ACK to complete
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function: getsI2C()
** Input: array poINTer, Length.
** Output: None.
** Attention:read Length number of Bytes INTo array
***********************************************************************/
BYTE getsI2C(BYTE *rdptr, BYTE Length)
{
while (Length --)
{
*rdptr++ = getI2C(); //get a single byte
if(I2C2STATbits.BCL) //Test for Bus collision
{
return(-1);
}
if(Length)
{
AckI2C(); //Acknowledge until all read
}
}
return(0);
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function: getI2C()
** Input: None.
** Output: contents of I2C2 receive buffer.
** Attention:Read a single byte from Bus
***********************************************************************/
BYTE getI2C(VOID)
{
I2C2CONbits.RCEN = 1; //Enable Master receive
Nop();
while(!I2C2STATbits.RBF); //Wait for receive bufer to be full
return(I2C2RCV); //Return data in buffer
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function: putstringI2C()
** Input: poINTer to array
** Output: None.
** Attention:writes a string of data upto PAGESIZE from array
***********************************************************************/
UINT16 putstringI2C(BYTE *wrptr,BYTE Write_Data_Length)
{
BYTE i;
for(i= 0; i <Write_Data_Length; i++) //Transmit Data Until Pagesize
{
if(WriteI2C(*wrptr)) //Write 1 byte
{
return(-3); //Return with Write Collision
}
IdleI2C(); //Wait for Idle bus
if(I2C2STATbits.ACKSTAT)
{
return(-2); //Bus responded with Not ACK
}
wrptr++;
}
return(0);
}
//定義閏年及非閏年中每個(gè)月的天數(shù)
BYTE MonthDayNum[2][12]={{31,29,31,30,31,30,31,31,30,31,30,31},{31,28,31,30,31,30,31,31,30,31,30,31}};
/***********************************************************************
** Time: liwenjin 2012.10
** Function: 把時(shí)間轉(zhuǎn)換為分鐘(從2000年開(kāi)始的時(shí)間)
** Input:
** Output:
** Attention
***********************************************************************/
UINT32 TimeToMinute(strTIME *Time_Set)
{
BYTE c;
UINT32 TimeMinute,i;
Time_Set->sYear &= 0xFF;
TimeMinute=(UINT32)525600*(UINT32)Time_Set->sYear; //年//525600=(60*24*365)
c=((Time_Set->sYear-1)>>2)+1;
TimeMinute+=(UINT32)1440*(UINT32)c;//1440=60*24
if(Time_Set->sYear&0x03) c=1; //閏年判斷
else c=0;
if (Time_Set->cMonth==0) return 0;
for (i=0;i<(Time_Set->cMonth-1);i++) { //月
TimeMinute+=(UINT32)1440*(UINT32)MonthDayNum[c][i];////1440=60*24
}
if (Time_Set->cDay==0) return 0;
TimeMinute+=((UINT32)1440*(UINT32)(Time_Set->cDay-1) ); //日
TimeMinute+=((UINT32)60*(UINT32)Time_Set->cHour); //小時(shí)
TimeMinute+=(UINT32)(Time_Set->cMinute); //分
return TimeMinute;
}
/***********************************************************************
** Time: liwenjin 2012.10
** Function: 把時(shí)間轉(zhuǎn)換為秒(從2000年開(kāi)始的時(shí)間)
** Input:
** Output:
** Attention
***********************************************************************/
UINT32 TimeToSecond(strTIME *Time_Set)
{
UINT32 TimeSecond;
TimeSecond = TimeToMinute(Time_Set)*60;
TimeSecond += Time_Set->cSecond; //秒
return TimeSecond;
}
/***********************************************************************
** Time:
** Function: 分鐘值轉(zhuǎn)換為年月日時(shí)分秒
** Input:
** Output:
** Attention
***********************************************************************/
VOID MinuteToTime(UINT32 Minute,strTIME *T)
{
INT iTemp1,iTemp2,i,HourT;
T->cSecond=0;
HourT=Minute/60;
T->cMinute=Minute%60;
iTemp1=HourT/(365*24);
iTemp2=HourT%(365*24);
T->sYear=iTemp1;
iTemp2-=((iTemp1>>2)+1)*24;
if(iTemp1&0x03) iTemp1=1; //閏年判斷
else iTemp1=0;
for ( i=0;i<12;i++ ) {
if (iTemp2<MonthDayNum[iTemp1][i]*24) break;
iTemp2-=MonthDayNum[iTemp1][i]*24;
}
T->cMonth=i+1;
T->cDay=iTemp2/24;
T->cHour=iTemp2%24;
T->cDay++;
}
/***********************************************************************
** Time:
** Function:
** Input:
** Output:
** Attention
***********************************************************************/
VOID SecondToTime(UINT32 SecondT,strTIME *T)
{
UINT32 iTemp1,iTemp2,i,sTemp,HourT;
HourT=SecondT/3600;
sTemp=SecondT%3600;
T->cMinute=sTemp/60;
T->cSecond=sTemp%60;
for ( iTemp1=0;iTemp1<100;iTemp1++ ) {
if(iTemp1&0x03) iTemp2 = 365*24;
else iTemp2 = 366*24;
if (HourT>=iTemp2) {
HourT -= iTemp2;
}
else {
break;
}
}
T->sYear=iTemp1;
if(iTemp1&0x03) iTemp1=1; //閏年判斷
else iTemp1=0;
for ( i=0;i<12;i++ ) {
if (HourT < MonthDayNum[iTemp1][i]*24) break;
HourT -= MonthDayNum[iTemp1][i]*24;
}
T->cMonth = i+1;
T->cDay = HourT/24;
T->cHour = HourT%24;
T->cDay++;
iTemp2=SecondT%(7*24*3600);
if (iTemp2>=1) T->cWeek=iTemp2-1;
else T->cWeek=6;
}
void TimeDir(strTIME *T)
{
BYTE buf[64];
UINT16 len;
len = sprintf((char *)buf,"%d年%d月%d日 %d:%d:%d\r\n",T->sYear,T->cMonth,T->cDay,T->cHour,T->cMinute,T->cSecond);
sioapi_puts(P30f6012SER2,(BYTE*)buf,(UINT)len);
}
|
|