www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > > 充電吧
[導讀]//C文件/**********************************************************************************************

//C文件


/*************************************************************************************************************
?*?文件名:			PCF8563.c
?*?功能:			STM32?PCF8563?高精度?RTC?芯片驅動
?*?作者:			cp1300@139.com
?*?創(chuàng)建時間:		2017-07-10
?*?最后修改時間:	2017-07-10
?*?詳細:			使用軟件IIC接口驅動
					2017-07-13:通過寫入PCF8563_REG_CLKOUT與讀取PCF8563_REG_CLKOUT寄存器,發(fā)現某些不用的位會亂跳,最終發(fā)現時間寄存器也有同樣的問題,需要把不用的位都屏蔽掉
*************************************************************************************************************/
#include?"system.h"
#include?"delay.h"
#include?"PCF8563.h"
#include?"stdio.h"
#include?"SoftwareIIC.h"

//月修正數據表
static?u8?const?table_week[12]?=?{0,3,3,6,1,4,6,2,5,0,3,5};?		??
//平年的月份日期表
static?u8?const?mon_table[12]?=?{31,28,31,30,31,30,31,31,30,31,30,31};
static?bool?Is_Leap_Year(u16?year);


rtc_timer?ext_timer;	//外部RTC時鐘
static?SIIC_HANDLE?IIC_Handel;

#define?PCF8563_SDA_GPIOx?	GPIOC
#define?PCF8563_SCL_GPIOx?	GPIOC
#define?PCF8563_SDA_Bit?	1
#define?PCF8563_SCL_Bit	?	13




//調試宏開關
#define?PCF8563_DBUG	1
#if?PCF8563_DBUG
	#include?"system.h"
	#define?PCF8563_Debug(format,...)	uart_printf(format,##__VA_ARGS__)
#else
	#define?PCF8563_Debug(format,...)	/
/
#endif	//PCF8563_DBUG


//PCF8563?iic總線地址
#define?PCF8563_IIC_W_ADDR			0xA2
#define?PCF8563_IIC_R_ADDR			0xA3


static?u8?GetWeek(u16?year,u8?month,u8?day);	//獲取2000-2099年之間的日期對應的星期
static?u32?DECtoBCD(?u8?DEC);					//將數字轉換為壓縮BCD格式,最大支持99
static?u32?BCDtoDEC(u8?BCD);					//將壓縮BCD轉為DEC,最大支持99
bool?PCF8563_ReadReg(PCF8563_REG_TYPE?RegIndex,?u8?*pData,?u8?RegNum)?;		//讀取PCF8563寄存器
bool?PCF8563_WriteReg(PCF8563_REG_TYPE?RegIndex,?u8?*pData,?u8?RegNum)?;	//寫入PCF8563寄存器
bool?PCF8563_WriteOneReg(PCF8563_REG_TYPE?RegIndex,?u8?Data);				//寫單個寄存器


/*************************************************************************************************************************
*函數????????	:	bool?PCF8563_Init(void)
*功能????????	:	初始化PCF8563
*參數????????	:	無
*返回????????	:	FALSE:失敗;TRUE:成功
*依賴			:?	底層宏定義
*作者???????	:	cp1300@139.com
*時間?????		:	2017-07-10
*最后修改時間	:	2017-07-10
*說明????????	:	無
*************************************************************************************************************************/
bool?PCF8563_Init(void)
{
	u8?data;
	
	memset(&ext_timer,0,sizeof(rtc_timer));
	if(SIIC_Init(&IIC_Handel,PCF8563_SDA_GPIOx,?PCF8563_SCL_GPIOx,?PCF8563_SDA_Bit,?PCF8563_SCL_Bit,?1)?==?FALSE)
	{
		PCF8563_Debug("**********************PCF8563?初始化失敗,IIC接口初始化失??!rn");
		return?FALSE;
	}
	
	if(PCF8563_WriteOneReg(PCF8563_REG_CONTROL1,?0x08)?==?FALSE)	//啟動時鐘,開啟掉電檢測
	{
		PCF8563_Debug("**********************PCF8563?初始化失敗,開啟掉電監(jiān)測功能失敗!rn");
		return?FALSE;
	}

	if(PCF8563_ReadReg(PCF8563_REG_SECONDS,?&data,?1)?==?FALSE)
	{
		PCF8563_Debug("**********************PCF8563?初始化失敗,讀取秒寄存器失?。n");
		return?FALSE;
	}
	if(data?&?0x80)	//秒?最高位為1,時鐘芯片沒有初始化?integrity?of?the?clock?information?is?no?longer?guaranteed
	{
		//初始化時鐘芯片與時間
		PCF8563_Debug("時鐘芯片沒有初始化,需要重新初始化時鐘!rn");
		if(PCF8563_SetTimer(2017,6,6,6,6,6)==FALSE)
		{
			PCF8563_Debug("時鐘芯片沒有初始化,需要重新初始化時鐘!rn");
		}
	}
	
	PCF8563_GetTimer();		//更新時間
	return?TRUE;
}

