📄 ds1306.c
字号:
#include "typedef.h"
#include "Hardef.h"
#include "ds1306.h"
static struct t_time time;
extern volatile TDATE g_tDate;
char rdflag;
extern int c20ms;
void DS1306_Interrupt(INT Vector)
{
return;
}
static bool CompareDate(volatile const TDATE *ptDate,const struct t_time *ptTime)
{
if(ptDate->wYear != ptTime->year) return false;
if(ptDate->byMon != ptTime->month) return false;
if(ptDate->byDay != ptTime->date) return false;
if(ptDate->byHour!= ptTime->hour) return false;
if(ptDate->byMin != ptTime->minute) return false;
if(ptDate->wMs != ptTime->msec) return false;
return true;
}
//BCD与16进制的转换函数
WORD BcdHex(WORD b)
{
WORD h;
h=(b&0xf)+(b&0xf0)/0x10*10;
h+=(b&0xf00)/0x100*100+(b&0xf000)/0x1000*1000;
return h;
}
WORD HexBcd(WORD h)
{
WORD b,t;
if(h>9999)return 0x9999;
t=h;
b=t/1000*0x1000,t%=1000;
b+=t/100*0x100,t%=100;
b+=t/10*0x10+t%10;
return b;
}
//从DS1306读一字节
char read_DS1306(const char reg)
{
register char temp;
register unsigned short data,status;
data=reg;
data<<=8;
*QSM_SPICC=0x58;
*QSM_SPITD=data; //control register
QSM_SPCR0=0x8105; // bit15:MSTR,设置QSPI为主机/从机
// bit14:WOMQ,线或允许/禁止
// bit13-10:BITS,每次传送16位
// bit9:CPOL,SCK无效状态高/低
// bit8:CPHA,时钟相位
// bit7-0:BAUD=1.0Mbps
QSM_SPCR3=0x00; // bit15-11:0,保留
// bit10:LOOPQ,反馈路径允许/禁止
// bit9:HMIE,HALTA和MODF中断允许/禁止
// bit8:HALT,暂停允许/禁止
QSM_SPCR2=0x0000; // ENDQP=0,NEWQP=0
QSM_SPCR1=0xb004; // bit15:SPE,QSPI允许/禁止
// bit14-8:DSCKL,SCK之前延时2.4us,
// bit7-0:DTL,传输间隔6.4us
while(!(QSM_SPSR & 0x80));
for(status =0; status < 250; status++);
QSM_SPSR=0;
temp=(char)*(QSM_SPIRD+0);
return temp;
}
//向DS1306写一字节
void TM_Write_DS1306(const char reg, const unsigned char control)
{
register unsigned short data,status;
data=reg; //reg:address of register
data<<=8; //control:content of register /////?????
data|=control; ///// here I don't understand
///// why locate the reg byte in high
*QSM_SPICC=0x58;
*QSM_SPITD=data; //control register
QSM_SPCR0=0x8105; // bit15:MSTR,设置QSPI为主机/从机
// bit14:WOMQ,线或允许/禁止
// bit13-10:BITS,每次传送16位
// bit9:CPOL,SCK无效状态高/低
// bit8:CPHA,时钟相位
// bit7-0:BAUD=1.0Mbps
QSM_SPCR3=0x00; // bit15-11:0,保留
// bit10:LOOPQ,反馈路径允许/禁止
// bit9:HMIE,HALTA和MODF中断允许/禁止
// bit8:HALT,暂停允许/禁止
QSM_SPCR2=0x0000; // ENDQP=0,NEWQP=0
QSM_SPCR1=0xb004; // bit15:SPE,QSPI允许/禁止
// bit14-8:DSCKL,SCK之前延时2.4us,
// bit7-0:DTL,传输间隔6.4us
while(!(QSM_SPSR&0x80));
for(status=0;status<250;status++);
QSM_SPSR=0;
}
void TM_Read_Timer(void)
{
register unsigned char temp;
register unsigned short temp2,status;
register unsigned char i;
if(rdflag==0x55) return;
rdflag=0x55;
for (i =0; i <= 6; i++)
{
*(QSM_SPICC+i)=0x98;//yy/mm/dd/ww/hh/mm/ss
*(QSM_SPITD+i)=0; //the first byte is address byte
}
*(QSM_SPICC+7)=0x18;//yy/mm/dd/ww/hh/mm/ss
*(QSM_SPITD+7)=0; //the first byte is address byte
QSM_SPCR0=0x8105; // bit15:MSTR,设置QSPI为主机/从机
// bit14:WOMQ,线或允许/禁止
// bit13-10:BITS,每次传送16位
// bit9:CPOL,SCK无效状态高/低
// bit8:CPHA,时钟相位
// bit7-0:BAUD=1.0Mbps
QSM_SPCR3=0x00; // bit15-11:0,保留
// bit10:LOOPQ,反馈路径允许/禁止
// bit9:HMIE,HALTA和MODF中断允许/禁止
// bit8:HALT,暂停允许/禁止
QSM_SPCR2=0x0700; // ENDQP=7,NEWQP=0
QSM_SPCR1=0xb004; // bit15:SPE,QSPI允许/禁止
// bit14-8:DSCKL,SCK之前延时2.4us,
// bit7-0:DTL,传输间隔6.4us
while(!(QSM_SPSR & 0x80));
for(status =0; status < 250; status++);
QSM_SPSR=0;
temp2=(short)*(QSM_SPIRD+7);
temp=(unsigned char)BcdHex((WORD)temp2);
if(temp > 90)
time.year=temp+1900; //year
else
time.year=temp+2000;
temp=(char)*(QSM_SPIRD+6);
time.month=(unsigned char)BcdHex((WORD)temp); //month
if(time.month>12) time.month=0;
temp=(char)*(QSM_SPIRD+5);
time.date=(unsigned char)BcdHex((WORD)temp); //date
if(time.date>32) time.date=0;
temp=(char)*(QSM_SPIRD+3);
time.hour=(unsigned char)BcdHex((WORD)temp); //hour
if(time.hour>24) time.hour=0;
temp=(char)*(QSM_SPIRD+2);
time.minute=(unsigned char)BcdHex((WORD)temp); //minute
if(time.minute>60) time.minute=0;
temp=(char)*(QSM_SPIRD+1);
time.second=(unsigned char)BcdHex((WORD)temp); //second
if(time.second > 60) time.second=0;
time.msec=time.second*1000; //msecond=1000*second
c20ms=time.second*47;
//copy t_time time to TDATE g_tDate
CopyTimeToDate:
g_tDate.wYear=time.year;
g_tDate.byMon=time.month;
g_tDate.byDay=time.date;
g_tDate.byHour=time.hour;
g_tDate.byMin=time.minute;
g_tDate.wMs=time.msec;
if(!CompareDate(&g_tDate,&time)) goto CopyTimeToDate;
rdflag=0;
}
void TM_Write_Timer(const TDATE *ptDate)
{
register unsigned short data,status;
unsigned short temp;
//copy TDATE tDate to t_time time
CopyDateToTime:
time.year=ptDate->wYear;
time.month=ptDate->byMon;
time.date=ptDate->byDay;
time.hour=ptDate->byHour;
time.minute=ptDate->byMin;
time.msec=ptDate->wMs;
if(!CompareDate(ptDate,&time)) goto CopyDateToTime;
//deal with msec
time.second=time.msec/1000;
temp=time.msec%1000;
if((temp>=500)&&(time.second<59)) time.second++;
TM_Write_DS1306((char)0x8f,0x00); //disable write protect
*(QSM_SPICC+0)=0x98; //address byte for burst transfer
*(QSM_SPITD+0)=0x80; //address increase automatically
*(QSM_SPICC+1)=0x98; //sec
data=HexBcd(time.second);
*(QSM_SPITD+1)=data;
*(QSM_SPICC+2)=0x98; //min
data=HexBcd(time.minute);
*(QSM_SPITD+2)=data;
*(QSM_SPICC+3)=0x98; //hour
data=HexBcd(time.hour);
*(QSM_SPITD+3)=data;
*(QSM_SPICC+4)=0x98; //day of the week
data=HexBcd(time.date);
*(QSM_SPITD+4)=data;
*(QSM_SPICC+5)=0x98; //date
data=HexBcd(time.date);
*(QSM_SPITD+5)=data;
*(QSM_SPICC+6)=0x98; //month
data=HexBcd(time.month);
*(QSM_SPITD+6)=data;
*(QSM_SPICC+7)=0x18; //year
data=HexBcd((unsigned short)(time.year%100));
*(QSM_SPITD+7)=data;
QSM_SPCR0=0x8105; // bit15:MSTR,设置QSPI为主机/从机
// bit14:WOMQ,线或允许/禁止
// bit13-10:BITS,每次传送16位
// bit9:CPOL,SCK无效状态高/低
// bit8:CPHA,时钟相位
// bit7-0:BAUD=1.0Mbps
QSM_SPCR3=0x00; // bit15-11:0,保留
// bit10:LOOPQ,反馈路径允许/禁止
// bit9:HMIE,HALTA和MODF中断允许/禁止
// bit8:HALT,暂停允许/禁止
QSM_SPCR2=0x0700; // ENDQP=7,NEWQP=0
QSM_SPCR1=0xb004; // bit15:SPE,QSPI允许/禁止
// bit14-8:DSCKL,SCK之前延时2.4us,
// bit7-0:DTL,传输间隔6.4us
while(!(QSM_SPSR & 0x80));
for(status =0; status < 250; status++);
QSM_SPSR=0;
TM_Write_DS1306((char)0x8f,0x40); //enable write protect
}
///////////////
void TM_Write_Alarm_Timer(void)
{
register unsigned short status;
//copy TDATE tDate to t_time time
TM_Write_DS1306((char)0x8f,0x00); //disable write protect and enable AIE0
*(QSM_SPICC+0)=0x98; //address byte for burst transfer
*(QSM_SPITD+0)=0x87; //address increase automatically
*(QSM_SPICC+1)=0x98; //sec alarm
*(QSM_SPITD+1)=0x84;
*(QSM_SPICC+2)=0x98; //min alarm
*(QSM_SPITD+2)=0x84;
*(QSM_SPICC+3)=0x98; //hour alarm
*(QSM_SPITD+3)=0x84;
*(QSM_SPICC+4)=0x18; //day of the week alarm
*(QSM_SPITD+4)=0x84;
QSM_SPCR0=0x8105; // bit15:MSTR,设置QSPI为主机/从机
// bit14:WOMQ,线或允许/禁止
// bit13-10:BITS,每次传送16位
// bit9:CPOL,SCK无效状态高/低
// bit8:CPHA,时钟相位
// bit7-0:BAUD=1.0Mbps
QSM_SPCR3=0x00; // bit15-11:0,保留
// bit10:LOOPQ,反馈路径允许/禁止
// bit9:HMIE,HALTA和MODF中断允许/禁止
// bit8:HALT,暂停允许/禁止
QSM_SPCR2=0x0500; // ENDQP=5,NEWQP=0
QSM_SPCR1=0xb004; // bit15:SPE,QSPI允许/禁止
// bit14-8:DSCKL,SCK之前延时2.4us,
// bit7-0:DTL,传输间隔6.4us
while(!(QSM_SPSR & 0x80));
for(status =0; status < 250; status++);
QSM_SPSR=0;
TM_Write_DS1306((char)0x8f,0x40); //enable write protect
}
void TM_Read_Alarm_Timer(void)
{
register unsigned char temp;
// register unsigned short temp5,temp6,temp7,temp8;
register unsigned short status;
register unsigned char i;
for (i =0; i <= 3; i++)
{
*(QSM_SPICC+i)=0x98;///ww/hh/mm/ss
*(QSM_SPITD+i)=0x07; //the first byte is address byte
}
*(QSM_SPICC+4)=0x18;
*(QSM_SPITD+4)=0x07;
QSM_SPCR0=0x8105; // bit15:MSTR,设置QSPI为主机/从机
// bit14:WOMQ,线或允许/禁止
// bit13-10:BITS,每次传送16位
// bit9:CPOL,SCK无效状态高/低
// bit8:CPHA,时钟相位
// bit7-0:BAUD=1.0Mbps
QSM_SPCR3=0x00; // bit15-11:0,保留
// bit10:LOOPQ,反馈路径允许/禁止
// bit9:HMIE,HALTA和MODF中断允许/禁止
// bit8:HALT,暂停允许/禁止
QSM_SPCR2=0x0500; // ENDQP=5,NEWQP=0
QSM_SPCR1=0xb004; // bit15:SPE,QSPI允许/禁止
// bit14-8:DSCKL,SCK之前延时2.4us,
// bit7-0:DTL,传输间隔6.4us
while(!(QSM_SPSR & 0x80));
for(status =0; status < 250; status++);
QSM_SPSR=0;
temp=(char)*(QSM_SPIRD+4);
if (temp&0x80) temp=0x30;
temp=(char)*(QSM_SPIRD+3);
if (temp&0x80) temp=0x30;
temp=(char)*(QSM_SPIRD+2);
if (temp&0x80) temp=0x30;
temp=(char)*(QSM_SPIRD+1);
if (temp&0x80) temp=0x30;
temp=(char)*(QSM_SPIRD+0);
if (temp&0x80) temp=0x30;
/*
*/
}
void TM_Read_DS_Array(char Offset,unsigned char Size,unsigned char *pTo)
{
char Addr;
unsigned char i;
Addr=0x20+Offset;
for(i =0; i < Size; i++)
{
*pTo++=read_DS1306(Addr++);
}
}
void TM_Write_DS_Array(char Offset,unsigned char Size,unsigned char *pFrom)
{
char Addr;
unsigned char i;
Addr=0xA0+Offset;
TM_Write_DS1306((char)0x8f,0); //disable write protect
for(i =0; i < Size; i++)
{
TM_Write_DS1306(Addr++,*pFrom++);
}
TM_Write_DS1306((char)0x8f,0x40); //enable write protect
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -