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

📄 rtc.c

📁 使用ISL12022的一个RTC代码 LPC2000系列
💻 C
📖 第 1 页 / 共 2 页
字号:

/****************************************************************************
* 名   称: I2CWrByte()
* 功   能: I2C写字节
* 入口参数: 
* 出口参数: 
****************************************************************************/
uint8 RTCI2CWrByte(uint8 type,uint8 Addr,uint8 data)
{
	uint8 temp=0;	  
	
	I2CONCLR=0x2c;     			// 清除AA,SI,STA
	I2CONSET=0x60;     			// 使能IIC,发送起始位
	
	I2CDelayWait();
	temp=I2CWrCommand(type); // 写操作   I2C器件本身地址	
	if (temp==FALSE) 
		return FALSE;		
	temp=I2CWrCommand(Addr & 0xff);
	if (temp==FALSE) 
		return FALSE;
	temp=I2CWrCommand(data);    // 写入数据	
	if (temp==FALSE) 
		return FALSE;
	I2CONSET=0x10;     			// 发送停止位
	I2CONCLR = 0x08;
	return TRUE;

}
/****************************************************************************
* 名   称: I2CRdByte()
* 功   能: I2C读字节
* 入口参数: 
* 出口参数: 
****************************************************************************/
uint8 RTCI2CRdByte(uint8 type,uint8 Addr)
{
	uint8 temp=0;	 
	
	//首先进行写地址操作
 	I2CONCLR=0x2c;     			// 清除AA,SI,STA
 	I2CONSET=0x60;     			// 使能IIC,发送起始位
 	
 	I2CDelayWait();
 	temp=I2CWrCommand(type);    // 写操作 	
 	if (temp==FALSE) 
 		return FALSE;
 	temp=I2CWrCommand(Addr & 0xff);
 	if (temp==FALSE) 
 		return FALSE;	
 		
 	//开始读时序
 	I2CONSET=0x20;     			// 发送起始位
 	I2CONCLR=0x08;     			// 清除SI
 	
 	I2CDelayWait();
 	temp=I2CWrCommand(type + 1);    // 声明读操作 	
 	if (temp==FALSE) 
 		return FALSE;
 	I2CONCLR = 0x2c;        
 	
 	I2CDelayWait();
	temp=I2STAT;
  	temp=I2DAT;     
 	I2CONSET=0x50;     			//发送停止位
 	I2CONCLR = 0x08;
 	return temp; 
}


/****************************************************************************
* 名   称: RTC_SetClockData()
* 功   能: 设置RTC初始时钟
* 入口参数: *pClock:初始时钟数据地址 S M H D M W Y C(7Byte BCD码 + 1控制字)
* 出口参数:
****************************************************************************/
void RTC_SetClockData(DateTimeType *pClock)
{ 
	unsigned char ab;
	RTCI2CWrByte(ISL12022,ISL_INT,0X4A); //1S脉冲
	 ab = RTCI2CRdByte(ISL12022,ISL_BETA);
	 ab |= 0xe0;
	 RTCI2CWrByte(ISL12022,ISL_BETA,ab); //使能温补
	RTCI2CWrByte(ISL12022,ISL_SECOND,pClock->second); 
	RTCI2CWrByte(ISL12022,ISL_MINUTE,pClock->minute);
	ab = pClock->hour;
	ab |= 0x80;
	RTCI2CWrByte(ISL12022,ISL_HOUR,ab);
	RTCI2CWrByte(ISL12022,ISL_DAY,pClock->day);
	RTCI2CWrByte(ISL12022,ISL_MONTH,pClock->month);
	RTCI2CWrByte(ISL12022,ISL_YEAR,pClock->year);
	RTCI2CWrByte(ISL12022,ISL_WEEK,pClock->week);
	return;
}
 

/****************************************************************************
* 名   称: RTC_GetClockData()
* 功   能: 获取RTC的当前时间  S M H D M W Y (7Byte BCD码)
* 入口参数: *pClock:读取当前时间存储区 
* 出口参数:
****************************************************************************/
void RTC_GetClockData(DateTimeType *pClock)
{ 
	unsigned char ab;
	pClock->second = RTCI2CRdByte(ISL12022,ISL_SECOND);
	pClock->minute = RTCI2CRdByte(ISL12022,ISL_MINUTE);
	ab = RTCI2CRdByte(ISL12022,ISL_HOUR);
	pClock->hour = ab&0x7f;
	pClock->day = RTCI2CRdByte(ISL12022,ISL_DAY);
	pClock->month = RTCI2CRdByte(ISL12022,ISL_MONTH);
	pClock->year = RTCI2CRdByte(ISL12022,ISL_YEAR);
	pClock->week = RTCI2CRdByte(ISL12022,ISL_WEEK);
}

