学习STM32的RTC实时时钟

实时时钟(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模块的使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值