📄 ds1302.c
字号:
/********************************************************************文件名:ds1302.c *功能:给cpu提供实时时钟*完成日期:2004.7.18*S3C4510B DATA:GPIO P1口; CLOCK:GPIO P2口;RESET:GPIO P3口********************************************************************/#include "ds1302.h"#include "htmllib.h"#include <stdio.h>#include <strings.h>#include <unistd.h>#include <stdlib.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/time.h>#include <time.h>#define WORD unsigned int#define BYTE unsigned charint DS1302IN(int ds1302_bit){ int x; iopmod[0]=iopmod[0]&(~ds1302_bit); x=iopdata[0]&ds1302_bit; if(x==0) return 0; else return 1;}TIME_STRUCT ds_1302_time;/* 拷贝系统时间 */void DS1302(unsigned char ds1302_bit,unsigned int logical_value) { iopmod[0]=iopmod[0]|ds1302_bit; if (!logical_value) iopdata[0]=iopdata[0]&(~ds1302_bit); else iopdata[0]=iopdata[0]|ds1302_bit; }/********************************************************************Setup_1302_Port*Initialize Port Pins to access DS1302 Clock.*Note that all three pins are defined initialliy as outputs.*When you want to read a port pin, you have to turn it*around.S3C4510B P1 = DATA P2 = CLOCK P3 = RST********************************************************************/void Setup_1302_Port(void) { iopmod[0]=0x000000ff; Idle_1302(); /* set the port pins idle */ return; } //end proc Setup_1302_Port()/********************************************************************Read_1302_Data*Reads all 8 bytes of data from the DS1302.*Inputs: TimeBuffer- Pointer to 8 byte unsigned char array where data* will be placed once read from the clock*Returns in TimeBuffer:*TimeBuffer[0] seconds: msb=1, clock hold, BCD seconds*TimeBuffer[1] minutes: 0,BCD minutes*TimeBuffer[2] 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*TimeBuffer[3] day of month: BCD day 0-31*TimeBuffer[4] month: BCD 1-12*TimeBuffer[5] day of week: BCD 1-7 1=Sunday*TimeBuffer[6] year: BCD 00-99*TimeBuffer[7] write protect: msb=1, write protect* msb=0, write en*returns: 0 if all is well, non-zero if clock was stopped*NOTE: If clock was stopped, returns non-zero and time is* indicated as Jan 1, 1999, 12:00:00 Noon********************************************************************/unsigned int Read_1302_Data(unsigned char * TimeBuffer) { unsigned char Cmd_Byte; /*clock command*/ unsigned char databyte; /*temp data byte*/ unsigned char shifter; /* bit selector */ unsigned int i,j; unsigned char c; DS1302(CLK_1302,LOW); DS1302(DAT_1302,LOW); DS1302(RST_1302,HIGH); Cmd_Byte = READ_CMD; /* set command to the 1302 for burst read operation */ shifter = 0x01; for(i=0; i<8; i++) /* shift the read command */ { if (shifter & Cmd_Byte) DS1302(DAT_1302,HIGH); else DS1302(DAT_1302,LOW); /* set up the data line */ DS1302(CLK_1302,HIGH); shifter = shifter << 1; DS1302(CLK_1302,LOW); /* toggle the clock */ } //next i for(i=0; i<8; i++) /* read in the next 7 bytes returned */ { databyte = 0; /* start clean */ for(j=0; j<8; j++) /* read in a byte */ { //make room for the new bit databyte = databyte >> 1; /* shift the collected data right */ if (DS1302IN(DAT_1302)) databyte |= 0x80; else /* capture the state of the data line */ databyte &= 0x7f; DS1302(CLK_1302,HIGH); DS1302(CLK_1302,LOW); /* clock the chip */ } //next j TimeBuffer[i] = databyte; /* save it in the buffer */ } //next i Idle_1302(); /* set the port pins idle */ //clean-up of time if time is bad (like when clock is stopped...) if (TimeBuffer[0] > 0x59) { //The time is bogus, make an assumption TimeBuffer[5] = 4; //day of week: BCD 1-7 1=Sunday TimeBuffer[6] = 0x99; //year: BCD 00-99 TimeBuffer[4] = 0x1; //month: BCD 1-12 TimeBuffer[3] = 0x1; //day of month: BCD day 0-31 TimeBuffer[1] = 0x00; //minutes: 0,BCD minutes TimeBuffer[2] = 0x12; //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 TimeBuffer[0] = 0; //0 sec //seconds: msb=1, clock hold, BCD seconds return(1); //indicate that clock was stopped } //end if (TimeBuffer[0] > 59) return(0); //indicate that clock is running } /* end Read_1302_Data() *//*********************************************************************WRITE_1302_Data*This routine will write all 8 bytes to the 1302 clock chip.*Inputs: TimeBuffer- Pointer to 8 byte unsigned char array where data* will be placed once read from the clock*Obtains from TimeBuffer:*TimeBuffer[0] seconds: msb=1, clock hold, BCD seconds*TimeBuffer[1] minutes: 0,BCD minutes*TimeBuffer[2] 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*TimeBuffer[3] day of month: BCD day 0-31*TimeBuffer[4] month: BCD 1-12*TimeBuffer[5] day of week: BCD 1-7 1=Sunday*TimeBuffer[6] year: BCD 00-99*TimeBuffer[7] write protect: msb=1, write protect* msb=0, write en* Returns: None*********************************************************************/void Write_1302_Data(unsigned char * TimeBuffer) { 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 = 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; 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 */ 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 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) { 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -