STM32F411 Nucleo实验板上有低速晶振,虽然没有电池。但是还是可以测试一下。这里顺便打开RTC外设的 1Hz 脉冲输出。后面项目里要用到,用硬件1Hz的脉冲给不同的定时器捕获通道,这几个定时器就有了同样的时间基准,触发捕获的时候同时处理各自其他通道上的事情。
板载的外部晶振32.768KHz
RTC外设1Hz脉冲输出
RTC输出用到的是 PC13引脚
实验板上PC13引脚连接的是用户按键,不是很方便后续捕获,但是还是可以看下波形
初始化一下PC13:配置为开漏输出,频率不需要很高
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_Init(GPIOC,&GPIO_InitStructure);
配置RTC : 日期、时间都被初始化为0了。闹钟暂时不用,被我注释掉了。
- void RTC_Configuration(void)
- {
- RTC_TimeTypeDef RTC_TimeStructure;
- RTC_DateTypeDef RTC_DateStructure;
- RTC_InitTypeDef RTC_InitStructure;
- // RTC_AlarmTypeDef RTC_AlarmStructure;
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
- PWR_BackupAccessCmd(ENABLE);
- RCC_BackupResetCmd(ENABLE);
- RCC_BackupResetCmd(DISABLE);
-
- RCC_LSEConfig(RCC_LSE_ON);
- while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
- RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
- RCC_RTCCLKCmd(ENABLE);
- RTC_WaitForSynchro();
- RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
- RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
- RTC_InitStructure.RTC_SynchPrediv = 0xFF;
- RTC_Init(&RTC_InitStructure);
- RTC_DateStructure.RTC_Date = GetDate.RTC_Date; //
- RTC_DateStructure.RTC_Month = GetDate.RTC_Month;
- RTC_DateStructure.RTC_Year = GetDate.RTC_Year;
- RTC_DateStructure.RTC_WeekDay = GetDate.RTC_WeekDay;
- RTC_SetDate(RTC_Format_BIN,&RTC_DateStructure);
- RTC_TimeStructure.RTC_H12 = RTC_H12_AM; //
- RTC_TimeStructure.RTC_Hours = GetTime.RTC_Hours;
- RTC_TimeStructure.RTC_Minutes = GetTime.RTC_Minutes;
- RTC_TimeStructure.RTC_Seconds = GetTime.RTC_Seconds;
- RTC_SetTime(RTC_Format_BIN,&RTC_TimeStructure);
- // RTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_WeekDay;//;
- // RTC_AlarmStructure.RTC_AlarmDateWeekDay = RTC_Weekday_Tuesday;//RTC_Weekday_Monday;
- // RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_All;
- // RTC_AlarmStructure.RTC_AlarmTime = RTC_TimeStructure; //
- // RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds += 2; //
- // RTC_SetAlarm(RTC_Format_BIN,RTC_Alarm_A,&RTC_AlarmStructure);
- // RTC_AlarmSubSecondConfig(RTC_Alarm_A,0xFF,RTC_AlarmSubSecondMask_All);
- // RTC_AlarmCmd(RTC_Alarm_A,ENABLE);
- // RTC_ITConfig(RTC_IT_ALRA,ENABLE);
- // RTC_ITConfig(RTC_IT_WUT,ENABLE);
- RTC_WakeUpCmd(DISABLE);
- RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);
- RTC_SetWakeUpCounter(0);
- RTC_WakeUpCmd(ENABLE);
-
- RTC_OUT_Config();
- }
配置一下 RTC 1Hz 脉冲输出:
- void RTC_OUT_Config(void)
- {
- RTC_OutputTypeConfig(RTC_OutputType_OpenDrain);
- // RTC_OutputConfig(RTC_Output_AlarmA,RTC_OutputPolarity_Low);
- RTC_CalibOutputConfig(RTC_CalibOutput_1Hz);
- RTC_CalibOutputCmd(ENABLE);
- }
使用库函数读取日期、时间:
- void Get_DateTime(void)
- {
- RTC_GetDate(RTC_Format_BIN,&GetDate);
- RTC_GetTime(RTC_Format_BIN,&GetTime);
- }
周期性的任务:1S中去读一次当前RTC时间
- void AppTaskStart(void const *arg)
- {
- AppTaskCreat();
- for(;;)
- {
- GPIO_PIN_TogglePin(GPIOA,GPIO_Pin_5);
- Get_DateTime();
- osDelay(1000);
- }
- }
仿真的结果可以看到RTC跑了起来
再看一下PC13(用户按键)上的波形:
可以看到 RTC 硬件方式输出的 1Hz 还是很精准的。1.000258S的周期性方波。