/****************************************************************************
* 名   称: InitRTC()
* 功   能: 初始化
* 入口参数: 
* 出口参数: 
****************************************************************************/
void InitRTC(void)
{
	unsigned char  ab;
	 RTCI2CWrByte(ISL12022,ISL_INT,0X4A); //1S脉冲
	 ab = RTCI2CRdByte(ISL12022,ISL_BETA);
	 ab |= 0xe0;
	 RTCI2CWrByte(ISL12022,ISL_BETA,ab); //使能温补
}

/****************************************************************************
* 名   称: Init_RTC()
* 功   能: 初始化RTC
* 入口参数: 
* 出口参数:
****************************************************************************/
void RTC_Init(void)
{   
	uint8  week1=0;
	uint8  flag = 0;
	uint8  i;
	  
   	
   	for(i=0;i<3;i++)
   	{
	   	InitRTC();
   		RTC_GetClockData(&SysDateTime);
	
		if(Bcd2Byte(SysDateTime.year) < 0x05)
			flag = 1;
		if((Bcd2Byte(SysDateTime.month) < 1)||(Bcd2Byte(SysDateTime.month) > 12))
			flag = 1;
		if((Bcd2Byte(SysDateTime.day) < 1)||(Bcd2Byte(SysDateTime.day) > 31))
			flag = 1;
		if(Bcd2Byte(SysDateTime.hour) > 23)
			flag = 1;
		if(Bcd2Byte(SysDateTime.minute) > 59)
			flag = 1;
		if(Bcd2Byte(SysDateTime.second) > 59)
			flag = 1;
		
		if(flag == 0)
			break;
	}
	
	if(flag == 1)
	{
		SysDateTime.year   = 0x08;
		SysDateTime.month  = 0x05;
		SysDateTime.day    = 0x01;
		SysDateTime.hour   = 0x00;
		SysDateTime.minute = 0x00;
		SysDateTime.second = 0x00;	
			
		RtcSetClockFlag = VALID_FLAG;
	}
	
	week1 = GetWeek(SysDateTime.year,SysDateTime.month,SysDateTime.day);
	
	if((SysDateTime.week != week1)||(SysDateTime.second & 0x80)||(flag == 1))
	{
		SysDateTime.week = week1;
		SysDateTime.second &= 0x7f;
		RTC_SetClockData(&SysDateTime);
		InitRTC();
	}
	
	DisplayTime(0,11,(DateTimeType *)&SysDateTime);	
}

/****************************************************************************
* 名   称: Init_Clock()
* 功   能: 初始化时钟
* 入口参数: 
* 出口参数: 
****************************************************************************/
void Init_Clock(DateTimeType *pDateTime)
{
	DateTimeType gDateTime;
	
	gDateTime.year   = pDateTime->year;
	gDateTime.month  = pDateTime->month;
	gDateTime.day    = pDateTime->day;
	gDateTime.hour   = pDateTime->hour;
	gDateTime.minute = pDateTime->minute;
	gDateTime.second = pDateTime->second;
	
	gDateTime.week = SysDateTime.week;
	gDateTime.week = GetWeek(gDateTime.year,gDateTime.month,gDateTime.day);
	
	RTC_SetClockData(&gDateTime);
	InitRTC();
	
}
///////////////////////////////////////////////////////////////////
#endif
/****************************************************************************
* 名   称: HandleDateTimeMessage()
* 功   能: 处理时钟消息
* 入口参数: 
* 出口参数: 
****************************************************************************/
void HandleDateTimeMessage(void)
{
	uint8 flag = 0;
	DateTimeType gDateTime;
	
	memset((uint8 *)&gDateTime,0,sizeof(DateTimeType));
	
	if(RtcSetClockFlag == VALID_FLAG)
	{
		if(++RtcSetClockTime > 30)
		{
			if((MeasurePara[1].DI8900 == MEASURE_VALID)&&(MeasurePara[1].DI8901 == MEASURE_TYPE_RS485)
			 &&(MeasurePara[1].DI8903 == MEASURE_RULE_GB)&&(gMeterComm[1].status == METER_COMM_SUCC))
			{
				if((Bcd2Byte(DIC010Addr[1].DIC010.year) < 0x05)||((Bcd2Byte(DIC010Addr[1].DIC010.year) > 20)))
					flag = 1;
				if((Bcd2Byte(DIC010Addr[1].DIC010.month) < 1)||(Bcd2Byte(DIC010Addr[1].DIC010.month) > 12))
					flag = 1;
				if((Bcd2Byte(DIC010Addr[1].DIC010.day) < 1)||(Bcd2Byte(DIC010Addr[1].DIC010.day) > 31))
					flag = 1;
				if(Bcd2Byte(DIC010Addr[1].DIC011.hour) > 23)
					flag = 1;
				if(Bcd2Byte(DIC010Addr[1].DIC011.minute) > 59)
					flag = 1;
				if(Bcd2Byte(DIC010Addr[1].DIC011.second) > 59)
					flag = 1;
				
				if(flag != 1)
				{
					SysDateTime.year   = DIC010Addr[1].DIC010.year;
					SysDateTime.month  = DIC010Addr[1].DIC010.month;
					SysDateTime.day    = DIC010Addr[1].DIC010.day;
					SysDateTime.hour   = DIC010Addr[1].DIC011.hour;
					SysDateTime.minute = DIC010Addr[1].DIC011.minute;
					SysDateTime.second = DIC010Addr[1].DIC011.second;
				}
				
				InitRTC();
				RTC_SetClockData(&SysDateTime);
				RtcCmpTime = 0;
			}
			RtcSetClockTime = 0;
			RtcSetClockFlag = 0;
		}
	}			
		
	if(++RtcCmpTime >= 10)
	{
		RtcCmpTime = 0;
		
		InitRTC();
		RTC_GetClockData(&gDateTime);
		InitRTC();
		if((gDateTime.second & 0x80)||(Bcd2Byte(gDateTime.year) > 20)||(Bcd2Byte(gDateTime.month) > 12)||(Bcd2Byte(gDateTime.day) > 31))
		{
			SysDateTime.second &= 0x7f;
			InitRTC();
			RTC_SetClockData(&SysDateTime);
			InitRTC();
			RTC_GetClockData(&gDateTime);
			InitRTC();
			if(gDateTime.second & 0x80)
			{
				SysDateTime.second &= 0x7f;
				RTC_SetClockData(&SysDateTime);
				InitRTC();
			}
			RtcSetClockFlag = VALID_FLAG;
		}
		else
			memcpy((uint8 *)&SysDateTime,(uint8 *)&gDateTime,sizeof(DateTimeType));
	}
	
	
	TerminalPara.DI8030.year = SysDateTime.year;
	TerminalPara.DI8030.month = SysDateTime.month;
	TerminalPara.DI8030.day = SysDateTime.day;
	TerminalPara.DI8030.hour = SysDateTime.hour;
	TerminalPara.DI8030.minute = SysDateTime.minute;
	TerminalPara.DI8030.second = SysDateTime.second;
}


