STM32的RTC指的是实时时钟(Real-Time Clock),它是一种用于计时和日期记录的硬件模块。在STM32微控制器中,RTC模块是由一个32位的计数器和一组用于保存日期和时间的寄存器组成的。

RTC模块具有很高的精度和稳定性,并且能够在微控制器断电时继续运行,从而保持准确的时间和日期信息。它通常用于需要精确定时和实时数据记录的应用场景,例如时钟、日历、定时器、闹钟、数据采集等。

STM32的RTC模块提供了一系列的功能,包括时钟频率配置、时间和日期的设置与读取、闹钟的设置与触发、定时器功能、中断控制等。通过配置和使用RTC模块,开发者可以实现各种与时间相关的功能和应用。

在STM32CubeIDE中配置使用RTC模块也是非常便捷的。

 



 


自动生成RTC初始化代码:

复制
static void MX_RTC_Init(void)

{



  /* USER CODE BEGIN RTC_Init 0 */



  /* USER CODE END RTC_Init 0 */



  RTC_PrivilegeStateTypeDef privilegeState = {0};

  RTC_TimeTypeDef sTime = {0};

  RTC_DateTypeDef sDate = {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_DISABLE;

  hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;

  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;

  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;

  hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;

  hrtc.Init.BinMode = RTC_BINARY_NONE;

  if (HAL_RTC_Init(&hrtc) != HAL_OK)

  {

    Error_Handler();

  }

  privilegeState.rtcPrivilegeFull = RTC_PRIVILEGE_FULL_YES;

  privilegeState.backupRegisterPrivZone = RTC_PRIVILEGE_BKUP_ZONE_NONE;

  privilegeState.backupRegisterStartZone2 = RTC_BKP_DR0;

  privilegeState.backupRegisterStartZone3 = RTC_BKP_DR0;

  if (HAL_RTCEx_PrivilegeModeSet(&hrtc, &privilegeState) != 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 = 0x21;

  sTime.Minutes = 0x27;

  sTime.Seconds = 0x40;

  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;

  sTime.StoreOperation = RTC_STOREOPERATION_RESET;

  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)

  {

    Error_Handler();

  }

  sDate.WeekDay = RTC_WEEKDAY_SATURDAY;

  sDate.Month = RTC_MONTH_SEPTEMBER;

  sDate.Date = 0x7;

  sDate.Year = 0x24;



  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)

  {

    Error_Handler();

  }

  /* USER CODE BEGIN RTC_Init 2 */



  /* USER CODE END RTC_Init 2 */



}




不过在运行过程中总是遇到错误,后来调试发现是在函数HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef *hrtc) 执行过程中,初始化状态竟然返回HAL_TIMEOUT.


如下单步调试可以发现:SET_BIT(RTC->ICSRRTC_ICSR_INIT);执行后,寄存器的初始化位并没有被置1.
 



后面在参考手册中找到:
 



所以解决办法:在RTC进入初始化状态之前会调用HAL_RTC_MspInit(hrtc);
 


所以进入到这个函数内部,添加一行语句使能写RTC寄存器。完整的代码如下

复制
void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)

{

  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  if(hrtc->Instance==RTC)

  {

  /* USER CODE BEGIN RTC_MspInit 0 */

        /* Enables access to the backup domain */

        HAL_PWR_EnableBkUpAccess();

  /* USER CODE END RTC_MspInit 0 */



  /** Initializes the peripherals clock

  */

    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;

    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;

    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)

    {

      Error_Handler();

    }



    /* Peripheral clock enable */

    __HAL_RCC_RTC_ENABLE();

    __HAL_RCC_RTCAPB_CLK_ENABLE();

  /* USER CODE BEGIN RTC_MspInit 1 */



  /* USER CODE END RTC_MspInit 1 */



  }



}

接下来,正常编译,运行,一切OK。

 



实物展示:
 



参考资料:
Getting started with RTC  https://wiki.stmicroelectronics.cn/stm32mcu/wiki/Getting_started_with_RTC

---------------------
作者:南来之风
链接:https://bbs.21ic.com/icview-3400954-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