讲了那么久终于讲到调时功能,我也觉得怪怪的,作为一个手表应该首先介绍其身为手表的功能…… 哎,新手,,,,没想太多
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);
以上就是求星期的源码,有需要的就拿去呗
------------------------------------------------------------------------温柔华丽的分割线--------------------------------------------------------------------
|