IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32Cube STM32L053配置RTC时钟详解 -> 正文阅读

[嵌入式]STM32Cube STM32L053配置RTC时钟详解

先看下STM32L053的RTC时钟,这里没有外部晶振用的是内部LSE,频率37KHz

?通过Cube配置RTC,启用日历和时钟,我这里开启了一个RTC中断,用来唤醒休眠中的单片机

STM32CubeMX默认填入的分频是使用32.768KHz的,但是内部振荡器是32KHz的,所以估计都是推荐使用外部晶振,使用内部振荡器的自己按公式重新计算分频值

公式如下:

RTC时钟频率 = RTC时钟源 / ((Asynchronous Predivider value + 1) * (Synchronous Predivider value + 1))

使用公式

32.768KHz / ((127+1)*(255+1)) = 1Hz,也就是1秒

年是从1970年算起的,其他月日时分秒以及24或者12小时制没什么好说的

数据格式Data Format,我使用Binary data format

stm32定义了RTC_FORMAT_BIN和RTC_FORMAT_BCD两种格式

RTC_FORMAT_BIN:为10进制,RTC_FORMAT_BCD为16进制,开始我也是这样认为的,然后并不是

看一下stm32l0xx_II_rtc.h头文件中对月份的定义:

/** @defgroup RTC_LL_EC_WEEKDAY  WEEK DAY
  * @{
  */
#define LL_RTC_WEEKDAY_MONDAY              ((uint8_t)0x01U) /*!< Monday    */
#define LL_RTC_WEEKDAY_TUESDAY             ((uint8_t)0x02U) /*!< Tuesday   */
#define LL_RTC_WEEKDAY_WEDNESDAY           ((uint8_t)0x03U) /*!< Wednesday */
#define LL_RTC_WEEKDAY_THURSDAY            ((uint8_t)0x04U) /*!< Thrusday  */
#define LL_RTC_WEEKDAY_FRIDAY              ((uint8_t)0x05U) /*!< Friday    */
#define LL_RTC_WEEKDAY_SATURDAY            ((uint8_t)0x06U) /*!< Saturday  */
#define LL_RTC_WEEKDAY_SUNDAY              ((uint8_t)0x07U) /*!< Sunday    */
/**
  * @}
  */

/** @defgroup RTC_LL_EC_MONTH  MONTH
  * @{
  */
#define LL_RTC_MONTH_JANUARY               ((uint8_t)0x01U)  /*!< January   */
#define LL_RTC_MONTH_FEBRUARY              ((uint8_t)0x02U)  /*!< February  */
#define LL_RTC_MONTH_MARCH                 ((uint8_t)0x03U)  /*!< March     */
#define LL_RTC_MONTH_APRIL                 ((uint8_t)0x04U)  /*!< April     */
#define LL_RTC_MONTH_MAY                   ((uint8_t)0x05U)  /*!< May       */
#define LL_RTC_MONTH_JUNE                  ((uint8_t)0x06U)  /*!< June      */
#define LL_RTC_MONTH_JULY                  ((uint8_t)0x07U)  /*!< July      */
#define LL_RTC_MONTH_AUGUST                ((uint8_t)0x08U)  /*!< August    */
#define LL_RTC_MONTH_SEPTEMBER             ((uint8_t)0x09U)  /*!< September */
#define LL_RTC_MONTH_OCTOBER               ((uint8_t)0x10U)  /*!< October   */
#define LL_RTC_MONTH_NOVEMBER              ((uint8_t)0x11U)  /*!< November  */
#define LL_RTC_MONTH_DECEMBER              ((uint8_t)0x12U)  /*!< December  */

比如12月份RTC_MONTH_DECEMBER的值是等于0x12的,转成10进制等于18,也就是RTC_FORMAT_BCD也不是16进制,只是用了16进制的样式,0x12不看0x直接看数字部分,就是12月份

再来看看stm32内部的两种格式的转换函数

/**
  * @brief  Helper macro to convert a value from 2 digit decimal format to BCD format
  * @param  __VALUE__ Byte to be converted
  * @retval Converted byte
  */
#define __LL_RTC_CONVERT_BIN2BCD(__VALUE__) (uint8_t)((((__VALUE__) / 10U) << 4U) | ((__VALUE__) % 10U))

/**
  * @brief  Helper macro to convert a value from BCD format to 2 digit decimal format
  * @param  __VALUE__ BCD value to be converted
  * @retval Converted byte
  */
#define __LL_RTC_CONVERT_BCD2BIN(__VALUE__) (uint8_t)((((uint8_t)((__VALUE__) & (uint8_t)0xF0U) >> (uint8_t)0x4U) * 10U ) + ((__VALUE__) & (uint8_t)0x0FU))