/*************************************************************************************************************************
*函數????????	:	bool?PCF8563_ReadReg(PCF8563_REG_TYPE?RegIndex,?u8?*pData,?u8?RegNum)?
*功能????????	:	讀取PCF8563多個寄存器
*參數????????	:	RegIndex:寄存器地址,pData:讀取到的值,RegNum:讀取的寄存器數量
*返回????????	:	TRUE:通信成功;FALSE:通信失敗
*依賴			:?	底層宏定義
*作者???????	:	cp1300@139.com
*時間?????		:	2017-07-10
*最后修改時間	:	2017-07-10
*說明????????	:	無
*************************************************************************************************************************/
bool?PCF8563_ReadReg(PCF8563_REG_TYPE?RegIndex,?u8?*pData,?u8?RegNum)?
{
	u8?i;
	
	if(RegNum?<?1)?RegNum?=?1;
	if(RegNum?>?16)?RegNum?=?16;								//限制讀取的最大數量
	
	SIIC_Start(&IIC_Handel);									//發(fā)送起始信號
	if(SIIC_SendByte(&IIC_Handel,?PCF8563_IIC_W_ADDR)==FALSE)	//發(fā)送寫地址
	{
		PCF8563_Debug("PCF8563?發(fā)送寫地址?ACK錯誤rn");
		return?FALSE;
	}
	
	if(SIIC_SendByte(&IIC_Handel,?RegIndex)==FALSE)				//發(fā)送要讀取的寄存器地址
	{
		PCF8563_Debug("PCF8563?發(fā)送要讀取的寄存器地址2?ACK錯誤rn");
		return?FALSE;
	}
	
	SIIC_Start(&IIC_Handel);									//發(fā)送起始信號	
	
	
	if(SIIC_SendByte(&IIC_Handel,?PCF8563_IIC_R_ADDR)==FALSE)	//發(fā)送讀取地址
	{
		PCF8563_Debug("PCF8563?發(fā)送讀取地址?ACK錯誤rn");
		return?FALSE;
	}
	
	for(i?=?0;i?<?RegNum;i?++)
	{
		if(i?==?(RegNum-1))										//最后一字節(jié)
		{
			pData[i]?=?SIIC_ReadByte(&IIC_Handel,?FALSE);		//讀取數據-最后一字節(jié)不發(fā)送ACK
		}
		else
		{
			pData[i]?=?SIIC_ReadByte(&IIC_Handel,?TRUE);		//讀取數據
		}
	}
	
	SIIC_Stop(&IIC_Handel);										//發(fā)送結束

	return?TRUE;
}


/*************************************************************************************************************************
*函數????????	:	bool?PCF8563_ReadOneReg(PCF8563_REG_TYPE?RegIndex,?u8?*pData)?
*功能????????	:	讀取PCF8563單個寄存器
*參數????????	:	RegIndex:寄存器地址,pData:讀取到的值
*返回????????	:	TRUE:通信成功;FALSE:通信失敗
*依賴			:?	底層宏定義
*作者???????	:	cp1300@139.com
*時間?????		:	2017-07-10
*最后修改時間	:	2017-07-13
*說明????????	:	無
*************************************************************************************************************************/
bool?PCF8563_ReadOneReg(PCF8563_REG_TYPE?RegIndex,?u8?*pData)?
{
	SIIC_Start(&IIC_Handel);									//發(fā)送起始信號
	if(SIIC_SendByte(&IIC_Handel,?PCF8563_IIC_W_ADDR)==FALSE)	//發(fā)送寫地址
	{
		PCF8563_Debug("PCF8563?發(fā)送寫地址?ACK錯誤rn");
		return?FALSE;
	}
	
	if(SIIC_SendByte(&IIC_Handel,?RegIndex)==FALSE)				//發(fā)送要讀取的寄存器地址
	{
		PCF8563_Debug("PCF8563?發(fā)送要讀取的寄存器地址2?ACK錯誤rn");
		return?FALSE;
	}
	
	SIIC_Start(&IIC_Handel);									//發(fā)送起始信號	
	
	
	if(SIIC_SendByte(&IIC_Handel,?PCF8563_IIC_R_ADDR)==FALSE)	//發(fā)送讀取地址
	{
		PCF8563_Debug("PCF8563?發(fā)送讀取地址?ACK錯誤rn");
		return?FALSE;
	}
	
	*pData?=?SIIC_ReadByte(&IIC_Handel,?FALSE);					//讀取數據-最后一字節(jié)不發(fā)送ACK
	
	SIIC_Stop(&IIC_Handel);										//發(fā)送結束
	return?TRUE;
}


