STM32
直播中

王兰

14年用户 943经验值
擅长:基础元器件
私信 关注
[问答]

如何对STM32F030 RTC进行配置

RTC的时钟源有哪些?
如何对STM32F030 RTC进行配置?

回帖(1)

王雷

2021-10-26 12:06:13
  STM32F030_RTC详细配置说明
  今天总结RTC(Real Time Clock)实时时钟相关的知识。在进行RTC的讲解前,我先对BKP进行一个简单的讲解。
  STM32的RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒后, RTC的设置和时间维持不变。
  STM32F0的RTC模块和F3的RTC模块最大区别在于F0模块中有“DATE”和“TIME”寄存器,也就是可以直接读取寄存器里面的值,而F3是秒计数寄存器的值,需要通过相关算法下才能得到时间的值。
  本文提供的软件工程里面用到BKP的配置,主要是用于掉电保持RTC数值(第一次上电初始化RTC,后面就不用初始化)。例程是在第一次初始化RTC值为:2016年2月29日 周一 23:59:45(自己可修改)。之后每秒读取一次,并通过串口打印出来。这里可以设置秒中断,不用软件等待1秒才去读取。
  1、概述
  
  通过RTC时钟进来分频之后达到1秒(1Hz),没相应一次时间更新RTC时钟寄存器(RTC_TR、RTC_DR),我们读取的数字就会更改。如果配置了中断,相应事件的时候,中断也会响应。如果配置了闹钟,同样达到了闹钟设定的值也会响应闹钟。
  RTC的时钟源有3个:LSE(32.768kHz);LSI(40kHz);HSE/32。
  
  2、准备工作
  查看STM32f030x数据手册
  了解USART的运行原理
  查看STM32F030开发板原理图和封装图
  电脑装有keil等编译软件
  3、寄存器说明
  RTC 时间寄存器 (RTC_TR)
  
  RTC 日期寄存器 (RTC_DR)
  
  RTC 控制寄存器 (RTC_CR)
  
  
  
  RTC 初始化和状态寄存器 (RTC_ISR)
  
  
  RTC 预分频器寄存器 (RTC_PRER)
  
  RTC alarm A 寄存器 (RTC_ALRMAR)
  
  
  RTC 亚秒寄存器 (RTC_SSR)
  
  RTC 移位控制寄存器 (RTC_SHIFTR)
  
  RTC 写保护寄存器 (RTC_WPR)
  
  RTC 校准寄存器 (RTC_CALR)
  
  
  RTC 侵入和复用功能配置寄存器 (RTC_TAFCR)
  
  
  
  
  RTC 备份寄存器 (RTC_BKPxR)
  
  4、RTC配置
  ①代码讲解
  void RTC_Config(void)
  {
  #if defined (RTC_CLOCK_SOURCE_LSI)
  RCC_LSICmd(ENABLE); /*启动LSI晶振*/
  while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); /*等待LSI就绪*/
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); /*选择LSI时钟*/
  /*RTC_LSI 为40kHz RTC_LSI = SynchPrediv * AsynchPrediv*/
  SynchPrediv = 0x18F;
  AsynchPrediv = 0x63;
  #elif defined (RTC_CLOCK_SOURCE_LSE)
  RCC_LSEConfig(RCC_LSE_ON); /*启动LSE晶振*/
  while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); /*等待LSE就绪*/
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); /*选择LSE时钟*/
  /*RTC_LSE 为32.768kHz RTC_LSI = SynchPrediv * AsynchPrediv*/
  SynchPrediv = 0xFF;
  AsynchPrediv = 0x7F;
  #else
  #error Please select the RTC Clock source inside the main.c file
  #endif
  RCC_RTCCLKCmd(ENABLE); /*使能RTC */
  RTC_WaitForSynchro(); /*等待同步 */
  void RTC_Initializes(void)
  {
  RTC_DateTimeTypeDef RTC_DateTimeStructure;
  RTC_InitTypeDef RTC_InitStructure;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  PWR_BackupAccessCmd(ENABLE); /*允许操作RTC*/
  if(RTC_ReadBackupRegister(RTC_BKP_DR0) != RTC_FLAG_BKP)
  {
  RTC_Config(); /*配置RTC*/
  RTC_InitStructure.RTC_AsynchPrediv = AsynchPrediv;
  RTC_InitStructure.RTC_SynchPrediv = SynchPrediv;
  RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
  if(RTC_Init(&RTC_InitStructure) == ERROR)
  {
  while(1); /*初始化失败*/
  }
  RTC_DateTimeStructure.Year = 16;
  RTC_DateTimeStructure.Month = 2;
  RTC_DateTimeStructure.Date = 29;
  RTC_DateTimeStructure.Week = 1;
  RTC_DateTimeStructure.Hour = 23;
  RTC_DateTimeStructure.Minute = 59;
  RTC_DateTimeStructure.Second = 45;
  RTC_SetDateTime(RTC_DateTimeStructure); /*首次初始化RTC(2016年6月5日 周七 12:00:00)*/
  RTC_WriteBackupRegister(RTC_BKP_DR0, RTC_FLAG_BKP);
  }
  else
  {
  #ifdef RTC_CLOCK_SOURCE_LSI
  RCC_LSICmd(ENABLE);
  #endif
  RTC_WaitForSynchro(); /*等待RTC与RTC_APB时钟同步*/
  }
  }
  /************************************************
  函数名称 : RTC_DateRegulate
  功 能 : RTC日期矫正
  参 数 : RTC_DateTimeStructure -- RTC结构体
  返 回 值 : RTC_OK ----------------- 成功
  RTC_ERR ---------------- 错误
  作 者 : Huang Fugui
  *************************************************/
  RTC_RESULT RTC_DateRegulate(RTC_DateTimeTypeDef RTC_DateTimeStructure)
  {
  RTC_DateTypeDef RTC_DateStructure;
  RTC_DateStructure.RTC_Year = RTC_DateTimeStructure.Year;
  RTC_DateStructure.RTC_Month = RTC_DateTimeStructure.Month;
  RTC_DateStructure.RTC_Date =RTC_DateTimeStructure.Date;
  RTC_DateStructure.RTC_WeekDay = RTC_DateTimeStructure.Week;
  if(RTC_SetDate(RTC_Format_BIN, &RTC_DateStructure) == SUCCESS)
  {
  return RTC_OK;
  }
  else
  {
  return RTC_ERR;
  }
  }
  /************************************************
  函数名称 : RTC_TimeRegulate
  功 能 : RTC时间矫正
  参 数 : RTC_DateTimeStructure -- RTC结构体
  返 回 值 : RTC_OK ----------------- 成功
  RTC_ERR ---------------- 错误
  作 者 : Huang Fugui
  *************************************************/
  RTC_RESULT RTC_TimeRegulate(RTC_DateTimeTypeDef RTC_DateTimeStructure)
  {
  RTC_TimeTypeDef RTC_TimeStructure;
  RTC_TimeStructure.RTC_H12 = RTC_H12_AM;
  RTC_TimeStructure.RTC_Hours = RTC_DateTimeStructure.Hour;
  RTC_TimeStructure.RTC_Minutes = RTC_DateTimeStructure.Minute;
  RTC_TimeStructure.RTC_Seconds = RTC_DateTimeStructure.Second;
  if(RTC_SetTime(RTC_Format_BIN, &RTC_TimeStructure) == SUCCESS)
  {
  return RTC_OK;
  }
  else
  {
  return RTC_ERR;
  }
  }
  /************************************************
  函数名称 : RTC_SetDateTime
  功 能 : RTC日期时间设置
  参 数 : RTC_DateTimeStructure -- RTC结构体
  返 回 值 : RTC_OK ----------------- 成功
  RTC_ERR ---------------- 错误
  作 者 : Huang Fugui
  *************************************************/
  RTC_RESULT RTC_SetDateTime(RTC_DateTimeTypeDef RTC_DateTimeStructure)
  {
  if(RTC_ERR == RTC_DateRegulate(RTC_DateTimeStructure))
  {
  return RTC_ERR;
  }
  if(RTC_ERR == RTC_TimeRegulate(RTC_DateTimeStructure))
  {
  return RTC_ERR;
  }
  return RTC_OK;
  }
  /************************************************
  函数名称 : RTC_GetDateTime
  功 能 : 读取RTC日期时间(含日历、星期)
  参 数 : RTC_DateTimeStructure -- RTC结构体
  返 回 值 : 无
  作 者 : Huang Fugui
  *************************************************/
  void RTC_GetDateTime(RTC_DateTimeTypeDef *RTC_DateTimeStructure)
  {
  RTC_DateTypeDef RTC_DateStructure;
  RTC_TimeTypeDef RTC_TimeStructure;
  RTC_GetDate(RTC_Format_BIN, &RTC_DateStructure);
  RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);
  RTC_DateTimeStructure-》Year = RTC_DateStructure.RTC_Year;
  RTC_DateTimeStructure-》Month = RTC_DateStructure.RTC_Month;
  RTC_DateTimeStructure-》Date = RTC_DateStructure.RTC_Date;
  RTC_DateTimeStructure-》Week = RTC_DateStructure.RTC_WeekDay;
  RTC_DateTimeStructure-》Hour = RTC_TimeStructure.RTC_Hours;
  RTC_DateTimeStructure-》Minute = RTC_TimeStructure.RTC_Minutes;
  RTC_DateTimeStructure-》Second = RTC_TimeStructure.RTC_Seconds;
  }
举报

更多回帖

发帖
×
20
完善资料,
赚取积分