实时时钟(RTC)是STM32微控制器的一个重要模块,它提供了一种精确计时的功能,可用于记录时间、日期和闹钟功能。在本文中,我将为您提供一个详细的代码案例,以帮助您了解如何在STM32上使用RTC模块。
首先,我们需要创建一个新的STM32项目,并使用CubeMX配置RTC模块。在CubeMX中,选择相关的引脚和功能,并生成代码。
接下来,我们将进入代码实现的部分。我将使用STM32Cube HAL库来编写代码,这是STMicroelectronics提供的用于STM32系列微控制器的一套驱动库。以下是一个完整的代码案例,它包含了初始化RTC模块、设置日期和时间、读取日期和时间、以及设置和关闭闹钟的功能。
#include "main.h"
#include "stm32f1xx_hal.h"
RTC_HandleTypeDef hrtc;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_RTC_Init(void);
void RTC_Init(void);
void RTC_SetDateTime(uint8_t year, uint8_t month, uint8_t day, uint8_t weekday, uint8_t hour, uint8_t minute, uint8_t second);
void RTC_GetDateTime(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *weekday, uint8_t *hour, uint8_t *minute, uint8_t *second);
void RTC_SetAlarm(uint8_t hour, uint8_t minute);
void RTC_DisableAlarm(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_RTC_Init();
RTC_Init();
RTC_SetDateTime(21, 4, 5, 2, 10, 30, 0); // 设置日期和时间
while (1)
{
uint8_t year, month, day, weekday, hour, minute, second;
RTC_GetDateTime(&year, &month, &day, &weekday, &hour, &minute, &second); // 读取日期和时间
// 在OLED或LCD上显示当前日期和时间
// ...
HAL_Delay(1000);
}
}
void RTC_Init(void)
{
// 使能RTC时钟
__HAL_RCC_RTC_ENABLE();
// 配置RTC时钟源为LSI,使用默认32kHz频率
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
// 初始化RTC配置
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
HAL_RTC_Init(&hrtc);
}
void RTC_SetDateTime(uint8_t year, uint8_t month, uint8_t day, uint8_t weekday, uint8_t hour, uint8_t minute, uint8_t second)
{
RTC_DateTypeDef sDate = {0};
RTC_TimeTypeDef sTime = {0};
// 设置日期
sDate.WeekDay = weekday;
sDate.Month = month;
sDate.Date = day;
sDate.Year = year;
// 设置时间
sTime.Hours = hour;
sTime.Minutes = minute;
sTime.Seconds = second;
// 设置RTC日期和时间
HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
}
void RTC_GetDateTime(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *weekday, uint8_t *hour, uint8_t *minute, uint8_t *second)
{
RTC_DateTypeDef sDate = {0};
RTC_TimeTypeDef sTime = {0};
// 读取RTC日期和时间
HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
// 返回日期和时间
*year = sDate.Year;
*month = sDate.Month;
*day = sDate.Date;
*weekday = sDate.WeekDay;
*hour = sTime.Hours;
*minute = sTime.Minutes;
*second = sTime.Seconds;
}
void RTC_SetAlarm(uint8_t hour, uint8_t minute)
{
// 配置闹钟中断
HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A);
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, hour, minute, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
}
void RTC_DisableAlarm(void)
{
// 关闭闹钟中断
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
}
void MX_RTC_Init(void)
{
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};
hrtc.Instance = RTC;
hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
sTime.Hours = 0x0;
sTime.Minutes = 0x0;
sTime.Seconds = 0x0;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD);
sDate.WeekDay = RTC_WEEKDAY_MONDAY;
sDate.Month = RTC_MONTH_JANUARY;
sDate.Date = 0x1;
sDate.Year = 0x0;
HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD);
}
// ... 省略 SystemClock_Config() 和 MX_GPIO_Init() 函数的实现 ...
这个代码案例将在无限循环中不断读取RTC的日期和时间,并可以根据需要设置和关闭闹钟。请注意,上述不完整代码示例中的MX_RTC_Init()
函数是自动生成的,并由CubeMX生成的代码提供。您可能需要根据您的实际需求进行适当的修改。
以上是一个基本的RTC实时时钟的代码案例。您可以根据具体的应用需求进行扩展和修改。希望本文能帮助您学习和理解STM32的RTC模块的使用。