/*************************************************************************************************************************
*函數????????	:	bool?PCF8563_WriteReg(PCF8563_REG_TYPE?RegIndex,?u8?*pData,?u8?RegNum)?
*功能????????	:	寫PCF8563多個寄存器
*參數????????	:	RegIndex:寄存器地址,pData:寫入的值,RegNum:寫入的寄存器數量
*返回????????	:	TRUE:通信成功;FALSE:通信失敗
*依賴			:?	底層宏定義
*作者???????	:	cp1300@139.com
*時間?????		:	2017-07-10
*最后修改時間	:	2017-07-10
*說明????????	:	無
*************************************************************************************************************************/
bool?PCF8563_WriteReg(PCF8563_REG_TYPE?RegIndex,?u8?*pData,?u8?RegNum)?
{
	u8?i;

	SIIC_Start(&IIC_Handel);									//發(fā)送起始信號
	if(SIIC_SendByte(&IIC_Handel,?PCF8563_IIC_W_ADDR)==FALSE)	//發(fā)送寫地址
	{
		PCF8563_Debug("PCF8563?發(fā)送寫地址?ACK錯誤rn");
		return?FALSE;
	}

	/*if(SIIC_SendByte(&IIC_Handel,?0)==FALSE)				//發(fā)送要讀取的寄存器地址
	{
		PCF8563_Debug("PCF8563?發(fā)送要讀取的寄存器地址2?ACK錯誤rn");
		return?FALSE;
	}*/
	
	if(SIIC_SendByte(&IIC_Handel,?RegIndex)==FALSE)				//發(fā)送要寫的寄存器地址
	{
		PCF8563_Debug("PCF8563?發(fā)送要讀取的寄存器地址2?ACK錯誤rn");
		return?FALSE;
	}
	/*SIIC_Start(&IIC_Handel);									//發(fā)送起始信號						
	if(SIIC_SendByte(&IIC_Handel,?PCF8563_IIC_W_ADDR)==FALSE)	//發(fā)送寫地址
	{
		PCF8563_Debug("PCF8563?發(fā)送讀取地址?ACK錯誤rn");
		return?FALSE;
	}*/
	
	for(i?=?0;i?<?RegNum;i?++)
	{
		SIIC_SendByte(&IIC_Handel,?pData[i]);					//發(fā)送數據
	}
	
	SIIC_Stop(&IIC_Handel);										//發(fā)送結束
???
	return?TRUE;
}


/*************************************************************************************************************************
*函數????????	:	bool?PCF8563_WriteOneReg(PCF8563_REG_TYPE?RegIndex,?u8?Data)??
*功能????????	:	寫PCF8563單個寄存器
*參數????????	:	RegIndex:寄存器地址,Data:寫入的值
*返回????????	:	TRUE:通信成功;FALSE:通信失敗
*依賴			:?	底層宏定義
*作者???????	:	cp1300@139.com
*時間?????		:	2017-07-10
*最后修改時間	:	2017-07-13
*說明????????	:	無
*************************************************************************************************************************/
bool?PCF8563_WriteOneReg(PCF8563_REG_TYPE?RegIndex,?u8?Data)?
{
	SIIC_Start(&IIC_Handel);									//發(fā)送起始信號
	if(SIIC_SendByte(&IIC_Handel,?PCF8563_IIC_W_ADDR)==FALSE)	//發(fā)送寫地址
	{
		PCF8563_Debug("PCF8563?發(fā)送寫地址?ACK錯誤rn");
		return?FALSE;
	}
	if(SIIC_SendByte(&IIC_Handel,?RegIndex)==FALSE)				//發(fā)送要寫的寄存器地址
	{
		PCF8563_Debug("PCF8563?發(fā)送要讀取的寄存器地址2?ACK錯誤rn");
		return?FALSE;
	}
	
	SIIC_SendByte(&IIC_Handel,?Data);							//發(fā)送數據
	
	SIIC_Stop(&IIC_Handel);										//發(fā)送結束
???
	return?TRUE;
}

