当前位置:首页 > 芯闻号 > 充电吧
[导读]STM32F4裸机RTC驱动,寄存器操作。/******************************************************************************

STM32F4裸机RTC驱动,寄存器操作。


/*************************************************************************************************************
 * 文件名		:	RTC.c
 * 功能			:	STM32F4 RTC驱动
 * 作者			:	cp1300@139.com
 * 创建时间		:	2017-07-01
 * 最后修改时间	:	2017-07-01
 * 详细:			要正确读取 RTC 日历寄存器(RTC_SSR、RTC_TR 和 RTC_DR),APB1 时钟频率 (fPCLK1) 必须等于或大于 fRTCCLK RTC 时钟频率的七倍。这可以确保同步机制行为的安全性。
					如果 APB1 时钟频率低于 RTC 时钟频率的七倍,则软件必须分两次读取日历时间寄存器和 日期寄存器。这样,当两次读取的 RTC_TR 结果相同时,才能确保数据正确。
					否则必须执 行第三次读访问。任何情况下,APB1 的时钟频率都不能低于 RTC 的时钟频率。
					RTC->BKP0R:用于标示是否进行了初始化RTC,请不要再使用了。
					注意:初始化时会使用调试串口打印信息
					2017-01-15:修改全局时间结构体名称为g_timer,并且增加系统命令支持
*************************************************************************************************************/	
#include "rtc.h"
#include "system.h" 

volatile tm g_timer;								//全局系统时钟

//秒中断回调函数
static void (*RTC_SerIntCallBack)(void) ;			//秒中断回调函数

//内部函数申明
u8 RTC_GetWeek(u16 year,u8 month,u8 day);		//获取2000-2099年之间的日期对应的星期
u32 RTC_DECtoBCD( u8 DEC);						//将数字转换为压缩BCD格式,最大支持99
u32 RTC_BCDtoDEC(u8 BCD);						//将压缩BCD转为DEC,最大支持99