配置完成,生成工程

找到static void MX_RTC_Init(void)函数,在MX_RTC_Init后,使用RTC的后备寄存器保存是否初始化过时间的标志,RTC的后备寄存器也是后备电源供电的,所以主电源断电后数据还在,也可以用这些寄存器保存数据,读写函数如下:

#define RTC_BKP_DATE_TIME_UPDTATED ((uint32_t)0x32F2)
unsigned char const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表   
unsigned char rtc_get_week(unsigned short int year,unsigned char month, unsigned char day)
{
	unsigned short int temp2;
	unsigned char yearH, yearL;

	yearH = year/100; yearL = year%100;
	
	// 如果为21世纪,年份数加100
	if (yearH>19) yearL+=100;
	
	// 所过闰年数只算1900年之后的
	temp2 = yearL + yearL/4;
	temp2 = temp2 % 7;
	temp2 = temp2 + day + table_week[month-1];
	
	if (yearL%4 == 0&&month<3) temp2--;
	
	return(temp2 % 7);
}

void rtc_set(LL_RTC_DateTypeDef *date,LL_RTC_TimeTypeDef *time)
{	
	LL_RTC_TIME_Init(RTC, LL_RTC_FORMAT_BIN, time);
	LL_RTC_DATE_Init(RTC, LL_RTC_FORMAT_BIN, date);	
	LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, RTC_BKP_DATE_TIME_UPDTATED);
}

void rtc_get(LL_RTC_DateTypeDef *date,LL_RTC_TimeTypeDef *time)
{
	time->Hours   = __LL_RTC_CONVERT_BCD2BIN(LL_RTC_TIME_GetHour(RTC));
	time->Minutes = __LL_RTC_CONVERT_BCD2BIN(LL_RTC_TIME_GetMinute(RTC));
	time->Seconds = __LL_RTC_CONVERT_BCD2BIN(LL_RTC_TIME_GetSecond(RTC));
	date->Year  = __LL_RTC_CONVERT_BCD2BIN(LL_RTC_DATE_GetYear(RTC));
	date->Month = __LL_RTC_CONVERT_BCD2BIN(LL_RTC_DATE_GetMonth(RTC));
	date->Day   = __LL_RTC_CONVERT_BCD2BIN(LL_RTC_DATE_GetDay(RTC));
}

需要屏蔽2个函数

//LL_RCC_ForceBackupDomainReset();
//LL_RCC_ReleaseBackupDomainReset();

测试代码

void rtc_read(void)
{	
	LL_RTC_DateTypeDef curData;
	LL_RTC_TimeTypeDef curTime;
		
	rtc_get(&curData, &curTime);
#ifdef ENABLE_PRINT
	printf("MX_RTC_Init:Date time: %d-%02d-%02d weekData:%d %02d:%02d:%02d\r\n"                   
                   , 1970 + curData.Year, curData.Month, curData.Day, curData.WeekDay
                   , curTime.Hours, curTime.Minutes, curTime.Seconds);
#endif
	curData.WeekDay = rtc_get_week((curData.Year+2000), curData.Month, curData.Day );
	
	curData.Year = 51;
	curData.Month = 7;
	curData.Day = 4;	
	curData.WeekDay = rtc_get_week((curData.Year+2000), curData.Month, curData.Day );
	
	curTime.Hours = 9;
	curTime.Minutes = 29;
	curTime.Seconds = 1;	
	
	rtc_set(&curData, &curTime);	
	#ifdef ENABLE_PRINT
	printf("MX_RTC_Init:Date time: %d-%02d-%02d weekData:%d %02d:%02d:%02d\r\n"                   
                   , 1970 + curData.Year, curData.Month, curData.Day, curData.WeekDay
                   , curTime.Hours, curTime.Minutes, curTime.Seconds);
#endif
	rtc_get(&curData, &curTime);	
	#ifdef ENABLE_PRINT
	printf("MX_RTC_Init:Date time: %d-%02d-%02d weekData:%d %02d:%02d:%02d\r\n"                   
                   , 1970 + curData.Year, curData.Month, curData.Day, curData.WeekDay
                   , curTime.Hours, curTime.Minutes, curTime.Seconds);
#endif
	rtc_get(&curData, &curTime);
	#ifdef ENABLE_PRINT
	printf("MX_RTC_Init:Date time: %d-%02d-%02d weekData:%d %02d:%02d:%02d\r\n"                   
                   , 1970 + curData.Year, curData.Month, curData.Day, curData.WeekDay
                   , curTime.Hours, curTime.Minutes, curTime.Seconds);
#endif
}
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-12-08 13:58:41  更:2021-12-08 14:00:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 2:04:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码