/*************************************************************************************************************************
*?函數			:	bool?PCF8563_GetTimer(void)
*?功能			:	PCF8563獲取時間
*?參數			:	無
*?返回			:	TRUE:成功,FALSE:失敗
*?依賴			:	底層宏定義
*?作者			:	cp1300@139.com
*?時間			:	2017-07-11
*?最后修改時間?	:?	2017-07-11
*?說明			:?	獲取到的時間會更新到全局ext_timer
*************************************************************************************************************************/
bool?PCF8563_GetTimer(void)
{
	u8?data[7];
	u8?retry;
	u8?temp;

	
	for(retry?=?0;retry?<?3;retry?++)
	{
		if(PCF8563_ReadReg(PCF8563_REG_SECONDS,?data,?7)?==?TRUE)	//設置時間
		{
			if(data[0]?&?0x80)	//時間無效
			{
				PCF8563_Debug("PCF8563?時間無效,需要重新初始化!rn");
				PCF8563_SetTimer(2017,6,6,6,6,6);					//初始化設置時間
			}
			else
			{
				
				//uart_printf("%02X,%02X,%02X,%02X,%02X,%02X,%02Xrn",data[0],data[1],data[2],data[3],data[4],data[5],data[6]);
				temp?=?BCDtoDEC(data[0]&0x7F);
				if(temp?>?59)?continue;				//秒鐘范圍不對
				ext_timer.sec?=?temp;
				temp?=?BCDtoDEC(data[1]&0x7F);
				if(temp?>?59)?continue;				//分鐘范圍不對
				ext_timer.min?=?temp;
				temp?=?BCDtoDEC(data[2]&0x3F);
				if(temp?>?23)?continue;				//小時范圍不對
				ext_timer.hour?=?temp;
				temp?=?BCDtoDEC(data[3]&0x3F);
				if(temp?>?31||temp==0)?continue;	//日期范圍不對
				ext_timer.date?=?temp;
				temp?=?BCDtoDEC(data[4]&0x07);
				if(temp?>?6)?continue;				//星期范圍不對
				ext_timer.week?=?temp+1;
				temp?=?BCDtoDEC(data[5]&0x1F);
				if(temp?>?12||temp==0)?continue;	//月份范圍不對
				ext_timer.month?=?temp;
				ext_timer.year?=?BCDtoDEC(data[6])+2000;

				return?TRUE;
			}
		}
		else
		{
			PCF8563_Debug("PCF8563?讀取時間失??!rn");
		}
	}
	return?FALSE;
}



/*************************************************************************************************************************
*?函數			:	bool?PCF8563_SetTimer(u16?year,u8?month,u8?date,u8?hour,u8?min,u8?sec)
*?功能			:	PCF8563時間設置
*?參數			:	year,month,date:年(2000~2099),月(1~12),日(1~31),hour,min,sec:小時24小時,分鐘,秒鐘
*?返回			:	TRUE:成功,FALSE:失敗
*?依賴			:	底層宏定義
*?作者			:	cp1300@139.com
*?時間			:	2017-07-11
*?最后修改時間?	:?	2017-07-11
*?說明			:?	
*************************************************************************************************************************/
bool?PCF8563_SetTimer(u16?year,u8?month,u8?date,u8?hour,u8?min,u8?sec)
{
	u8?data[7];
	
	if(year?<?2000)?year?=?2000;
	if(year?>?2099)?year?=?2099;
	
	data[0]?=?DECtoBCD(sec);	//秒
	data[1]?=?DECtoBCD(min);	//分
	data[2]?=?DECtoBCD(hour);	//小時
	data[3]?=?DECtoBCD(date);	//日
	data[4]?=?GetWeek(year,?month,?date)-1;	//星期
	year?-=?2000;
	data[5]?=?DECtoBCD(month);	//月
	data[6]?=?DECtoBCD(year);	//年
	
	PCF8563_WriteReg(PCF8563_REG_SECONDS,?&data[0],?7);	//設置時間

	
	
	if(PCF8563_WriteOneReg(PCF8563_REG_CONTROL1,?0x08)?==?FALSE)	//啟動時鐘,開啟掉電檢測
	{
		PCF8563_Debug("**********************PCF8563?設置失敗,啟動時鐘失?。n");
		return?FALSE;
	}
	
	return?TRUE;
}