/****************************************************************************
* 名   称: HandleRTCTimer()
* 功   能: 处理时钟时间
* 入口参数:100ms 
* 出口参数: 
****************************************************************************/
void HandleRTCTimer(void)
{
	uint16 i;

	if(RtcInitFlag == INVALID_FLAG)
	{
		if(++RtcInitTime >= RTC_INIT_TIME)
		{
			RtcInitTime = 0;
			RtcInitFlag = VALID_FLAG;
			for(i=0;i<500;i++);
			RTC_Init();
			for(i=0;i<500;i++);
			SystemClockOKFlag = VALID_FLAG;
			
			OldSystemTimeMin = SysDateTime.minute;	//产生1MIN变量实始化
			
			InitNoPowerTime();						//初始化终端停电时间
		}
	}
}	


/****************************************************************************
* 名   称: Cal_MonthDayNum()
* 功   能: 算出某年某月有多少天
* 说   明: 如果能被4整除而不能被100整除/能被400整除的年份为润年,
		   当年2月为29天
* 方   法:  先计算月份的天数,再计算从1900开始到待求日期的天数,
  		   最后求出星期(1900.1.1是星期一)	
****************************************************************************/
uint8 Cal_MonthDayNum(uint16 year,uint8 month)  
{
	if(month==2)
	{
		return(((year%4==0)&&(year%100!=0)||(year%400==0))?29:28);
	}
	else
		return(monthday[month-1]);
}


/****************************************************************************
* 名   称: Cal_Week()
* 功   能: 计算某年某月某日是星期几(1900年开始)
* 说   明:  计算从1900到当天的天数除7所得余数就是星期几
****************************************************************************/
uint8 Cal_Week(uint16 year,uint8 month,uint8 day)    
{
    uint32 daynum=0;
	uint16 i;
	
	if ((year > 1900)&&( month >= 1)&&(month <= 12)&&(day >0)&&(day <= 31))
	{
		for(i=1900;i<year;i++)
		{
			daynum = daynum + (((i%4==0)&&(i%100!=0)||(i%400==0))?366:365);
		}
		for(i=1;i<month;i++)	
		{
			daynum = daynum + Cal_MonthDayNum(year,i);	
		}
		daynum = daynum + day;
		return(daynum%7);
	}
	else
	{
		return 8;		//"8"表示输入的年月日出错
	}
}

/****************************************************************************
* 名   称: GetWeek()
* 功   能: 获取星期 
* 说   明:  year,month,day:都为BCD码,返回week也为BCD码(或HEX)
****************************************************************************/
uint8 GetWeek(uint8 year,uint8 month,uint8 day)  
{
	uint16 year1=0;
	uint8  month1=0;
	uint8  day1=0;
	uint8  week = 0;
	
	year1 = Bcd2Byte(year) + 2000;
	month1 = Bcd2Byte(month);
	day1 = Bcd2Byte(day);
	
	week = Cal_Week(year1,month1,day1);
	
	return week;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -