问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

STM32单片机RTC实时时钟详解及实战

创作时间:
作者:
@小白创作中心

STM32单片机RTC实时时钟详解及实战

引用
CSDN
1.
https://blog.csdn.net/zy2232652/article/details/140750117

STM32单片机的RTC(实时时钟)模块是嵌入式系统中非常重要的一个组件,它能够提供精确的时间基准,广泛应用于各种需要时间记录和定时控制的场景。本文将详细介绍STM32单片机的RTC模块,包括其基本概念、内部结构、配置方法以及实际应用,适合零基础的读者学习。

一.概要

RTC(Real-Time Clock)是一种用于追踪和记录实际时间的时钟系统。在STM32中,RTC通常用于提供实时时钟和日期信息,例如年、月、日、时、分、秒等。RTC在许多应用中都是重要的,尤其是需要记录事件发生时间的系统,如数据日志、定时器等。

RTC位于系统的后备区域,这意味着在系统复位时,其数据不会清零。此外,即使在电源VDD(2.0-3.6V)断开的情况下,RTC仍可以通过备份电源VBAT(1.8~3.6V)供电,继续运行。

本文介绍了STM32 RTC实时时钟的基本概念,内部结构,以及用内部RTC进行时间计时的例程。

二.RTC基本介绍

实时时钟(Real Time Clock)是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。

这款MCU的RTC没有硬件万年历功能,是通过RTC库的HAL_RTC_GetTime()函数将秒数转换成日期数据的。RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒后,RTC的设置和时间维持不变。

RTC主要特性
可编程的预分频系数:分频系数最高为220。
● 32位的可编程计数器,可用于较长时间段的测量。
● 2个分离的时钟:用于APB1接口的PCLK1和RTC时钟(RTC时钟的频率必须小于PCLK1时钟频率的四分之一以上)。
● 可以选择以下三种RTC的时钟源:
─ HSE时钟除以128。
─ LSE振荡器时钟,这个是最常用的时钟源。
─ LSI振荡器时钟。
● 2个独立的复位类型:
─ APB1接口由系统复位;
─ RTC核心(预分频器、闹钟、计数器和分频器)只能由后备域复位。
● 3个专门的可屏蔽中断:
─ 闹钟中断,用来产生一个软件可编程的闹钟中断。
─ 秒中断,用来产生一个可编程的周期性中断信号(最长可达1秒)。
─ 溢出中断,指示内部可编程计数器溢出并回转为0的状态。

三.STM32单片机RTC内部结构图

RTC内部结构图如下

灰色区域是后备区域,这些电路在主电源掉电后,可以使用备用电池维持工作,所以这里是RTC的主要部分。

RTCCLK进来,需要首先经过RTC预分频器进行分频,时钟信号提供给32位寄存器RTC_CNT,就是计时最核心的部分,RTC_CNT寄存器用来存放计数器的计数值,对RTC_CNT进行读操作时,直接返回计数器内的计数值(系统时间)。

RTC_CNT一个 32 位的时钟计数器,按秒钟计算,可以记 录 4294967296 秒,约合 136 年左右,STM32F103C8T6通过RTC库的HAL_RTC_GetTime()(小时、分钟、秒)和HAL_RTC_GetDate()(年、月、日和星期)把RTC_CNT转换成日历值。

四.CubeMX配置一个RTC走秒例程

STLINK接STM32F103C8T6小系统板,STLINK接电脑USB口。

打开STM32CubeMX软件,新建工程

Part Number处输入STM32F103C8,再双击就创建新的工程

配置下载口引脚

配置外部晶振引脚,配置外部低频晶振引脚

配置RTC使能

配置系统主频

配置RTC时钟为外部32.768K

配置工程文件名,保存路径,KEIL5工程输出方式

生成工程

用Keil5打开工程

添加代码


uint8_t aShowTime[16] = "hh:ms:ss";//定义时分秒
uint8_t aShowDate[16] = "dd-mm-yyyy";//定义年月日
//获取日期,时间,
static void RTC_CalendarShow(uint8_t *showtime, uint8_t *showdate)
{
  RTC_DateTypeDef sdatestructureget;
  RTC_TimeTypeDef stimestructureget;
  /* Get the RTC current Time */
  HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);
  /* Get the RTC current Date */
  HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);
//  /* Display time Format : hh:mm:ss */
  sprintf((char *)showtime, "%2d:%2d:%2d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
//  /* Display date Format : mm-dd-yy */
  sprintf((char *)showdate, "%2d-%2d-%2d", sdatestructureget.Month, sdatestructureget.Date, 2000 + sdatestructureget.Year);
}
/* USER CODE END 0 */
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_RTC_Init();
  /* USER CODE BEGIN 2 */
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
          RTC_CalendarShow(aShowTime, aShowDate);//读取时间,日期保存到数组
  }
  /* USER CODE END 3 */
}
void MX_RTC_Init(void)
{
  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef DateToUpdate = {0};
  /** Initialize RTC Only
  */
  hrtc.Instance = RTC;
  hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
  hrtc.Init.OutPut = RTC_OUTPUTSOURCE_ALARM;
  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 = 0x0;
  sTime.Minutes = 0x0;
  sTime.Seconds = 0x0;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY;
  DateToUpdate.Month = RTC_MONTH_JANUARY;
  DateToUpdate.Date = 0x1;
  DateToUpdate.Year = 0x21;//设置初始时间是21年1月1日
  if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
}
  

实验效果

查看aShowTime数组,能看到时间会一秒一秒走

五.CubeMX工程源代码下载

链接:https://pan.baidu.com/s/1w_undAclM4IKjJPA4NusWg

提取码:pw02

如果链接失效,可以联系博主给最新链接

程序下载下来之后解压就行

六.小结

RTC 可以为嵌入式系统提供精确的时间基准,用于各种定时任务和事件。RTC 可以用于智能家居设备中的时间控制,如智能门锁、智能照明等。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号