/*************************************************************************************************************************
*?函數			:	u32?PCF8563_TimeToSec(u16?syear,u8?smon,u8?sday,u8?hour,u8?min,u8?sec)
*?功能			:	PCF8563時間轉換為秒(從1970開始)(注意:不可重入,請注意調用沖突)
*?參數			:	year,month,date:年(2000~2099),月(1~12),日(1~31),hour,min,sec:小時24小時,分鐘,秒鐘
*?返回			:	TRUE:成功,FALSE:失敗
*?依賴			:	底層宏定義
*?作者			:	cp1300@139.com
*?時間			:	2017-07-11
*?最后修改時間?	:?	2017-07-17
*?說明			:?	只能計算從2000年之后的秒,修改如果年,月,日不變,則無需重新計算,提高效率
					注意:不可重入,請注意調用沖突
*************************************************************************************************************************/
u32?PCF8563_TimeToSec(u16?syear,u8?smon,u8?sday,u8?hour,u8?min,u8?sec)
{
	u16?t;
	u32?seccount?=?0;
	static?u32?LastYearSec?=?0;		//之前年對應的秒,如果年不變,則不用重新計算
	static?u32?LastMonSec?=?0;		//當前年月份對應的秒數,如果月份不變,則不需要重新計算
	static?u32?LastDaySec?=?0;		//當前日期對應的秒,如果日期不變,則不需要重新計算
	static?u16?LastYear?=?0;		//之前的年如果不變,則只計算今年的秒
	static?u8?LastMon?=?0;			//當前年之前的月份
	static?u8?LastDay?=?0;			//之前的日期
	
	
	
	if(syear?<?2000?||?syear?>?2099)
		return?0;

	//年變化了才重新計算
	if(LastYear?!=?syear)							//年發(fā)生了變化,重新計算
	{
		LastYear?=?syear;							//記錄本次的年
		LastYearSec?=?0;
		for(t?=?1970;t?<?syear;t?++)				//把所有年份的秒鐘相加
		{
			if(Is_Leap_Year(t))
				LastYearSec?+=?31622400;			//閏年的秒鐘數
			else?
				LastYearSec?+=?31536000;			??//平年的秒鐘數
		}
	}

	//月變化了才重新計算
	if(LastMon?!=?smon)								//月份有變化
	{
		LastMon?=?smon;								//記錄本次的月份
		smon?-=?1;
		LastMonSec?=?0;
		for(t?=?0;t?<?smon;t?++)	???					//把前面月份的秒鐘數相加
		{
			LastMonSec?+=?(u32)mon_table[t]?*?86400;	//月份秒鐘數相加
			if(Is_Leap_Year(syear)?&&?t?==?1)
				LastMonSec?+=?86400;					//閏年2月份增加一天的秒鐘數	???
		}
	}
	//日期變化了才重新計算
	if(LastDay?!=?sday)
	{
		LastDay?=?sday;								//記錄本次的日期
		LastDaySec?=?(u32)(sday?-?1)?*?86400;		//把前面日期的秒鐘數相加?
	}
	
	seccount?=?LastYearSec+LastMonSec+LastDaySec;	//直接獲取年對應的秒,不用每次計算

	seccount?+=?(u32)hour?*?3600;					//小時秒鐘數
????seccount?+=?(u32)min?*?60;	?					//分鐘秒鐘數
	seccount?+=?sec;								//最后的秒鐘加上去
	
	return?seccount;
}



??
/*************************************************************************************************************************
*?函數			:	bool?Is_Leap_Year(u16?year)
*?功能			:	判斷是否是閏年函數
*?參數			:	year:年份
*?返回			:	TRUE:是閏年,FALSE:不是閏年
*?依賴			:	無
*?作者			:	cp1300@139.com
*?時間			:	2014-05-30
*?最后修改時間	:	2014-05-30
*?說明			:?	
					月份???1??2??3??4??5??6??7??8??9??10?11?12
					閏年???31?29?31?30?31?30?31?31?30?31?30?31
					非閏年?31?28?31?30?31?30?31?31?30?31?30?31	
*************************************************************************************************************************/
static?bool?Is_Leap_Year(u16?year)
{			??
	if(year?%?4?==?0)?//必須能被4整除
	{?
		if(year?%?100?==?0)?
		{?
			if(year?%?400?==?0)
				return?TRUE;//如果以00結尾,還要能被400整除?	???
			else?
				return?FALSE;???
		}else?
			return?TRUE;???
	}else?
		return?FALSE;	
}


//獲取2000-2099年之間的日期對應的星期
//功能描述:輸入公歷日期得到星期(只允許1901-2099年)
//year,month,day:公歷年月日?
//返回值:星期號(1~7,代表周1~周日)																						?
static?u8?GetWeek(u16?year,u8?month,u8?day)
{	
	u16?temp2;
	u8?yearH,yearL;
	yearH=year/100;	yearL=year%100;?
	//?如果為21世紀,年份數加100??
	if?(yearH>19)yearL+=100;
	//?所過閏年數只算1900年之后的??
	temp2=yearL+yearL/4;
	temp2=temp2%7;?
	temp2=temp2+day+table_week[month-1];
	if?(yearL%4==0&&month<3)temp2--;
	temp2%=7;
	if(temp2==0)temp2=7;
	return?temp2;
}	




