STM32 的 RTC 外设是一个掉电后还继续运行的定时器。 这里的掉电是指当主电源断开的时候,可以接上锂电池给RTC供电。RTC时钟具有计时和触发中断的功能,但是它比起其它外设强大在它的掉电可持续运行特性。
它使用的时钟 源有三种,分别为高速外部时钟的 128 分频(HSE/128)、低速内部时钟 LSI 以及低速外 部时钟 LSE; 一般要保证RTC能够在掉电后还能继续计时,要使用LSE外部低速时钟。以下是RTC的外设框图。
RTC外设框图
RTC可以触发三种中断:
使用STM32CubeMX创建项目。
设置高速外部时钟HSE为时钟源,同时使能外部晶振LSE:
由于HSE分频时钟或者LSI时钟源在主电源掉电时会受到影响,不能保证RTC时钟正常工作,这里使用外部低速时钟LSE。
开启RTC时钟,并且启动日历和时钟源,RTC_OUT参数是询问是否在PC13引脚输出校正的秒脉冲时钟,Tamper指RTC入侵检测校验功能。
生成代码:
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** 根据指定参数初始化RCC振荡器
* 在 RCC_OscInitTypeDef 结构中。
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
// 这里启用HSE,LSE,HSI三个时钟源
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** 初始化 CPU、AHB 和 APB 总线时钟
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
使能串口,为了发送数据到电脑上:
使用HAL_RTC_GetTime和HAL_RTC_GetDate函数获取时间和日期。通过使用HAL_RTC_GetDate函数生成的日期结构体中包含WeekDay属性,只需提供年,月,日三个参数就可通过HAL库的库函数计算出当天是星期几:
/**
* @brief 显示时间和日期
* @param 无
* @retval 无
*/
void RTC_TimeAndDate_Show(void)
{
RTC_DateTypeDef GetDate; //获取日期结构体
RTC_DateTypeDef GetDate2; //获取日期结构体
RTC_TimeTypeDef GetTime; //获取时间结构体
while(1)
{
HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
/* Get the RTC current Date */
HAL_RTC_GetDate(&hrtc, &GetDate, RTC_FORMAT_BIN);
/* Display date Format : yy/mm/dd */
printf("%02d/%02d/%02d\r\n",2000 + GetDate.Year, GetDate.Month, GetDate.Date);
// 星期几
printf("%s\r\n",ToString(GetDate.WeekDay));
//printf("%0.2d\r\n",GetDate2.WeekDay);
/* Display time Format : hh:mm:ss */
printf("%02d:%02d:%02d\r\n",GetTime.Hours, GetTime.Minutes, GetTime.Seconds);
printf("\r\n");
HAL_Delay(1000);
}
printf("Finish\r\n");
}
const char* ToString(uint8_t v)
{
switch (v)
{
case RTC_WEEKDAY_MONDAY: return "MONDAY";
case RTC_WEEKDAY_TUESDAY: return "TUESDAY";
case RTC_WEEKDAY_WEDNESDAY: return "WEDNESDAY";
case RTC_WEEKDAY_THURSDAY: return "THURSDAY";
case RTC_WEEKDAY_FRIDAY: return "FRIDAY";
case RTC_WEEKDAY_SATURDAY: return "SATURDAY";
case RTC_WEEKDAY_SUNDAY: return "SUNDAY";
default: return "[Unknown WeekDay]";
}
}
源码下载: 源码
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。