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

當(dāng)前位置:首頁 > > 充電吧
[導(dǎo)讀]STM32F4裸機(jī)RTC驅(qū)動(dòng),寄存器操作。/******************************************************************************

STM32F4裸機(jī)RTC驅(qū)動(dòng),寄存器操作。


/*************************************************************************************************************
?*?文件名		:	RTC.c
?*?功能			:	STM32F4?RTC驅(qū)動(dòng)
?*?作者			:	cp1300@139.com
?*?創(chuàng)建時(shí)間		:	2017-07-01
?*?最后修改時(shí)間	:	2017-07-01
?*?詳細(xì):			要正確讀取?RTC?日歷寄存器(RTC_SSR、RTC_TR?和?RTC_DR),APB1?時(shí)鐘頻率?(fPCLK1)?必須等于或大于?fRTCCLK?RTC?時(shí)鐘頻率的七倍。這可以確保同步機(jī)制行為的安全性。
					如果?APB1?時(shí)鐘頻率低于?RTC?時(shí)鐘頻率的七倍,則軟件必須分兩次讀取日歷時(shí)間寄存器和?日期寄存器。這樣,當(dāng)兩次讀取的?RTC_TR?結(jié)果相同時(shí),才能確保數(shù)據(jù)正確。
					否則必須執(zhí)?行第三次讀訪問。任何情況下,APB1?的時(shí)鐘頻率都不能低于?RTC?的時(shí)鐘頻率。
					RTC->BKP0R:用于標(biāo)示是否進(jìn)行了初始化RTC,請(qǐng)不要再使用了。
					注意:初始化時(shí)會(huì)使用調(diào)試串口打印信息
					2017-01-15:修改全局時(shí)間結(jié)構(gòu)體名稱為g_timer,并且增加系統(tǒng)命令支持
*************************************************************************************************************/	
#include?"rtc.h"
#include?"system.h"?

volatile?tm?g_timer;								//全局系統(tǒng)時(shí)鐘

//秒中斷回調(diào)函數(shù)
static?void?(*RTC_SerIntCallBack)(void)?;			//秒中斷回調(diào)函數(shù)

//內(nèi)部函數(shù)申明
u8?RTC_GetWeek(u16?year,u8?month,u8?day);		//獲取2000-2099年之間的日期對(duì)應(yīng)的星期
u32?RTC_DECtoBCD(?u8?DEC);						//將數(shù)字轉(zhuǎn)換為壓縮BCD格式,最大支持99
u32?RTC_BCDtoDEC(u8?BCD);						//將壓縮BCD轉(zhuǎn)為DEC,最大支持99