//將數字轉換為壓縮BCD格式,最大支持99
static?u32?DECtoBCD(?u8?DEC)?
{
	return?((u8)(DEC/10)<>4)*10+(BCD&0x0f);
}



//使能系統命令行
#if?SYS_CMD_EN_
#include?"cmd.h"
#include?"string.h"

const?CMD_TYPE??CMD_GET_ExtTIME		=	{"TIME?",?0xCC5C410A,?CMD_ExtGetTime,?"tt獲取系統時間"};
const?CMD_TYPE??CMD_GET_ExtDATE		=	{"DATE?",?0xB2704461,?CMD_ExtGetDate,?"tt獲取系統日期"};
const?CMD_TYPE??CMD_SET_ExtTIME		=	{"TIME=",?0xCC5C4108,?CMD_ExtSetTime,?"tt設置系統時間?如(12:32:54):TIME=12?32?54"};
const?CMD_TYPE??CMD_SET_ExtDATE		=	{"DATE=",?0xB270445F,?CMD_ExtSetDate,?"tt設置系統日期?如(2014?6?8):TIME=2014?6?8"};

//獲取時間
void?CMD_ExtGetTime(char?*pStr)
{
	//PCF8563_GetTimer();		//更新時間
	cmd_printf("[獲取時間成功]:%02d:%02d:%02drn",ext_timer.hour,?ext_timer.min,?ext_timer.sec);
}

//獲取日期
void?CMD_ExtGetDate(char?*pStr)
{
	//PCF8563_GetTimer();		//更新時間
	cmd_printf("[獲取日期成功]:%04d-%02d-%02drn",ext_timer.year,?ext_timer.month,?ext_timer.date);
}

