📄 ds1302.c
字号:
DS1302(RST_1302,HIGH);
Cmd_Byte = WRITE_CMD; /* set command to the 1302 for
burst write operation */
shifter = 0x01;
//写 写 命令
for(i=0; i<8; i++) /* shift out the command */
{
if (shifter & Cmd_Byte)
DS1302(DAT_1302,HIGH);
else
DS1302(DAT_1302,LOW); /* set up the data port pin */
DS1302(CLK_1302,HIGH);
shifter = shifter << 1;
DS1302(CLK_1302,LOW); /* clock the chip */
} //next i
for(i=0; i<8; i++) /* output all 8 bytes to DS1302 */
{
shifter = 0x01;
databyte = TimeBuffer[i]; /* get byte from buffer */
for(j=0; j<8; j++) /* shift out data */
{
if (shifter & databyte)
DS1302(DAT_1302,HIGH);
else
DS1302(DAT_1302,LOW); /* set up the data port pin */
DS1302(CLK_1302,HIGH);
shifter = shifter << 1;
DS1302(CLK_1302,LOW); /* clock the chip */
} //next j
} //next i
Idle_1302(); /* set the port pins idle */
return;
} /* end Write_1302_Data() */
/*******************************************************************
Enable_1302
Write enables the Dallas Semi 1302 clock chip.
********************************************************************/
void Enable_1302(void)
{
unsigned char Cmd_Byte; /*clock command*/
unsigned char databyte; /*temp data byte*/
unsigned char shifter; /* bit selector */
unsigned int i,j;
DS1302(CLK_1302,LOW);
DS1302(DAT_1302,LOW);
DS1302(RST_1302,HIGH);
Cmd_Byte = 0x8e; /* set command to the 1302 for
write to write prot register */
shifter = 0x01;
//写0x8E表示写控制寄存器,后面必须跟着是0的一个字节
for(i=0; i<8; i++) /* shift out the command */
{
if (shifter & Cmd_Byte)
DS1302(DAT_1302,HIGH);
else
DS1302(DAT_1302,LOW);
DS1302(CLK_1302,HIGH);
shifter = shifter << 1;
DS1302(CLK_1302,LOW);
} //next i
shifter = 0x01;
databyte =0; /* we want to write enable the DS1302 chip */
//写8个零是DataSheet这样定的,WP位也写0表示去掉DS1302的写保护功能
for(j=0; j<8; j++) /* shift out the data */
{
if (shifter & databyte)
DS1302(DAT_1302,HIGH);
else
DS1302(DAT_1302,LOW);
DS1302(CLK_1302,HIGH);
shifter = shifter << 1;
DS1302(CLK_1302,LOW); /* clock the chip */
} //next j
//秒寄存器的第7位表示时钟停止标记,为1表示时钟停止
Idle_1302(); /* idle the port pins */
return;
} /* end Enable_1302() */
/*******************************************************************
Idle_1302
This routine will set the port pins that drive the clock to
their idle states.
********************************************************************/
void Idle_1302(void)
{
//刚好和Enable相反
DS1302(RST_1302,LOW);
DS1302(DAT_1302,HIGH);
DS1302(CLK_1302,HIGH);
return;
} /* end Idle_1302() */
/*******************************************************************
Lock_1302
This routine will LOCK the clock and stop its oscillator to
preserve Battery Life.
Uses TimeBuffer[] as temporary storage.
********************************************************************/
void Lock_1302 (void)
{
unsigned char TimeBuffer[8]; //temp storage
Read_1302_Data(&TimeBuffer[0]); //get the time
TimeBuffer[0] = TimeBuffer[0]|0x80; //halt the clock
Enable_1302(); //write enable the clock
Write_1302_Data(&TimeBuffer[0]); //write back the halted time
return;
} /* end proc Lock_1203() */
/*******************************************************************
Set_Time
This routine SETs the clock and start its oscillator, write-
protecting the clock registers.
Obtains time from TimeBuffer[].
//在WinCE架构中不用这个函数了
********************************************************************/
void Set_Time(unsigned char * TimeBuffer)
{
TimeBuffer[7] = '\x80'; //write protect the chip after write
Enable_1302(); //write enable the clock
Write_1302_Data(TimeBuffer); //write the clock and start it up
} /* end proc Set_Time() */
/*******************************************************************
Get_Time
This routine GETs the time from the Dallas 1302 clock.
The time is returned in TimeBuffer.
This function returns 0 when the clock is operating properly.
If the clock was locked (stopped) the default time is returned
as 1/1/99, 12:00Noon and the function returns non-zero.
//在WinCE架构中不用这个函数了
********************************************************************/
unsigned int Get_Time(unsigned char * TimeBuffer)
{
unsigned int clock_locked;
//get the time and put it in TimeBuffer[]
clock_locked = Read_1302_Data(TimeBuffer);
//store the time in system variable time....
//Note that since the values in the RTC and TimeBuffer are in
//BCD, we need to convert back to normal numbers!
return(clock_locked);
} /* end proc Get_Time() */
//本函数将替换RTC4513GetRealTime函数
void DS1302GetRealTime(LPSYSTEMTIME lpst)
{
unsigned char TimeBuffer[8]; //temp storage
unsigned char ucBCDLow, ucBCDHigh;
OALMSG(1, (TEXT("+DS1302GetRealTime: Enter!\r\n")));
Read_1302_Data(TimeBuffer);
lpst->wMilliseconds = 0;
ucBCDHigh = TimeBuffer[0] & 0x70;
ucBCDLow = TimeBuffer[0] & 0x0F;
ucBCDHigh >>= 4; //左移四位
lpst->wSecond = (ucBCDLow + ucBCDHigh * 10);
ucBCDHigh = TimeBuffer[1] & 0x70;
ucBCDLow = TimeBuffer[1] & 0x0F;
ucBCDHigh >>= 4; //左移四位
lpst->wMinute = (ucBCDLow + ucBCDHigh * 10);
ucBCDHigh = TimeBuffer[2] & 0x10; //暂时只支持24制??????
ucBCDLow = TimeBuffer[2] & 0x0F;
ucBCDHigh >>= 4; //左移四位
lpst->wHour = (ucBCDLow + ucBCDHigh * 10);
ucBCDHigh = TimeBuffer[3] & 0x30;
ucBCDLow = TimeBuffer[3] & 0x0F;
ucBCDHigh >>= 4; //左移四位
lpst->wDay = (ucBCDLow + ucBCDHigh * 10);
ucBCDHigh = TimeBuffer[4] & 0x10;
ucBCDLow = TimeBuffer[4] & 0x0F;
ucBCDHigh >>= 4; //左移四位
lpst->wMonth = (ucBCDLow + ucBCDHigh * 10);
lpst->wDayOfWeek = TimeBuffer[5]; //不会超过10的
ucBCDHigh = TimeBuffer[6] & 0xF0;
ucBCDLow = TimeBuffer[6] & 0x0F;
ucBCDHigh >>= 4; //左移四位
lpst->wYear = (ucBCDLow + ucBCDHigh * 10 + 2000);
RETAILMSG(1,(TEXT("RTC4513GetRealTime: Year: %u, Month: %u, Day: %u, Hour: %u, Minute: %u, second: %u \r\n"),
lpst->wYear, lpst->wMonth,lpst->wDay, lpst->wHour, lpst->wMinute,lpst->wSecond));
OALMSG(1, (TEXT("-DS1302GetRealTime: Leave!\r\n")));
}
//本函数将替换RTC4513SetRealTime函数
void DS1302SetRealTime(LPSYSTEMTIME lpst)
{
unsigned char TimeBuffer[8]; //temp storage
unsigned char ucBCDLow, ucBCDHigh;
OALMSG(1, (TEXT("+DS1302SetRealTime: Enter!\r\n")));
lpst->wYear = lpst->wYear % 100;
//lpst->wDay = lpst->wDay - 1; //用DS1302这里就不用减拉
//lpst->wMonth = lpst->wMonth - 1;
ucBCDHigh = lpst->wSecond / 10;
ucBCDLow = lpst->wSecond % 10;
ucBCDHigh <<= 4; //右移四位
TimeBuffer[0] = (ucBCDLow | ucBCDHigh);
ucBCDHigh = lpst->wMinute / 10;
ucBCDLow = lpst->wMinute % 10;
ucBCDHigh <<= 4; //右移四位
TimeBuffer[1] = (ucBCDLow | ucBCDHigh);
/*hours: msb=1,12 hour/0,24 hour, BCD hour
msb=0, 0-23 BCD
msb=1, {10}{0=am/1=pm}01-12 BCD // */
ucBCDHigh = lpst->wHour / 10;
ucBCDLow = lpst->wHour % 10;
ucBCDHigh <<= 4; //右移四位,最高为铁定为0,这样就成24小时制了
TimeBuffer[2] = (ucBCDLow | ucBCDHigh);
ucBCDHigh = lpst->wDay / 10;
ucBCDLow = lpst->wDay % 10;
ucBCDHigh <<= 4; //右移四位
TimeBuffer[3] = (ucBCDLow | ucBCDHigh);
ucBCDHigh = lpst->wMonth / 10;
ucBCDLow = lpst->wMonth % 10;
ucBCDHigh <<= 4; //右移四位
TimeBuffer[4] = (ucBCDLow | ucBCDHigh);
TimeBuffer[5] = (BYTE)lpst->wDayOfWeek; //不会超过10的
ucBCDHigh = lpst->wYear / 10;
ucBCDLow = lpst->wYear % 10;
ucBCDHigh <<= 4; //右移四位
TimeBuffer[6] = (ucBCDLow | ucBCDHigh);
TimeBuffer[7] = '\x80'; //write protect the chip after write
Enable_1302(); //write enable the clock
Write_1302_Data(TimeBuffer); //write the clock and start it up
RETAILMSG(1,(TEXT("RTC4513SetRealTime: Year: %u, Month: %u, Day: %u, Hour: %u, Minute: %u, second: %u \r\n"),
lpst->wYear, lpst->wMonth,lpst->wDay, lpst->wHour, lpst->wMinute,lpst->wSecond));
OALMSG(1, (TEXT("-DS1302SetRealTime: Leave!\r\n")));
}
//本函数应该在OEMInit中被调用
//本函数将替换RTC4513_Init函数
void DS1302_Init(void)
{
PHYSICAL_ADDRESS PhysicAddr;
XLLP_UINT32_T uiArrPin[2] = {1, 0};
OALMSG(1, (TEXT("DS1302_Init Enter!\r\n")));
//这里要初始化三个GPIO为双向的,方便以后使用,同时获取其地址
// PhysicAddr.LowPart = ;
// PhysicAddr.HighPart = 0;
g_pBaseAddressGPIORegs = (BULVERDE_GPIO_REG *) OALPAtoVA(BULVERDE_BASE_REG_PA_GPIO, FALSE);
if(NULL == g_pBaseAddressGPIORegs)
{
return ;
}
//设置几个管脚为GPIO用的
uiArrPin[1] = VAL_GPIO_INDEX_CLK;
XllpGpioClearAlternateFn(g_pBaseAddressGPIORegs, uiArrPin);
XllpGpioSetFallingEdgeDetectDisable(g_pBaseAddressGPIORegs, uiArrPin);
XllpGpioSetRisingDetectDisable(g_pBaseAddressGPIORegs, uiArrPin);
uiArrPin[1] = VAL_GPIO_INDEX_DATA;
XllpGpioClearAlternateFn(g_pBaseAddressGPIORegs, uiArrPin);
XllpGpioSetFallingEdgeDetectDisable(g_pBaseAddressGPIORegs, uiArrPin);
XllpGpioSetRisingDetectDisable(g_pBaseAddressGPIORegs, uiArrPin);
uiArrPin[1] = VAL_GPIO_INDEX_RST;
XllpGpioClearAlternateFn(g_pBaseAddressGPIORegs, uiArrPin);
XllpGpioSetFallingEdgeDetectDisable(g_pBaseAddressGPIORegs, uiArrPin);
XllpGpioSetRisingDetectDisable(g_pBaseAddressGPIORegs, uiArrPin);
SetPinDirection(RST_1302, FALSE); //设为输出方向
SetPinDirection(DAT_1302, FALSE); //设为输出方向
SetPinDirection(CLK_1302, FALSE); //设为输出方向
OALMSG(1, (TEXT("DS1302_Init Leave!\r\n")));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -