讲了那么久终于讲到调时功能,我也觉得怪怪的,作为一个手表应该首先介绍其身为手表的功能…… 哎,新手,,,,没想太多
stm32f4的固件库对RTC优化了很多,接下来我们就详细讲讲,到底优化多少了!
static void RTC_delay_ms(u16 time)
{
u16 i=0;
while(time--)
{
i=16666;
while(i--);
}
}
//RTC时间设置
//hour,min,sec:小时,分钟,秒钟
//ampm:@RTC_AM_PM_Definitions :RTC_H12_AM/RTC_H12_PM
//返回值:SUCEE(1),成功
// ERROR(0),进入初始化模式失败
ErrorStatus RTC_Set_Time(u8 hour,u8 min,u8 sec)
{
RTC_TimeTypeDef RTC_TimeTypeInitStructure;
RTC_TimeTypeInitStructure.RTC_Hours=hour;
RTC_TimeTypeInitStructure.RTC_Minutes=min;
RTC_TimeTypeInitStructure.RTC_Seconds=sec;
return RTC_SetTime(RTC_Format_BIN,&RTC_TimeTypeInitStructure);
}
//RTC日期设置
//year,month,date:年(0~99),月(1~12),日(0~31)
//week:星期(1~7,0,非法!)
//返回值:SUCEE(1),成功
// ERROR(0),进入初始化模式失败
ErrorStatus RTC_Set_Date(u8 year,u8 month,u8 date,u8 week)
{
RTC_DateTypeDef RTC_DateTypeInitStructure;
RTC_DateTypeInitStructure.RTC_Date=date;
RTC_DateTypeInitStructure.RTC_Month=month;
RTC_DateTypeInitStructure.RTC_WeekDay=week;
RTC_DateTypeInitStructure.RTC_Year=year;
return RTC_SetDate(RTC_Format_BIN,&RTC_DateTypeInitStructure);
}
u8 RTC_init(void)
{
RTC_InitTypeDef RTC_InitStructure;
u16 retry=0x1FFF;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
PWR_BackupAccessCmd(ENABLE);
if(RTC_ReadBackupRegister(RTC_BKP_DR0)!=0x5040)
{
RCC_LSEConfig(RCC_LSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET)
{
retry++;
RTC_delay_ms(10);
}
if(retry==0)return 1;
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
RTC_InitStructure.RTC_AsynchPrediv=0x7f;
RTC_InitStructure.RTC_SynchPrediv=0xff;
RTC_InitStructure.RTC_HourFormat=RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure);
RTC_Set_Time(9,46,10); //设置时间
RTC_Set_Date(15,3,2,1); //设置日期
RTC_WriteBackupRegister(RTC_BKP_DR0,0x5040); //标记已经初始化过了
}
return 0;
}
没错,不用70行代码就能对时间日期的修改,打开以前stm32f1系列的代码,粗略计算了一下,要700行,大大减少工程的代码量和我们的工作量。
打开电源管理时钟,使能后备寄存器,判断后备寄存器的值(防止多次配置),如果数据对不上,就对RTC重新初始化,配置LSE时钟并等待时钟稳定,配置RTC的结构体,再设置时间。
在这里利用SysTick定时器对时间进行刷新
void SysTick_Handler(void)
{
static uint8_t count_time=0;
static uint32_t rtc_time=0;
// TimingDelay_Decrement();
OS_TimeMS ++;
count_time++;
rtc_time++;
if(count_time == 10)
{
GUI_TOUCH_Exec(); //每10ms调用一次,触发调用触摸驱动
count_time =0;
}
if(rtc_time == 2000)
{
if(WM_IsWindow(WinPara.hWinMain))//判断当前激活的窗口
WM_SendMessageNoPara(WinPara.hWinMain,MY_MESSAGE_RTC);
if(WM_IsWindow(WinPara.hBkWheel))//判断当前激活的窗口
WM_SendMessageNoPara(WinPara.hBkWheel,MY_MESSAGE_RTC);
rtc_time=0;
LED_TOGGLE;
}
}
分别对两个窗口进行时间刷新,分别为时间调节窗口和主窗口,在这里必须对当前窗口进行判断,否则图形界面可能会卡死。
如图为调节时间的主界面,采用的是LISTWHEEL控件进行时间选择,选择好时间后点击ok后即可对时间的调节。
大家可以发现,这里没有对星期的调节,别怕我找了条公式 ,传说中的 蔡勒(Zeller)公式
w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
if(RTC_DateStruct.RTC_Month==1||RTC_DateStruct.RTC_Month==2)
{
m=RTC_DateStruct.RTC_Month+12;
y=RTC_DateStruct.RTC_Year-1;
}
else
{
m=RTC_DateStruct.RTC_Month;
y=RTC_DateStruct.RTC_Year;
}
RTC_DateStruct.RTC_WeekDay=(y+y/4+26*(m+1)/10+RTC_DateStruct.RTC_Date-36)%7;
if(RTC_DateStruct.RTC_WeekDay==0)RTC_DateStruct.RTC_WeekDay=7;
RTC_Set_Date(RTC_DateStruct.RTC_Year,RTC_DateStruct.RTC_Month,RTC_DateStruct.RTC_Date,RTC_DateStruct.RTC_WeekDay);
RTC_Set_Time(RTC_TimeStruct.RTC_Hours,RTC_TimeStruct.RTC_Minutes,RTC_TimeStruct.RTC_Seconds);
以上就是求星期的源码,有需要的就拿去呗
------------------------------------------------------------------------温柔华丽的分割线--------------------------------------------------------------------
|