⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds1306.c

📁 DS1306 driver 时钟芯片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 + -