前言
在做51单片机项目时,如果需要年月日时分秒的时间记录,会在51单片机上面外挂一个DS1302的时钟芯片,再加上时间芯片的外围电路。但在STM32F407中,不再需要这么干了,因为在STM32的内部就已经集成了年月日时分秒的时钟电路--也就是实时时钟(RTC)
RTC框图
下图是RTC的框图,箭头部分是实时时钟基本部分,包括时钟源,预分频,影子寄存器,引脚复用输出。此外还有两个闹钟,周期唤醒,入侵检测以及时间戳。
STM32实时时钟电路
在开发板上有低速外部时钟源-32.768Khz。
功能需要
1)配置当前时间
时间可以采取24小时格式,也可以采用12小时格式,默认采用24小时格式。配置时间时,还会设置日期格式,是采用BCD或者二进制。建议采用二进制即可,可以直接填入时间数值。
2)配置闹钟(每隔10s,触发一次闹钟中断)
3)设置周期唤醒(唤醒时间1s)并且可以输出低电平。
STM32CubeMx配置RTC
配置RCC
由于RTC使用到外部时钟源,因此需要在时钟配置使用低速外部时钟源。
配置RTC
配置时间,闹钟,唤醒
配置时间24小时格式,二进制格式(22年5月2日,12时19分50秒);设置闹钟(由于每10s,闹钟触发一次中断,因此屏蔽掉时分,不屏蔽秒);设置周期时钟,周期为1Hz,不需要计数,也就是1s触发一次;如果计数值为1,则为2s触发一次中断。
开启中断
设置中断优先级
功能代码实现
STM32Cude生成RTC初始化
void MX_RTC_Init(void)
{
/* USER CODE BEGIN RTC_Init 0 */
/* USER CODE END RTC_Init 0 */
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};
RTC_AlarmTypeDef sAlarm = {0};
/* USER CODE BEGIN RTC_Init 1 */
/* USER CODE END RTC_Init 1 */
/** Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_WAKEUP;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN Check_RTC_BKUP */
/* USER CODE END Check_RTC_BKUP */
/** Initialize RTC and set the Time and Date
*/
sTime.Hours = 12;
sTime.Minutes = 19;
sTime.Seconds = 50;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
sDate.WeekDay = RTC_WEEKDAY_MONDAY;
sDate.Month = RTC_MONTH_MAY;
sDate.Date = 2;
sDate.Year = 22;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
/** Enable the Alarm A
*/
sAlarm.AlarmTime.Hours = 0;
sAlarm.AlarmTime.Minutes = 0;
sAlarm.AlarmTime.Seconds = 10;
sAlarm.AlarmTime.SubSeconds = 0;
sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS
|RTC_ALARMMASK_MINUTES;
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
sAlarm.AlarmDateWeekDay = 1;
sAlarm.Alarm = RTC_ALARM_A;
if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
/** Enable the WakeUp
*/
if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN RTC_Init 2 */
/* USER CODE END RTC_Init 2 */
}
自定义触发闹钟次数变量
重写周期唤醒回调函数
注:
1)一定要要先读Time然后再度Date,否者会出错;
2)即使不需要Date数据,也要读Date否则也会出错。
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{
RTC_TimeTypeDef sTime ={0};
RTC_DateTypeDef sDate={0};
char str[40] ={0};
//1)一定要要先读Time然后再度Date,否者会出做;即使不需要Date数据,也要度Date否则也会出错
if((HAL_RTC_GetTime(hrtc,&sTime,RTC_FORMAT_BIN)!=HAL_OK)|| (HAL_RTC_GetDate(hrtc,&sDate,RTC_FORMAT_BIN)!=HAL_OK))
{
return;
}
sprintf(str,"RTC Time = %4d年%2d月%2d日 rn",2000+sDate.Year,sDate.Month,sDate.Date);
HAL_UART_Transmit(&huart1,(const uint8_t *)str,strlen(str),100);
sprintf(str,"RTC Time = %2d时%2d分%2d秒 rn",sTime.Hours,sTime.Minutes,sTime.Seconds);
HAL_UART_Transmit(&huart1,(const uint8_t *)str,strlen(str),100);
}
重写闹钟中断函数
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
char str[40] ={0};
sprintf(str,"闹钟触发次数: %d rn",++alarmTrigger);
HAL_UART_Transmit(&huart1,(const uint8_t *)str,strlen((const char *)str),100);
}
上一篇:STM32基础11--模数转换(ADC)
下一篇:STM32基础9--串口通信(UART)
推荐阅读最新更新时间:2024-11-04 20:40
设计资源 培训 开发板 精华推荐
- LTC2624 的典型应用 - 采用 16 引脚 SSOP 的四通道 12 位轨至轨 DAC
- DC2169A,用于 LT8616EFE 双同步降压的演示板,4.1V = VIN = 42V,Vout1 = 5V @ 1.5A,Vout2 = 3.3V @ 2.5A
- ADM1068ASTZ超级定序器和监视器的典型应用电路
- AOZ1210AI-EVB,使用AOZ1210AI DC-DC单步降压转换器的评估板
- MPC852TADS-KIT: MPC852T应用开发系统套件
- EV-ADUCM320QSPZ,基于 ADuCM320 双芯片堆栈片上系统的开发系统,专为固定波长激光光学模块应用的诊断控制而设计
- AD8018AR-EBZ、AD8018评估板
- EVAL-ADN2850SDZ,用于 ADN2850 双通道、1024 位、非易失性存储器数字电阻器的评估板
- 基于CH340G的USB转TTL模块
- A7986A 3A 汽车应用正降压-升压稳压器的典型应用