/*************************************************************************************************************************
* 函数			:	bool RTC_WaitSynchro(void)
* 功能			:	等待RSF同步
* 参数			:	无
* 返回			:	TRUE:成功,FALSE:失败
* 依赖			:	底层宏定义
* 作者			:	cp1300@139.com
* 时间			:	2017-07-01
* 最后修改时间 	: 	2017-07-01
* 说明			: 	
*************************************************************************************************************************/
bool RTC_WaitSynchro(void)
{ 
	u32 retry=0XFFFFF; 
	
	//执行以下步骤解锁RTC寄存器写保护
	RTC->WPR = 0xCA;						//写入KEY后关闭RTC寄存器写保护
	RTC->WPR = 0x53; 
	
	RTC->ISR &= ~(1<ISR&(1<WPR= 0xff;							//随便写入一个值(不是KEY)使能RTC寄存器写保护 
	
	return TRUE;
}




/*************************************************************************************************************************
* 函数			:	bool RTC_InitMode(void)
* 功能			:	RTC进入初始化模式
* 参数			:	无
* 返回			:	TRUE:成功,FALSE:失败
* 依赖			:	底层宏定义
* 作者			:	cp1300@139.com
* 时间			:	2017-07-01
* 最后修改时间 	: 	2017-07-01
* 说明			: 	
*************************************************************************************************************************/
bool RTC_InitMode(void)
{ 
	u32 retry=0X10000; 
		
	if(RTC->ISR & (1<ISR |= 1<ISR&(1<WPR = 0xCA;						//写入KEY后关闭RTC寄存器写保护
	RTC->WPR = 0x53; 
	if(RTC_InitMode() == FALSE)return FALSE;//进入RTC初始化模式失败
	temp = (u32)RTC_DECtoBCD(hour) << 16;	//小时
	temp |= (u32)RTC_DECtoBCD(min) << 8;	//分钟
	temp |= (u32)RTC_DECtoBCD(sec) << 0;	//秒钟
	
	RTC->TR=temp;							//设置时间
	RTC->ISR&=~(1<WPR = 0xFF;						//开启写保护
	
	return TRUE; 
}


/*************************************************************************************************************************
* 函数			:	bool RTC_SetDate(u16 year,u8 month,u8 date)
* 功能			:	RTC日期设置
* 参数			:	year,month,date:年(2000~2099),月(1~12),日(1~31)
* 返回			:	TRUE:成功,FALSE:失败
* 依赖			:	底层宏定义
* 作者			:	cp1300@139.com
* 时间			:	2017-07-01
* 最后修改时间 	: 	2017-07-01
* 说明			: 	会自动退出写保护
*************************************************************************************************************************/
bool RTC_SetDate(u16 year,u8 month,u8 date)
{
	u32 temp;
	u8 week;
	
	//执行以下步骤解锁RTC寄存器写保护
	RTC->WPR = 0xCA;						//写入KEY后关闭RTC寄存器写保护
	RTC->WPR = 0x53; 
	if(RTC_InitMode() == FALSE)return FALSE;//进入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);	//计算设置的日期对应的星期
	year -= 2000;							//年转换为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;						//开启写保护
	
	return TRUE; 
}


/*************************************************************************************************************************
* 函数			:	bool RTC_GetTime(u8 *hour,u8 *min,u8 *sec)
* 功能			:	获取RTC时间
* 参数			:	*hour,*min,*sec:小时,分钟,秒钟 
* 返回			:	TRUE:成功,FALSE:失败
* 依赖			:	底层宏定义
* 作者			:	cp1300@139.com
* 时间			:	2017-07-01
* 最后修改时间 	: 	2017-07-01
* 说明			: 	24小时制
*************************************************************************************************************************/
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小时制,并且是下午,则小时加上12小时
	{
		*hour += 12;
	}
	
	return TRUE;
}


/*************************************************************************************************************************
* 函数			:	bool RTC_GetDate(u16 *year,u8 *month,u8 *date,u8 *week)
* 功能			:	获取RTC日期
* 参数			:	*year,*mon,*date:年,月,日;*week:星期
* 返回			:	TRUE:成功,FALSE:失败
* 依赖			:	底层宏定义
* 作者			:	cp1300@139.com
* 时间			:	2017-07-01
* 最后修改时间 	: 	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;
}


/*************************************************************************************************************************
* 函数			:	bool RTC_Get(void)
* 功能			:	更新RTC时间
* 参数			:	无
* 返回			:	TRUE:成功,FALSE:失败
* 依赖			:	底层宏定义
* 作者			:	cp1300@139.com
* 时间			:	2017-07-01
* 最后修改时间 	: 	2017-07-01
* 说明			: 	APB时钟必须大于RTC时钟7倍,通常会远大于,一般APB少说也得1MHZ以上
					时间写入到了全局缓冲区 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; 
	//获取时间
	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小时制,并且是下午,则小时加上12小时
	{
		g_timer.hour += 12;
	}
	
	return TRUE;
}


/*************************************************************************************************************************
* 函数			:	bool RTC_SetWakeUp(bool isEnableInt, u16 WakeSecs)
* 功能			:	RTC唤醒中断设置
* 参数			:	isEnableInt:是否开启唤醒中断;WakeSecs:唤醒周期,单位秒
* 返回			:	TRUE:开启成功;FALSE:开启失败
* 依赖			:	底层宏定义
* 作者			:	cp1300@139.com
* 时间			:	2017-07-02
* 最后修改时间 	: 	2017-07-02
* 说明			: 	
*************************************************************************************************************************/
bool RTC_SetWakeUp(bool isEnableInt, u16 WakeSecs)
{
	u32 temp = RTC->CR;
	u32 retry = 500;
	
	//关闭RTC寄存器写保护
	RTC->WPR=0xCA;
	RTC->WPR=0x53; 
	if(WakeSecs==0) WakeSecs = 1;		//最少1秒	
	temp |= 1<<10;						//唤醒定时器使能	
	if(isEnableInt)	//需要开启唤醒中断
	{			
		temp |= 1<<14;					//使能唤醒定时器中断	
		SYS_EXTI_SetEdge(EXTI_RTC_WAKE_UP, EXTI_POS_EDGE);	//设置RTC唤醒中断上升沿触发
		SYS_EXTI_IntEnable(EXTI_RTC_WAKE_UP, TRUE);			//RTC唤醒中断EXTI开关
		SYS_EXTI_ClearInt(EXTI_RTC_WAKE_UP);				//清除中断标记
		SYS_NVIC_IntEnable(IRQ_RTC_WKUP, TRUE);				//RTC唤醒中断 NVIC全局中断使能
	}
	else
	{	
		temp &= ~(1<ISR &= ~(1<WUTR != (WakeSecs-1))
	{
		//在 RTC_CR 寄存器中的 WUTE 位置 0 后,当唤醒定时器值可更改时,由硬件将该位置 1。
		//仅当 RTC_ISR 中的 WUTWF 置 1 时才可对该寄存器执行写操作。
		RTC->CR &= ~(1<ISR & (1 << 2)) == 0) && retry)
		{
			Delay_US(1);
			retry --;
		}
		if(retry==0)
		{
			uart_printf("设置RTC唤醒定时器失败!");
			return FALSE;
		}
		
		RTC->WUTR = WakeSecs-1;				//重新设置唤醒自动重载值
	}
	
	RTC->CR = temp;						//设置配置寄存器
	
	RTC->WPR=0xFF;						//开启写保护
	
	return TRUE;
}

/*************************************************************************************************************************
* 函数			:	bool RTC_Init(bool SerIntEnable)
* 功能			:	RTC初始化
* 参数			:	SerIntEnable:TRUE:开启秒中断;FALSE:关闭秒中断
* 返回			:	TRUE:成功,FALSE:失败
* 依赖			:	底层宏定义
* 作者			:	cp1300@139.com
* 时间			:	2017-07-01
* 最后修改时间 	: 	2017-07-01
* 说明			: 	使用备份区0存放标志来区别是否进行过初始化 RTC->BKP0R=0x5A5AA5A5
*************************************************************************************************************************/
bool RTC_Init(bool SerIntEnable)
{
	u32 retry=0XFFFFFFF; 
	
	RCC->APB1ENR|=1<CR|=1<BKP0R != 0x5A5AA5A5)	//没有进行过配置
	{
		info_printf("RTC没有初始化,开始初始化...rn");
		RCC->BDCR|=1<BDCR&0X02)==0))//等待LSE准备好
		{
			retry--;
			nop;nop;nop;
		}
		if(retry==0)
		{
			info_printf("RTC时钟初始化失败了!rn");
			return FALSE;		//LSE 开启失败.
		}
			 
		RCC->BDCR|=1<BDCR|=1<WPR=0xCA;
		RTC->WPR=0x53; 
		if(RTC_InitMode() == FALSE)//进入RTC初始化模式
		{
			info_printf("RTC进入初始化模式失败了!rn");
			return FALSE;			
		}
		//将32768 进行128x256分频 得到1秒的 ck_spre频率,用于产生秒唤醒中断
		RTC->PRER=255;				//RTC同步分频系数(0~7FFF),必须先设置同步分频,再设置异步分频,Frtc=Fclks/((Sprec+1)*(Asprec+1))
		RTC->PRER|=127<CR&=~(1<ISR&=~(1<WPR=0xFF;				//使能RTC寄存器写保护  
		RTC_SetTime(6,6,6);			//设置初始时间
		RTC_SetDate(2017,6,6);		//设置初始日期
		RTC->BKP0R = 0x5A5AA5A5;	//写入备份区标记,标示已经初始化过RTC
		
		
		info_printf("初始化RTC成功!rn");
		
		//RTC_Set_AlarmA(7,0,0,10);	//设置闹钟时间
	} 
	//RTC_Set_WakeUp(4,0);			
	if(RTC_Get()==FALSE)			//更新一次时间
	{
		info_printf("初始获取时间失败!rn");
	}
	RTC_SetWakeUp(SerIntEnable, 1);//配置WAKE UP中断,1秒钟中断一次 
	
	return TRUE;
}

//设置秒中断回调函数
void RTC_SetWkupCallBack(void (*pCallBack)(void))
{
	RTC_SerIntCallBack = pCallBack;
}


//RTC闹钟中断服务函数
void RTC_Alarm_IRQHandler(void)
{    
	if(RTC->ISR&(1<ISR&=~(1<PR|=1<ISR&(1<ISR&=~(1<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
u32 RTC_DECtoBCD( u8 DEC) 
{
	return ((u8)(DEC/10)<>4)*10+(BCD&0x0f);
}







//使能系统命令行
#if SYS_CMD_EN_
#include "sys_cmd.h"
#include "string.h"

const SYS_CMD_TYPE  CMD_GET_TIME		=	{"TIME?", CMD_GetTime, "tt获取系统时间", TRUE};
const SYS_CMD_TYPE  CMD_GET_DATE		=	{"DATE?", CMD_GetDate, "tt获取系统日期", TRUE};
const SYS_CMD_TYPE  CMD_SET_TIME		=	{"TIME=", CMD_SetTime, "tt设置系统时间 如(12:32:54):TIME=12 32 54", TRUE};
const SYS_CMD_TYPE  CMD_SET_DATE		=	{"DATE=", CMD_SetDate, "tt设置系统日期 如(2014 6 8):TIME=2014 6 8", TRUE};

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

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

//设置时间
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("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	//小时
	p = strstr(pStr," ");	//搜索空格
	if(p == NULL)
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	num = p - pStr;
	if((num > 2) || (num == 0))
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	hour = SYS_CMD_StringToDec(pStr, num);
	if(hour>23)
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	
	//分钟
	pStr = p+1;
	p = strstr(pStr," ");	//搜索空格
	if(p == NULL)
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	num = p - pStr;
	if((num > 2) || (num == 0))
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	min = SYS_CMD_StringToDec(pStr, num);
	if(min>59)
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	//秒钟
	pStr = p+1;
	num = strlen(pStr);
	if((num > 2) || (num == 0))
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	sec = SYS_CMD_StringToDec(pStr, num);
	if(sec>59)
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	
	if(RTC_SetTime(hour, min, sec) == FALSE)
	{
		RTC_Get();		//更新时间
		pHandle->DataPrintf("[时间设置失败]:%02d:%02d:%02drn",g_timer.hour, g_timer.min, g_timer.sec);
	}
	else
	{
		RTC_Get();		//更新时间
		pHandle->DataPrintf("[时间设置成功]:%02d:%02d:%02drn",g_timer.hour, g_timer.min, g_timer.sec);
	}
	
} 


//设置日期
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("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	//年
	p = strstr(pStr," ");	//搜索空格
	if(p == NULL)
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	num = p - pStr;
	if((num > 4) || (num == 0))
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	year = SYS_CMD_StringToDec(pStr, num);
	if(year>9999)
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	
	//月
	pStr = p+1;
	p = strstr(pStr," ");	//搜索空格
	if(p == NULL)
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	num = p - pStr;
	if((num > 2) || (num == 0))
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	month = SYS_CMD_StringToDec(pStr, num);
	if(month>12)
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	//日
	pStr = p+1;
	num = strlen(pStr);
	if((num > 2) || (num == 0))
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	date = SYS_CMD_StringToDec(pStr, num);
	if(date>31)
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	

	if(RTC_SetDate(year, month, date) == FALSE)
	{
		RTC_Get();		//更新时间
		pHandle->DataPrintf("[日期设置失败]:%04d-%02d-%02drn",g_timer.year, g_timer.month, g_timer.date);
	}
	else
	{
		RTC_Get();		//更新时间
		pHandle->DataPrintf("[日期设置成功]:%04d-%02d-%02drn",g_timer.year, g_timer.month, g_timer.date);
	}
	
} 


#endif //SYS_CMD_EN_


/*************************************************************************************************************
 * 文件名		:	RTC.h
 * 功能			:	STM32F4 RTC驱动
 * 作者			:	cp1300@139.com
 * 创建时间		:	2017-07-01
 * 最后修改时间	:	2017-07-01
 * 详细:			要正确读取 RTC 日历寄存器(RTC_SSR、RTC_TR 和 RTC_DR),APB1 时钟频率 (fPCLK1) 必须等于或大于 fRTCCLK RTC 时钟频率的七倍。这可以确保同步机制行为的安全性。
					如果 APB1 时钟频率低于 RTC 时钟频率的七倍,则软件必须分两次读取日历时间寄存器和 日期寄存器。这样,当两次读取的 RTC_TR 结果相同时,才能确保数据正确。
					否则必须执 行第三次读访问。任何情况下,APB1 的时钟频率都不能低于 RTC 的时钟频率。
					RTC->BKP0R:用于标示是否进行了初始化RTC,请不要再使用了。
*************************************************************************************************************/
#ifndef __RTC_H_
#define __RTC_H_
#include "system.h" 


//时间结构体
typedef  struct 
{
	u8	hour; 		//小时
	u8	min;	 	//分钟
	u8	sec;		//秒			
	u8  month;		//月
	u8  date;		//日
	u8  week;		//星期
	u16 year;	 	//年
}tm;
extern volatile tm g_timer;



//函数接口
bool RTC_SetTime(u8 hour,u8 min,u8 sec);	//RTC时间设置
bool RTC_SetDate(u16 year,u8 month,u8 date);//RTC日期设置
bool RTC_GetTime(u8 *hour,u8 *min,u8 *sec);	//获取RTC时间
bool RTC_GetDate(u16 *year,u8 *month,u8 *date,u8 *week);//获取RTC日期
bool RTC_Get(void);							//更新RTC时间
bool RTC_Init(bool SerIntEnable);			//RTC初始化
bool RTC_SetWakeUp(bool isEnableInt, u16 WakeSecs);	//RTC唤醒中断设置
void RTC_SetWkupCallBack(void (*pCallBack)(void));//设置秒中断回调函数



//使能系统命令行
#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;


//获取时间
void CMD_GetTime(SYS_CMD_HANDLE *pHandle,char *pStr);
//获取日期
void CMD_GetDate(SYS_CMD_HANDLE *pHandle,char *pStr);
//设置时间
void CMD_SetTime(SYS_CMD_HANDLE *pHandle,char *pStr);
//设置日期
void CMD_SetDate(SYS_CMD_HANDLE *pHandle,char *pStr);

#endif //SYS_CMD_EN_




#endif //__RTC_H_


使用时需要一个秒中断回调函数,比如我的秒中断是用来唤醒一个线程,处理秒任务


RTC_Init(TRUE);




//任务2:负责后台(RTC 1秒唤醒一次)
void TaskBack(void *pdata)
{
	RTC_SetWkupCallBack(RTC_WkupCallBack);					//设置RTC回调函数
	
	while(1)
	{
		RTC_Get();											//更新系统时间
		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);						//挂起后台进程
	}
}
//RTC秒中断回调函数
void RTC_WkupCallBack(void)
{
	OSTaskResume(BACK_TASK_Prio);						//唤醒后台进程
}




本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

基于ARM® Cortex®-M4的STM32F4 MCU系列采用了意法半导体的NVM工艺和ART Accelerator™,在高达180 MHz的工作频率下通过闪存执行时其处理性能达到225 DMIPS/608 Cor...

关键字: stm32f4 ARM

stm32f4和f1都有哪些区别?除了需要的头文件不一样,管脚配置什么的有区别么?

关键字: stm32f4 f1 比较

STM32F407VET6引脚图及中文资料

关键字: stm32f4 引脚图

  2016年2月26日,德国慕尼黑和西班牙巴塞罗那讯——赢得消费者的信任对于智能移动设备支付解决方案至关重要。作为全球最大的安全芯片供应商之一,英飞凌科技股份公司(FS

关键字: rtc 机器人 rx8010sj

博主使用的是天嵌的开发板型号IMX6Q_coreC。1.发现使用开发板是时间总是被设置为2028年6月18日3时41分,一开始以为是底层驱动的问题, 故去底层加打印信息调试。2.发现在系统内hwclo

关键字: Linux rtc

比较F1的片子对于F4的RTC来说有很大提升,F4的RTC提供了日历时钟和两个可编程闹钟中断,一个周期性可编程唤醒标志。这样很方便设置系统时间,并不会像F1的RTC那样要自己计算年月日时分秒。F4的RTC是一个独立的BC...

关键字: rtc stm32f4

【实验目的】输出7路占空比不同的PWM信号是各个版本ST库必备的例子。本实验的主要目的不是表现ST芯片PWM功能的强大,而是要完成输出的精确计算。【实验内容】输出7路PWM信号,并用示波器测量输出。【实验原理】1、时

关键字: pwm stm32f4 tim1 信号输出

STM32F4的随机数发生器RNG,以环境噪声为种子,产生32位随机数供主机使用。【主要特性】1、产生32位随机数 2、两次转换时间间隔40PLL48CLK 3、随机数熵检测以发现不正常位,以产生稳定序列 3、可被关闭以...

关键字: stm32f4 随机数发生器

  RTC-Real Time Clock是430单片机的实时时钟模块,可以配置成实时时钟模式(万年历)或者一般目的的32位计数器模式,其中实时时钟模式提供了年月日、时分秒,可以选择BCD码或者二进制格式,并且具有可编程...

关键字: MSP430 rtc 单片机 实时时钟

STM32RTC使用步骤:打开PWR时钟和Backup区数据访问若使用外部低速时钟(LSE),打开LSE并等待起振选择和打开RTC时钟,等待时钟同步配置时间格式,分频系数等根据需要配置时钟,日期,闹钟,唤醒,输出,时间戳...

关键字: rtc stm32f3 实时时钟
关闭
关闭