/*************************************************************************************************************************
*?函數(shù)			:	bool?RTC_WaitSynchro(void)
*?功能			:	等待RSF同步
*?參數(shù)			:	無
*?返回			:	TRUE:成功,FALSE:失敗
*?依賴			:	底層宏定義
*?作者			:	cp1300@139.com
*?時(shí)間			:	2017-07-01
*?最后修改時(shí)間?	:?	2017-07-01
*?說明			:?	
*************************************************************************************************************************/
bool?RTC_WaitSynchro(void)
{?
	u32?retry=0XFFFFF;?
	
	//執(zhí)行以下步驟解鎖RTC寄存器寫保護(hù)
	RTC->WPR?=?0xCA;						//寫入KEY后關(guān)閉RTC寄存器寫保護(hù)
	RTC->WPR?=?0x53;?
	
	RTC->ISR?&=?~(1<ISR&(1<WPR=?0xff;							//隨便寫入一個(gè)值(不是KEY)使能RTC寄存器寫保護(hù)?
	
	return?TRUE;
}




/*************************************************************************************************************************
*?函數(shù)			:	bool?RTC_InitMode(void)
*?功能			:	RTC進(jìn)入初始化模式
*?參數(shù)			:	無
*?返回			:	TRUE:成功,FALSE:失敗
*?依賴			:	底層宏定義
*?作者			:	cp1300@139.com
*?時(shí)間			:	2017-07-01
*?最后修改時(shí)間?	:?	2017-07-01
*?說明			:?	
*************************************************************************************************************************/
bool?RTC_InitMode(void)
{?
	u32?retry=0X10000;?
		
	if(RTC->ISR?&?(1<ISR?|=?1<ISR&(1<WPR?=?0xCA;						//寫入KEY后關(guān)閉RTC寄存器寫保護(hù)
	RTC->WPR?=?0x53;?
	if(RTC_InitMode()?==?FALSE)return?FALSE;//進(jìn)入RTC初始化模式失敗
	temp?=?(u32)RTC_DECtoBCD(hour)?<<?16;	//小時(shí)
	temp?|=?(u32)RTC_DECtoBCD(min)?<<?8;	//分鐘
	temp?|=?(u32)RTC_DECtoBCD(sec)?<<?0;	//秒鐘
	
	RTC->TR=temp;							//設(shè)置時(shí)間
	RTC->ISR&=~(1<WPR?=?0xFF;						//開啟寫保護(hù)
	
	return?TRUE;?
}


/*************************************************************************************************************************
*?函數(shù)			:	bool?RTC_SetDate(u16?year,u8?month,u8?date)
*?功能			:	RTC日期設(shè)置
*?參數(shù)			:	year,month,date:年(2000~2099),月(1~12),日(1~31)
*?返回			:	TRUE:成功,FALSE:失敗
*?依賴			:	底層宏定義
*?作者			:	cp1300@139.com
*?時(shí)間			:	2017-07-01
*?最后修改時(shí)間?	:?	2017-07-01
*?說明			:?	會(huì)自動(dòng)退出寫保護(hù)
*************************************************************************************************************************/
bool?RTC_SetDate(u16?year,u8?month,u8?date)
{
	u32?temp;
	u8?week;
	
	//執(zhí)行以下步驟解鎖RTC寄存器寫保護(hù)
	RTC->WPR?=?0xCA;						//寫入KEY后關(guān)閉RTC寄存器寫保護(hù)
	RTC->WPR?=?0x53;?
	if(RTC_InitMode()?==?FALSE)return?FALSE;//進(jìn)入RTC初始化模式失敗
	if(year?<?2000)?year?=?2000;			//限制年
	if(year?>?2099)?year?=?2099;			//限制年
	if(month?<?1)?month?=?1;				//限制月
	if(month?>?12)?month?=?12;				//限制月
	if(date?<?1)?date?=?1;					//限制日
	if(date?>?31)?date?=?31;				//限制日
	week?=?RTC_GetWeek(year,month,date);	//計(jì)算設(shè)置的日期對(duì)應(yīng)的星期
	year?-=?2000;							//年轉(zhuǎn)換為0-99
	
	temp?=?(u32)RTC_DECtoBCD(year)<<16;		//年
	temp?|=?week<<13;						//星期
	temp?|=?(u32)RTC_DECtoBCD(month)<<8;	//月份
	temp?|=?(u32)RTC_DECtoBCD(date)<DR=temp;							//寫入
	RTC->ISR&=~(1<WPR?=?0xFF;						//開啟寫保護(hù)
	
	return?TRUE;?
}


/*************************************************************************************************************************
*?函數(shù)			:	bool?RTC_GetTime(u8?*hour,u8?*min,u8?*sec)
*?功能			:	獲取RTC時(shí)間
*?參數(shù)			:	*hour,*min,*sec:小時(shí),分鐘,秒鐘?
*?返回			:	TRUE:成功,FALSE:失敗
*?依賴			:	底層宏定義
*?作者			:	cp1300@139.com
*?時(shí)間			:	2017-07-01
*?最后修改時(shí)間?	:?	2017-07-01
*?說明			:?	24小時(shí)制
*************************************************************************************************************************/
bool?RTC_GetTime(u8?*hour,u8?*min,u8?*sec)
{
	u32?temp;
	u32?retry?=?5250*3;
	u8?ampm;
	
?	while((RTC_WaitSynchro()?==?FALSE)?&&?(retry!=0))	//等待同步??	?
	{
		nop;nop;nop;nop;nop;nop;
		retry?--;
	}
	if(retry==0)?return?FALSE;
	
	temp=RTC->TR;
	*hour=RTC_BCDtoDEC((temp>>16)&0X3F);
	*min=RTC_BCDtoDEC((temp>>8)&0X7F);
	*sec=RTC_BCDtoDEC(temp&0X7F);
	
	ampm=temp>>22;?
	if(ampm!=0)	//使用的是12小時(shí)制,并且是下午,則小時(shí)加上12小時(shí)
	{
		*hour?+=?12;
	}
	
	return?TRUE;
}


/*************************************************************************************************************************
*?函數(shù)			:	bool?RTC_GetDate(u16?*year,u8?*month,u8?*date,u8?*week)
*?功能			:	獲取RTC日期
*?參數(shù)			:	*year,*mon,*date:年,月,日;*week:星期
*?返回			:	TRUE:成功,FALSE:失敗
*?依賴			:	底層宏定義
*?作者			:	cp1300@139.com
*?時(shí)間			:	2017-07-01
*?最后修改時(shí)間?	:?	2017-07-01
*?說明			:?	
*************************************************************************************************************************/
bool?RTC_GetDate(u16?*year,u8?*month,u8?*date,u8?*week)
{
	u32?retry?=?5250*3;
	u32?temp;
	
?	while((RTC_WaitSynchro()?==?FALSE)?&&?(retry!=0))	//等待同步??	?
	{
		nop;nop;nop;nop;nop;nop;
		retry?--;
	}
	if(retry==0)?return?FALSE;	?
	temp=RTC->DR;
	*year=RTC_BCDtoDEC((temp>>16)&0XFF)+2000;
	*month=RTC_BCDtoDEC((temp>>8)&0X1F);
	*date=RTC_BCDtoDEC(temp&0X3F);
	*week=(temp>>13)&0X07;?
	
	return?TRUE;
}


/*************************************************************************************************************************
*?函數(shù)			:	bool?RTC_Get(void)
*?功能			:	更新RTC時(shí)間
*?參數(shù)			:	無
*?返回			:	TRUE:成功,FALSE:失敗
*?依賴			:	底層宏定義
*?作者			:	cp1300@139.com
*?時(shí)間			:	2017-07-01
*?最后修改時(shí)間?	:?	2017-07-01
*?說明			:?	APB時(shí)鐘必須大于RTC時(shí)鐘7倍,通常會(huì)遠(yuǎn)大于,一般APB少說也得1MHZ以上
					時(shí)間寫入到了全局緩沖區(qū)?timer?中
*************************************************************************************************************************/
bool?RTC_Get(void)
{
	u32?temp;
	u32?retry?=?5250*3;
	u8?ampm;
	
?	while((RTC_WaitSynchro()?==?FALSE)?&&?(retry!=0))	//等待同步??	?
	{
		nop;nop;nop;nop;nop;nop;
		retry?--;
	}
	if(retry==0)?return?FALSE;
	//獲取日期
	temp=RTC->DR;
	g_timer.year=RTC_BCDtoDEC((temp>>16)&0XFF)+2000;
	g_timer.month=RTC_BCDtoDEC((temp>>8)&0X1F);
	g_timer.date=RTC_BCDtoDEC(temp&0X3F);
	g_timer.week=(temp>>13)&0X07;?
	//獲取時(shí)間
	temp=RTC->TR;
	g_timer.hour=RTC_BCDtoDEC((temp>>16)&0X3F);
	g_timer.min=RTC_BCDtoDEC((temp>>8)&0X7F);
	g_timer.sec=RTC_BCDtoDEC(temp&0X7F);
	
	ampm=temp>>22;?
	if(ampm!=0)	//使用的是12小時(shí)制,并且是下午,則小時(shí)加上12小時(shí)
	{
		g_timer.hour?+=?12;
	}
	
	return?TRUE;
}


/*************************************************************************************************************************
*?函數(shù)			:	bool?RTC_SetWakeUp(bool?isEnableInt,?u16?WakeSecs)
*?功能			:	RTC喚醒中斷設(shè)置
*?參數(shù)			:	isEnableInt:是否開啟喚醒中斷;WakeSecs:喚醒周期,單位秒
*?返回			:	TRUE:開啟成功;FALSE:開啟失敗
*?依賴			:	底層宏定義
*?作者			:	cp1300@139.com
*?時(shí)間			:	2017-07-02
*?最后修改時(shí)間?	:?	2017-07-02
*?說明			:?	
*************************************************************************************************************************/
bool?RTC_SetWakeUp(bool?isEnableInt,?u16?WakeSecs)
{
	u32?temp?=?RTC->CR;
	u32?retry?=?500;
	
	//關(guān)閉RTC寄存器寫保護(hù)
	RTC->WPR=0xCA;
	RTC->WPR=0x53;?
	if(WakeSecs==0)?WakeSecs?=?1;		//最少1秒	
	temp?|=?1<<10;						//喚醒定時(shí)器使能	
	if(isEnableInt)	//需要開啟喚醒中斷
	{			
		temp?|=?1<<14;					//使能喚醒定時(shí)器中斷	
		SYS_EXTI_SetEdge(EXTI_RTC_WAKE_UP,?EXTI_POS_EDGE);	//設(shè)置RTC喚醒中斷上升沿觸發(fā)
		SYS_EXTI_IntEnable(EXTI_RTC_WAKE_UP,?TRUE);			//RTC喚醒中斷EXTI開關(guān)
		SYS_EXTI_ClearInt(EXTI_RTC_WAKE_UP);				//清除中斷標(biāo)記
		SYS_NVIC_IntEnable(IRQ_RTC_WKUP,?TRUE);				//RTC喚醒中斷?NVIC全局中斷使能
	}
	else
	{	
		temp?&=?~(1<ISR?&=?~(1<WUTR?!=?(WakeSecs-1))
	{
		//在?RTC_CR?寄存器中的?WUTE?位置?0?后,當(dāng)喚醒定時(shí)器值可更改時(shí),由硬件將該位置?1。
		//僅當(dāng)?RTC_ISR?中的?WUTWF?置?1?時(shí)才可對(duì)該寄存器執(zhí)行寫操作。
		RTC->CR?&=?~(1<ISR?&?(1?<<?2))?==?0)?&&?retry)
		{
			Delay_US(1);
			retry?--;
		}
		if(retry==0)
		{
			uart_printf("設(shè)置RTC喚醒定時(shí)器失敗!");
			return?FALSE;
		}
		
		RTC->WUTR?=?WakeSecs-1;				//重新設(shè)置喚醒自動(dòng)重載值
	}
	
	RTC->CR?=?temp;						//設(shè)置配置寄存器
	
	RTC->WPR=0xFF;						//開啟寫保護(hù)
	
	return?TRUE;
}

/*************************************************************************************************************************
*?函數(shù)			:	bool?RTC_Init(bool?SerIntEnable)
*?功能			:	RTC初始化
*?參數(shù)			:	SerIntEnable:TRUE:開啟秒中斷;FALSE:關(guān)閉秒中斷
*?返回			:	TRUE:成功,FALSE:失敗
*?依賴			:	底層宏定義
*?作者			:	cp1300@139.com
*?時(shí)間			:	2017-07-01
*?最后修改時(shí)間?	:?	2017-07-01
*?說明			:?	使用備份區(qū)0存放標(biāo)志來區(qū)別是否進(jìn)行過初始化?RTC->BKP0R=0x5A5AA5A5
*************************************************************************************************************************/
bool?RTC_Init(bool?SerIntEnable)
{
	u32?retry=0XFFFFFFF;?
	
	RCC->APB1ENR|=1<CR|=1<BKP0R?!=?0x5A5AA5A5)	//沒有進(jìn)行過配置
	{
		info_printf("RTC沒有初始化,開始初始化...rn");
		RCC->BDCR|=1<BDCR&0X02)==0))//等待LSE準(zhǔn)備好
		{
			retry--;
			nop;nop;nop;
		}
		if(retry==0)
		{
			info_printf("RTC時(shí)鐘初始化失敗了!rn");
			return?FALSE;		//LSE?開啟失敗.
		}
			?
		RCC->BDCR|=1<BDCR|=1<WPR=0xCA;
		RTC->WPR=0x53;?
		if(RTC_InitMode()?==?FALSE)//進(jìn)入RTC初始化模式
		{
			info_printf("RTC進(jìn)入初始化模式失敗了!rn");
			return?FALSE;			
		}
		//將32768?進(jìn)行128x256分頻?得到1秒的?ck_spre頻率,用于產(chǎn)生秒喚醒中斷
		RTC->PRER=255;				//RTC同步分頻系數(shù)(0~7FFF),必須先設(shè)置同步分頻,再設(shè)置異步分頻,Frtc=Fclks/((Sprec+1)*(Asprec+1))
		RTC->PRER|=127<CR&=~(1<ISR&=~(1<WPR=0xFF;				//使能RTC寄存器寫保護(hù)??
		RTC_SetTime(6,6,6);			//設(shè)置初始時(shí)間
		RTC_SetDate(2017,6,6);		//設(shè)置初始日期
		RTC->BKP0R?=?0x5A5AA5A5;	//寫入備份區(qū)標(biāo)記,標(biāo)示已經(jīng)初始化過RTC
		
		
		info_printf("初始化RTC成功!rn");
		
		//RTC_Set_AlarmA(7,0,0,10);	//設(shè)置鬧鐘時(shí)間
	}?
	//RTC_Set_WakeUp(4,0);			
	if(RTC_Get()==FALSE)			//更新一次時(shí)間
	{
		info_printf("初始獲取時(shí)間失?。n");
	}
	RTC_SetWakeUp(SerIntEnable,?1);//配置WAKE?UP中斷,1秒鐘中斷一次?
	
	return?TRUE;
}

//設(shè)置秒中斷回調(diào)函數(shù)
void?RTC_SetWkupCallBack(void?(*pCallBack)(void))
{
	RTC_SerIntCallBack?=?pCallBack;
}


//RTC鬧鐘中斷服務(wù)函數(shù)
void?RTC_Alarm_IRQHandler(void)
{????
	if(RTC->ISR&(1<ISR&=~(1<PR|=1<ISR&(1<ISR&=~(1<19)yearL+=100;
	//?所過閏年數(shù)只算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;
}	




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







//使能系統(tǒng)命令行
#if?SYS_CMD_EN_
#include?"sys_cmd.h"
#include?"string.h"

const?SYS_CMD_TYPE??CMD_GET_TIME		=	{"TIME?",?CMD_GetTime,?"tt獲取系統(tǒng)時(shí)間",?TRUE};
const?SYS_CMD_TYPE??CMD_GET_DATE		=	{"DATE?",?CMD_GetDate,?"tt獲取系統(tǒng)日期",?TRUE};
const?SYS_CMD_TYPE??CMD_SET_TIME		=	{"TIME=",?CMD_SetTime,?"tt設(shè)置系統(tǒng)時(shí)間?如(12:32:54):TIME=12?32?54",?TRUE};
const?SYS_CMD_TYPE??CMD_SET_DATE		=	{"DATE=",?CMD_SetDate,?"tt設(shè)置系統(tǒng)日期?如(2014?6?8):TIME=2014?6?8",?TRUE};

//獲取時(shí)間
void?CMD_GetTime(SYS_CMD_HANDLE?*pHandle,char?*pStr)
{
	RTC_Get();		//更新時(shí)間
	pHandle->DataPrintf("[獲取時(shí)間成功]:%02d:%02d:%02drn",g_timer.hour,?g_timer.min,?g_timer.sec);
}

//獲取日期
void?CMD_GetDate(SYS_CMD_HANDLE?*pHandle,char?*pStr)
{
	RTC_Get();		//更新時(shí)間
	pHandle->DataPrintf("[獲取日期成功]:%04d-%02d-%02drn",g_timer.year,?g_timer.month,?g_timer.date);
}

//設(shè)置時(shí)間
void?CMD_SetTime(SYS_CMD_HANDLE?*pHandle,char?*pStr)
{
	u8?hour,min,sec;
	u8?len;
	char?*p;
	u8?num;
	
	len?=?strlen(pStr);	//獲取長度
	if(isStrNumAndSpc(pStr,?len,?2)?==?FALSE)
	{
		pHandle->DataPrintf("[時(shí)間設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	//小時(shí)
	p?=?strstr(pStr,"?");	//搜索空格
	if(p?==?NULL)
	{
		pHandle->DataPrintf("[時(shí)間設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	num?=?p?-?pStr;
	if((num?>?2)?||?(num?==?0))
	{
		pHandle->DataPrintf("[時(shí)間設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	hour?=?SYS_CMD_StringToDec(pStr,?num);
	if(hour>23)
	{
		pHandle->DataPrintf("[時(shí)間設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	
	//分鐘
	pStr?=?p+1;
	p?=?strstr(pStr,"?");	//搜索空格
	if(p?==?NULL)
	{
		pHandle->DataPrintf("[時(shí)間設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	num?=?p?-?pStr;
	if((num?>?2)?||?(num?==?0))
	{
		pHandle->DataPrintf("[時(shí)間設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	min?=?SYS_CMD_StringToDec(pStr,?num);
	if(min>59)
	{
		pHandle->DataPrintf("[時(shí)間設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	//秒鐘
	pStr?=?p+1;
	num?=?strlen(pStr);
	if((num?>?2)?||?(num?==?0))
	{
		pHandle->DataPrintf("[時(shí)間設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	sec?=?SYS_CMD_StringToDec(pStr,?num);
	if(sec>59)
	{
		pHandle->DataPrintf("[時(shí)間設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	
	if(RTC_SetTime(hour,?min,?sec)?==?FALSE)
	{
		RTC_Get();		//更新時(shí)間
		pHandle->DataPrintf("[時(shí)間設(shè)置失敗]:%02d:%02d:%02drn",g_timer.hour,?g_timer.min,?g_timer.sec);
	}
	else
	{
		RTC_Get();		//更新時(shí)間
		pHandle->DataPrintf("[時(shí)間設(shè)置成功]:%02d:%02d:%02drn",g_timer.hour,?g_timer.min,?g_timer.sec);
	}
	
}?


//設(shè)置日期
void?CMD_SetDate(SYS_CMD_HANDLE?*pHandle,char?*pStr)
{
	u16?year;
	u8?month,?date;
	u8?len;
	char?*p;
	u8?num;
	
	len?=?strlen(pStr);	//獲取長度
	if(isStrNumAndSpc(pStr,?len,?2)?==?FALSE)
	{
		pHandle->DataPrintf("[日期設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	//年
	p?=?strstr(pStr,"?");	//搜索空格
	if(p?==?NULL)
	{
		pHandle->DataPrintf("[日期設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	num?=?p?-?pStr;
	if((num?>?4)?||?(num?==?0))
	{
		pHandle->DataPrintf("[日期設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	year?=?SYS_CMD_StringToDec(pStr,?num);
	if(year>9999)
	{
		pHandle->DataPrintf("[日期設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	
	//月
	pStr?=?p+1;
	p?=?strstr(pStr,"?");	//搜索空格
	if(p?==?NULL)
	{
		pHandle->DataPrintf("[日期設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	num?=?p?-?pStr;
	if((num?>?2)?||?(num?==?0))
	{
		pHandle->DataPrintf("[日期設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	month?=?SYS_CMD_StringToDec(pStr,?num);
	if(month>12)
	{
		pHandle->DataPrintf("[日期設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	//日
	pStr?=?p+1;
	num?=?strlen(pStr);
	if((num?>?2)?||?(num?==?0))
	{
		pHandle->DataPrintf("[日期設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	date?=?SYS_CMD_StringToDec(pStr,?num);
	if(date>31)
	{
		pHandle->DataPrintf("[日期設(shè)置錯(cuò)誤]:格式不對(duì)或非法參數(shù)!rn");
		return;
	}
	

	if(RTC_SetDate(year,?month,?date)?==?FALSE)
	{
		RTC_Get();		//更新時(shí)間
		pHandle->DataPrintf("[日期設(shè)置失敗]:%04d-%02d-%02drn",g_timer.year,?g_timer.month,?g_timer.date);
	}
	else
	{
		RTC_Get();		//更新時(shí)間
		pHandle->DataPrintf("[日期設(shè)置成功]:%04d-%02d-%02drn",g_timer.year,?g_timer.month,?g_timer.date);
	}
	
}?


#endif?//SYS_CMD_EN_


/*************************************************************************************************************
?*?文件名		:	RTC.h
?*?功能			:	STM32F4?RTC驅(qū)動(dòng)
?*?作者			:	cp1300@139.com
?*?創(chuàng)建時(shí)間		:	2017-07-01
?*?最后修改時(shí)間	:	2017-07-01
?*?詳細(xì):			要正確讀取?RTC?日歷寄存器(RTC_SSR、RTC_TR?和?RTC_DR),APB1?時(shí)鐘頻率?(fPCLK1)?必須等于或大于?fRTCCLK?RTC?時(shí)鐘頻率的七倍。這可以確保同步機(jī)制行為的安全性。
					如果?APB1?時(shí)鐘頻率低于?RTC?時(shí)鐘頻率的七倍,則軟件必須分兩次讀取日歷時(shí)間寄存器和?日期寄存器。這樣,當(dāng)兩次讀取的?RTC_TR?結(jié)果相同時(shí),才能確保數(shù)據(jù)正確。
					否則必須執(zhí)?行第三次讀訪問。任何情況下,APB1?的時(shí)鐘頻率都不能低于?RTC?的時(shí)鐘頻率。
					RTC->BKP0R:用于標(biāo)示是否進(jìn)行了初始化RTC,請(qǐng)不要再使用了。
*************************************************************************************************************/
#ifndef?__RTC_H_
#define?__RTC_H_
#include?"system.h"?


//時(shí)間結(jié)構(gòu)體
typedef??struct?
{
	u8	hour;?		//小時(shí)
	u8	min;	?	//分鐘
	u8	sec;		//秒			
	u8??month;		//月
	u8??date;		//日
	u8??week;		//星期
	u16?year;	?	//年
}tm;
extern?volatile?tm?g_timer;



//函數(shù)接口
bool?RTC_SetTime(u8?hour,u8?min,u8?sec);	//RTC時(shí)間設(shè)置
bool?RTC_SetDate(u16?year,u8?month,u8?date);//RTC日期設(shè)置
bool?RTC_GetTime(u8?*hour,u8?*min,u8?*sec);	//獲取RTC時(shí)間
bool?RTC_GetDate(u16?*year,u8?*month,u8?*date,u8?*week);//獲取RTC日期
bool?RTC_Get(void);							//更新RTC時(shí)間
bool?RTC_Init(bool?SerIntEnable);			//RTC初始化
bool?RTC_SetWakeUp(bool?isEnableInt,?u16?WakeSecs);	//RTC喚醒中斷設(shè)置
void?RTC_SetWkupCallBack(void?(*pCallBack)(void));//設(shè)置秒中斷回調(diào)函數(shù)



//使能系統(tǒng)命令行
#if?SYS_CMD_EN_
#include?"sys_cmd.h"
#include?"string.h"

extern?const?SYS_CMD_TYPE??CMD_GET_TIME;
extern?const?SYS_CMD_TYPE??CMD_GET_DATE;
extern?const?SYS_CMD_TYPE??CMD_SET_TIME;
extern?const?SYS_CMD_TYPE??CMD_SET_DATE;


//獲取時(shí)間
void?CMD_GetTime(SYS_CMD_HANDLE?*pHandle,char?*pStr);
//獲取日期
void?CMD_GetDate(SYS_CMD_HANDLE?*pHandle,char?*pStr);
//設(shè)置時(shí)間
void?CMD_SetTime(SYS_CMD_HANDLE?*pHandle,char?*pStr);
//設(shè)置日期
void?CMD_SetDate(SYS_CMD_HANDLE?*pHandle,char?*pStr);

#endif?//SYS_CMD_EN_




#endif?//__RTC_H_


使用時(shí)需要一個(gè)秒中斷回調(diào)函數(shù),比如我的秒中斷是用來喚醒一個(gè)線程,處理秒任務(wù)


RTC_Init(TRUE);




//任務(wù)2:負(fù)責(zé)后臺(tái)(RTC?1秒喚醒一次)
void?TaskBack(void?*pdata)
{
	RTC_SetWkupCallBack(RTC_WkupCallBack);					//設(shè)置RTC回調(diào)函數(shù)
	
	while(1)
	{
		RTC_Get();											//更新系統(tǒng)時(shí)間
		uart_printf("%04d-%02d-%02d?%02d:%02d:%02drn",g_timer.year,g_timer.month,g_timer.date,g_timer.hour,g_timer.min,g_timer.sec);
		OSTimeDlyHMSM(0,0,0,100);
		IWDG_Feed();

		OSTaskSuspend(BACK_TASK_Prio);						//掛起后臺(tái)進(jìn)程
	}
}
//RTC秒中斷回調(diào)函數(shù)
void?RTC_WkupCallBack(void)
{
	OSTaskResume(BACK_TASK_Prio);						//喚醒后臺(tái)進(jìn)程
}




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

基于ARM? Cortex?-M4的STM32F4 MCU系列采用了意法半導(dǎo)體的NVM工藝和ART Accelerator?,在高達(dá)180 MHz的工作頻率下通過閃存執(zhí)行時(shí)其處理性能達(dá)到225 DMIPS/608 Cor...

關(guān)鍵字: stm32f4 ARM

stm32f4和f1都有哪些區(qū)別?除了需要的頭文件不一樣,管腳配置什么的有區(qū)別么?

關(guān)鍵字: stm32f4 f1 比較

STM32F407VET6引腳圖及中文資料

關(guān)鍵字: stm32f4 引腳圖

  2016年2月26日,德國慕尼黑和西班牙巴塞羅那訊——贏得消費(fèi)者的信任對(duì)于智能移動(dòng)設(shè)備支付解決方案至關(guān)重要。作為全球最大的安全芯片供應(yīng)商之一,英飛凌科技股份公司(FS

關(guān)鍵字: rtc 機(jī)器人 rx8010sj

博主使用的是天嵌的開發(fā)板型號(hào)IMX6Q_coreC。1.發(fā)現(xiàn)使用開發(fā)板是時(shí)間總是被設(shè)置為2028年6月18日3時(shí)41分,一開始以為是底層驅(qū)動(dòng)的問題, 故去底層加打印信息調(diào)試。2.發(fā)現(xiàn)在系統(tǒng)內(nèi)hwclo

關(guān)鍵字: Linux rtc

比較F1的片子對(duì)于F4的RTC來說有很大提升,F(xiàn)4的RTC提供了日歷時(shí)鐘和兩個(gè)可編程鬧鐘中斷,一個(gè)周期性可編程喚醒標(biāo)志。這樣很方便設(shè)置系統(tǒng)時(shí)間,并不會(huì)像F1的RTC那樣要自己計(jì)算年月日時(shí)分秒。F4的RTC是一個(gè)獨(dú)立的BC...

關(guān)鍵字: rtc stm32f4

【實(shí)驗(yàn)?zāi)康摹枯敵?路占空比不同的PWM信號(hào)是各個(gè)版本ST庫必備的例子。本實(shí)驗(yàn)的主要目的不是表現(xiàn)ST芯片PWM功能的強(qiáng)大,而是要完成輸出的精確計(jì)算?!緦?shí)驗(yàn)內(nèi)容】輸出7路PWM信號(hào),并用示波器測(cè)量輸出?!緦?shí)驗(yàn)原理】1、時(shí)

關(guān)鍵字: pwm stm32f4 tim1 信號(hào)輸出

STM32F4的隨機(jī)數(shù)發(fā)生器RNG,以環(huán)境噪聲為種子,產(chǎn)生32位隨機(jī)數(shù)供主機(jī)使用?!局饕匦浴?、產(chǎn)生32位隨機(jī)數(shù) 2、兩次轉(zhuǎn)換時(shí)間間隔40PLL48CLK 3、隨機(jī)數(shù)熵檢測(cè)以發(fā)現(xiàn)不正常位,以產(chǎn)生穩(wěn)定序列 3、可被關(guān)閉以...

關(guān)鍵字: stm32f4 隨機(jī)數(shù)發(fā)生器

  RTC-Real Time Clock是430單片機(jī)的實(shí)時(shí)時(shí)鐘模塊,可以配置成實(shí)時(shí)時(shí)鐘模式(萬年歷)或者一般目的的32位計(jì)數(shù)器模式,其中實(shí)時(shí)時(shí)鐘模式提供了年月日、時(shí)分秒,可以選擇BCD碼或者二進(jìn)制格式,并且具有可編程...

關(guān)鍵字: MSP430 rtc 單片機(jī) 實(shí)時(shí)時(shí)鐘

STM32RTC使用步驟:打開PWR時(shí)鐘和Backup區(qū)數(shù)據(jù)訪問若使用外部低速時(shí)鐘(LSE),打開LSE并等待起振選擇和打開RTC時(shí)鐘,等待時(shí)鐘同步配置時(shí)間格式,分頻系數(shù)等根據(jù)需要配置時(shí)鐘,日期,鬧鐘,喚醒,輸出,時(shí)間戳...

關(guān)鍵字: rtc stm32f3 實(shí)時(shí)時(shí)鐘
關(guān)閉