//設置時間
void?CMD_ExtSetTime(char?*pStr)
{
	u8?hour,min,sec;
	u8?len;
	char?*p;
	u8?num;
	
	len?=?strlen(pStr);	//獲取長度
	if(isStrNumAndSpc(pStr,?len,?2)?==?FALSE)
	{
		cmd_printf("[時間設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	//小時
	p?=?strstr(pStr,"?");	//搜索空格
	if(p?==?NULL)
	{
		cmd_printf("[時間設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	num?=?p?-?pStr;
	if((num?>?2)?||?(num?==?0))
	{
		cmd_printf("[時間設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	hour?=?CMD_StringToDec(pStr,?num);
	if(hour>23)
	{
		cmd_printf("[時間設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	
	//分鐘
	pStr?=?p+1;
	p?=?strstr(pStr,"?");	//搜索空格
	if(p?==?NULL)
	{
		cmd_printf("[時間設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	num?=?p?-?pStr;
	if((num?>?2)?||?(num?==?0))
	{
		cmd_printf("[時間設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	min?=?CMD_StringToDec(pStr,?num);
	if(min>59)
	{
		cmd_printf("[時間設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	//秒鐘
	pStr?=?p+1;
	num?=?strlen(pStr);
	if((num?>?2)?||?(num?==?0))
	{
		cmd_printf("[時間設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	sec?=?CMD_StringToDec(pStr,?num);
	if(sec>59)
	{
		cmd_printf("[時間設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	
	PCF8563_GetTimer();		//更新時間
	if(PCF8563_SetTimer(ext_timer.year,?ext_timer.month,?ext_timer.date,hour,?min,?sec)?==?FALSE)
	{
		PCF8563_GetTimer();		//更新時間
		cmd_printf("[時間設置失敗]:%02d:%02d:%02drn",ext_timer.hour,?ext_timer.min,?ext_timer.sec);
	}
	else
	{
		PCF8563_GetTimer();		//更新時間
		cmd_printf("[時間設置成功]:%02d:%02d:%02drn",ext_timer.hour,?ext_timer.min,?ext_timer.sec);
	}
	
}?


//設置日期
void?CMD_ExtSetDate(char?*pStr)
{
	u16?year;
	u8?month,?date;
	u8?len;
	char?*p;
	u8?num;
	
	len?=?strlen(pStr);	//獲取長度
	if(isStrNumAndSpc(pStr,?len,?2)?==?FALSE)
	{
		cmd_printf("[日期設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	//年
	p?=?strstr(pStr,"?");	//搜索空格
	if(p?==?NULL)
	{
		cmd_printf("[日期設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	num?=?p?-?pStr;
	if((num?>?4)?||?(num?==?0))
	{
		cmd_printf("[日期設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	year?=?CMD_StringToDec(pStr,?num);
	if(year>9999)
	{
		cmd_printf("[日期設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	
	//月
	pStr?=?p+1;
	p?=?strstr(pStr,"?");	//搜索空格
	if(p?==?NULL)
	{
		cmd_printf("[日期設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	num?=?p?-?pStr;
	if((num?>?2)?||?(num?==?0))
	{
		cmd_printf("[日期設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	month?=?CMD_StringToDec(pStr,?num);
	if(month>12)
	{
		cmd_printf("[日期設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	//日
	pStr?=?p+1;
	num?=?strlen(pStr);
	if((num?>?2)?||?(num?==?0))
	{
		cmd_printf("[日期設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	date?=?CMD_StringToDec(pStr,?num);
	if(date>31)
	{
		cmd_printf("[日期設置錯誤]:格式不對或非法參數!rn");
		return;
	}
	
	PCF8563_GetTimer();		//更新時間
	if(PCF8563_SetTimer(year,?month,?date,?ext_timer.hour,?ext_timer.min,?ext_timer.sec)?==?FALSE)
	{
		PCF8563_GetTimer();		//更新時間
		cmd_printf("[日期設置失敗]:%04d-%02d-%02drn",ext_timer.year,?ext_timer.month,?ext_timer.date);
	}
	else
	{
		PCF8563_GetTimer();		//更新時間
		cmd_printf("[日期設置成功]:%04d-%02d-%02drn",ext_timer.year,?ext_timer.month,?ext_timer.date);
	}
	
}?


#endif?//SYS_CMD_EN_


//,H文件


/*************************************************************************************************************
?*?文件名:			PCF8563.h
?*?功能:			STM32?PCF8563?高精度?RTC?芯片驅動
?*?作者:			cp1300@139.com
?*?創(chuàng)建時間:		2017-07-10
?*?最后修改時間:	2017-07-10
?*?詳細:			使用軟件IIC接口驅動
*************************************************************************************************************/
#ifndef?_PCF8563_H_
#define?_PCF8563_H_

#include?"system.h"

#if(BOARD_SUPPORT)	//需要板級支持
#include?"board.h"?
#else	//默認支持

#endif


//時間結構體
typedef??struct?
{
	u8	hour;?		//小時
	u8	min;	?	//分鐘
	u8	sec;		//秒			
	u8??month;		//月
	u8??date;		//日
	u8??week;		//星期
	u16?year;	?	//年
}rtc_timer;
extern?rtc_timer?ext_timer;	//外部RTC時鐘


//PCF8563?寄存器
typedef?enum
{
	PCF8563_REG_CONTROL1			=	0x00,	//控制寄存器1
	PCF8563_REG_CONTROL2			=	0x01,	//控制寄存器2
	PCF8563_REG_SECONDS				=	0x02,	//秒?seconds?00?to?59?coded?in?BCD
	PCF8563_REG_MINUTES				=	0x03,	//分?minutes?00?to?59?coded?in?BCD
	PCF8563_REG_HOURS				=	0x04,	//小時?hours?00?to?23?coded?in?BCD
	PCF8563_REG_DAYS				=	0x05,	//日?days?01?to?31?coded?in?BCD
	PCF8563_REG_WEEK				=	0x06,	//星期?weekdays?0?to?6?in?BCD
	PCF8563_REG_MONTHS				=	0x07,	//月份?months?01?to?12?coded?in?BCD
	PCF8563_REG_YEARS				=	0x08,	//年份?years?00?to?99?coded?in?BCD
	PCF8563_REG_ALARM_MINUTE		=	0x09,	//鬧鐘,分鐘?minute?alarm?00?to?59?coded?in?BCD
	PCF8563_REG_ALARM_HOUR			=	0x0A,	//鬧鐘,小時?hour?alarm?00?to?23?coded?in?BCD
	PCF8563_REG_ALARM_DAY			=	0x0B,	//鬧鐘,日?day?alarm?01?to?31?coded?in?BCD
	PCF8563_REG_ALARM_WEEK			=	0x0C,	//鬧鐘,星期?weekday?alarm?0?to?6?in?BCD
	PCF8563_REG_CLKOUT				=	0x0D,	//時鐘輸出設置
	PCF8563_REG_TIME_CONTROL		=	0x0E,	//定時器設置
	PCF8563_REG_TIME				=	0x0F,	//定時器倒計數值
}PCF8563_REG_TYPE;


bool?PCF8563_Init(void);													//PCF8563初始化
bool?PCF8563_SetTimer(u16?year,u8?month,u8?date,u8?hour,u8?min,u8?sec);		//PCF8563時間設置
bool?PCF8563_GetTimer(void);												//更新時間

u32?PCF8563_TimeToSec(u16?syear,u8?smon,u8?sday,u8?hour,u8?min,u8?sec);		//時間轉換為秒,注意:不可重入,請注意調用沖突


//使能系統命令行
#if?SYS_CMD_EN_
#include?"cmd.h"
#include?"string.h"



extern?const?CMD_TYPE??CMD_GET_ExtTIME;
extern?const?CMD_TYPE??CMD_GET_ExtDATE;
extern?const?CMD_TYPE??CMD_SET_ExtTIME;
extern?const?CMD_TYPE??CMD_SET_ExtDATE;


//獲取時間
void?CMD_ExtGetTime(char?*pStr);
//獲取日期
void?CMD_ExtGetDate(char?*pStr);
//設置時間
void?CMD_ExtSetTime(char?*pStr);
//設置日期
void?CMD_ExtSetDate(char?*pStr);

#endif?//SYS_CMD_EN_

#endif?/*_PCF8563_H_*/



本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯系該專欄作者,如若文章內容侵犯您的權益,請及時聯系本站刪除。
換一批
延伸閱讀

在嵌入式開發(fā)中,STM32的時鐘系統因其靈活性和復雜性成為開發(fā)者關注的焦點。然而,看似簡單的時鐘配置背后,隱藏著諸多易被忽視的陷阱,輕則導致系統不穩(wěn)定,重則引發(fā)硬件損壞。本文從時鐘源選擇、PLL配置、總線時鐘分配等關鍵環(huán)...

關鍵字: STM32 時鐘系統

在嵌入式系統開發(fā)中,STM32系列微控制器的內部溫度傳感器因其低成本、高集成度特性,廣泛應用于設備自檢、環(huán)境監(jiān)測等場景。然而,受芯片工藝差異和電源噪聲影響,其原始數據存在±1.5℃的固有誤差。本文從硬件配置、校準算法、軟...

關鍵字: STM32 溫度傳感器

在能源效率與智能化需求雙重驅動下,AC-DC轉換器的數字控制技術正經歷從傳統模擬方案向全數字架構的深刻變革?;赟TM32微控制器的PFM(脈沖頻率調制)+PWM(脈沖寬度調制)混合調制策略,結合動態(tài)電壓調整(Dynam...

關鍵字: AC-DC STM32

當前智能家居產品需求不斷增長 ,在這一背景下 ,對現有澆花裝置缺陷進行了改進 ,設計出基于STM32單片機的全 自動家用澆花機器人。該設計主要由機械結構和控制系統構成 ,機械結構通過麥克納姆輪底盤與噴灑裝置的結合實現機器...

關鍵字: STM32 麥克納姆輪 安全可靠 通過性強

用c++編程似乎是讓你的Arduino項目起步的障礙嗎?您想要一種更直觀的微控制器編程方式嗎?那你需要了解一下Visuino!這個圖形化編程平臺將復雜電子項目的創(chuàng)建變成了拖動和連接塊的簡單任務。在本文中,我們將帶您完成使...

關鍵字: Visuino Arduino ESP32 STM32

基于STM32與LoRa技術的無線傳感網絡憑借其低功耗、廣覆蓋、抗干擾等特性,成為環(huán)境監(jiān)測、工業(yè)自動化等場景的核心解決方案。然而,如何在復雜電磁環(huán)境中實現高效休眠調度與動態(tài)信道優(yōu)化,成為提升網絡能效與可靠性的關鍵挑戰(zhàn)。本...

關鍵字: STM32 LoRa

在實時控制系統、高速通信協議處理及高精度數據采集等對時間敏感的應用場景中,中斷響應延遲的優(yōu)化直接決定了系統的可靠性與性能上限。STM32系列微控制器憑借其靈活的嵌套向量中斷控制器(NVIC)、多通道直接內存訪問(DMA)...

關鍵字: STM32 DMA

數字電源技術向高功率密度、高效率與高動態(tài)響應方向加速演進,STM32微控制器憑借其基于DSP庫的算法加速能力與對LLC諧振變換器的精準控制架構,成為優(yōu)化電源動態(tài)性能的核心平臺。相較于傳統模擬控制或通用型數字控制器,STM...

關鍵字: STM32 數字電源

STM32微控制器憑借其針對電機控制場景的深度優(yōu)化,成為高精度、高可靠性驅動系統的核心選擇。相較于通用型MCU,STM32在電機控制領域的核心優(yōu)勢集中體現在FOC(磁場定向控制)算法的硬件加速引擎與PWM死區(qū)時間的動態(tài)補...

關鍵字: STM32 電機控制

無線充電技術加速滲透消費電子與汽車電子領域,基于Qi協議的無線充電發(fā)射端開發(fā)成為智能設備能量補給的核心課題。傳統模擬控制方案存在響應滯后、參數調整困難等問題,而基于STM32的數字PID控制結合FOD(Foreign O...

關鍵字: STM32 無線充電
關閉