16.STM32RTC实时时钟知识与实验

本文详细介绍了STM32的实时时钟(RTC)功能,包括RTC的硬件结构、工作原理、寄存器配置以及HAL库的使用方法。通过RTC初始化、时间日期设置、闹钟和唤醒功能的配置,展示了如何在STM32中实现精确的时间管理和中断唤醒功能。同时,提供了RTC相关的代码示例,包括RTC的初始化、时间日期设置、闹钟设置和唤醒设置等。
摘要由CSDN通过智能技术生成

1.实时时钟

RTC是一个独立的BCD定时器/计数器。RTC提供一个日历时钟,两个可编程闹钟中断,以及一个具有中断功能的周期性可编程唤醒标志。RTC还包括用于管理低功耗模式的自动唤醒单元。
有两个32位的寄存器,包含二进制吗十进制格式BCD的秒,分,小时,星期,月份,年份。还提供二进制的亚秒。
系统还可以自动将月份的天数补偿到28,29,30,31天,夏令补时。等等等功能

2.实时时钟框图

请添加图片描述
上部分
时钟来源可以是LES,LSI,HSE。
7位预分频PTC_PRER(默认128预分频)后产生ck_apre(默认到256HZ)
ck_apre经过校准后的RTC_CALIBR在经过RTC_SSR的15位预分频(通常值位256),产生ck_spre1hz时钟
日历寄存器里面有RTC_TR,RTC_DR记时间与日期,影子寄存器会把当前的日历记住。这个三个寄存器确认了当前的时间
还有两个闹钟A与B,有专门的时间秒与亚秒寄存器,相等的时候会产生闹钟中断
亚秒是没有经过RTC_PRER分频的周期,就是256HZ,一个周期就是1/256s
下部分
HSE_RTC的时钟经过分频后产生一个时钟,还有一个CK_SPRE时钟可以选择。
根据选择的时钟然后,装入重装值不断下降直到溢出,就产生唤醒

3.实时时钟寄存器

1.BLP备份寄存器
共有20个32位寄存器,用于保存系统配置和相关标志位
这些寄存器有一个纽扣电池一直供电,不会消失。
2.RTC常用寄存器
请添加图片描述
3.预分频寄存器RTC_PRER
请添加图片描述
两个预分频,一个分频为亚秒,亚秒的时钟分频为为秒
4.时间寄存器RTC_TR
请添加图片描述

5.日期寄存器RTC_DR
请添加图片描述

6.亚秒寄存器RTC_SSR
请添加图片描述7.控制寄存器RTC_CR
请添加图片描述
太多了,就列了一部分
请添加图片描述

8.初始化和状态寄存器RTC_ISR
就是状态标志,表面现在日历等的状态
请添加图片描述
9.唤醒定时器寄存器RTC_WUTR
请添加图片描述10.闹钟定时器寄存器RTC_ALRMAR/RTC_ALRMBR
请添加图片描述

4.实时时钟HAL库函数

1.RTC初始化函数
*HAL_RTC_Init(RTC_HandleTypeDef hrtc);
初始化函数
请添加图片描述
第一个参数24小时还是12小时格式
异步同步参数
使能闹钟,唤醒等
输出极性与输出类型(唤醒与闹钟的输出)
*HAL_RTC_MspInit(RTC_HandleTypeDef hrtc);
回调函数
不说了,时钟使能与开启中断等
2.时间操作函数
**HAL_RTC_SetTime(RTC_HandleTypeDef hrtc, RTC_TimeTypeDef sTime, uint32_t Format);
时间设置函数
第一个参数就是配置信息结构体
第二个参数就是时间结构体
请添加图片描述
**HAL_RTC_GetTime(RTC_HandleTypeDef hrtc, RTC_TimeTypeDef sTime, uint32_t Format);
获取时间,获取到sTime结构体
3.日期操作函数
**HAL_RTC_SetDate(RTC_HandleTypeDef hrtc, RTC_DateTypeDef sDate, uint32_t Format);
日期设置
请添加图片描述

**HAL_RTC_GetDate(RTC_HandleTypeDef hrtc, RTC_DateTypeDef sDate, uint32_t Format);
日期获取
获取日期,获取到sDate结构体
这前面四个函数最后都有一个参数,确定是bin还是BCD
4.闹钟操作函数
请添加图片描述
5.周期性唤醒操作函数
请添加图片描述
6.备份区域操作函数
请添加图片描述
7.RTC时钟源操作函数
请添加图片描述
8.RTC中断服务函数
请添加图片描述
有一个Wake中断回调函数没有写

5.实时时钟代码步骤

1.日历一般配置步骤
请添加图片描述
1.使能PWR时钟,后备寄存器的时钟
2.使能后备寄存器,在断电的时候可以存贮配置的时间的信息,在上电的时候就直接读取后备寄存器就行了。
3.配置RTC的时钟源与使能RTC时钟
打开低速外部时钟LSE
RTC设置时钟源为LSE
使能RTC
4.设置RTC各参数
5.设置时间就行了
2.闹钟一般配置步骤
请添加图片描述

3.周期性自动唤醒一般配置步骤
请添加图片描述

6.实时时钟代码

1.日历
rtc.c文件

#include"rtc.h"
RTC_HandleTypeDef hrtc;
void MY_RTC_Set_Time(u8 hour,u8 minutes,u8 seconds)   //设置时间
{
	RTC_TimeTypeDef sTime;
	sTime.Hours=hour;
	sTime.Minutes=minutes;
	sTime.Seconds=seconds;
	sTime.DayLightSaving=RTC_DAYLIGHTSAVING_NONE;   //没有夏令营
	sTime.StoreOperation=RTC_STOREOPERATION_RESET;   //保存上面设置
	sTime.TimeFormat=RTC_HOURFORMAT12_AM;       
	HAL_RTC_SetTime(&hrtc,&sTime,RTC_FORMAT_BIN);
	
}
void MY_RTC_Set_Date(u8 year,u8 month,u8 date,u8 weekDay)  //设置日期
{
	RTC_DateTypeDef sTime;
	sTime.Year=year;
	sTime.Month=month;
	sTime.Date=date;
	sTime.WeekDay=weekDay;   //一个礼拜新期几
	HAL_RTC_SetDate(&hrtc,&sTime,RTC_FORMAT_BIN);
	
}
void MY_RTC_Init(void)
{
	hrtc.Instance=RTC;
	hrtc.Init.HourFormat = RTC_HOURFORMAT_24;  \\24小时制度
	hrtc.Init.AsynchPrediv =0x7f;     //异步分频128
	hrtc.Init.SynchPrediv=0xff;       //同步分频256
	HAL_RTC_Init(&hrtc);
	if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR0)!=11)   //寄存器判断时间是否设置过
	{

			MY_RTC_Set_Date(22,9,17,6);
			MY_RTC_Set_Time(18,31,50);
			HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,11);
	}

	
}

void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc)
{
	RCC_OscInitTypeDef RCC_OscInitStructure; 
	RCC_PeriphCLKInitTypeDef  PeriphClkInit;
	
	__HAL_RCC_PWR_CLK_ENABLE();  //使能PWR时钟
	HAL_PWR_EnableBkUpAccess();   //使能后备寄存器
	
	RCC_OscInitStructure.OscillatorType=RCC_OSCILLATORTYPE_LSE;  //开启了LSE时钟
	RCC_OscInitStructure.LSEState=RCC_LSE_ON;
	HAL_RCC_OscConfig(&RCC_OscInitStructure);       //开启时钟源的函数

	PeriphClkInit.PeriphClockSelection=RCC_PERIPHCLK_RTC;  //功能为RTC
	PeriphClkInit.RTCClockSelection=RCC_RTCCLKSOURCE_LSE;   //设置时钟源
	HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
	__HAL_RCC_RTC_ENABLE();

}

2.闹钟与唤醒时钟

#include"rtc.h"
#include"led.h"
RTC_HandleTypeDef hrtc;
RTC_AlarmTypeDef sAlarm;
void MY_RTC_Set_Time(u8 hour,u8 minutes,u8 seconds)  //时间确定
{
	RTC_TimeTypeDef sTime;
	sTime.Hours=hour;
	sTime.Minutes=minutes;
	sTime.Seconds=seconds;
	sTime.DayLightSaving=RTC_DAYLIGHTSAVING_NONE;      //无需夏命营时间
	sTime.StoreOperation=RTC_STOREOPERATION_RESET;     //保存设置
	sTime.TimeFormat=RTC_HOURFORMAT12_AM;             
	HAL_RTC_SetTime(&hrtc,&sTime,RTC_FORMAT_BIN);
	
}
void MY_RTC_Set_Date(u8 year,u8 month,u8 date,u8 weekDay)     //日期
{
	RTC_DateTypeDef sTime;
	sTime.Year=year;
	sTime.Month=month;
	sTime.Date=date;
	sTime.WeekDay=weekDay;   //一个礼拜新期几
	HAL_RTC_SetDate(&hrtc,&sTime,RTC_FORMAT_BIN);
	
}
void MY_RTC_Init(void)
{
	hrtc.Instance=RTC;
	hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
	hrtc.Init.AsynchPrediv =0x7f;         //异步时钟
	hrtc.Init.SynchPrediv=0xff;           //同步时钟
	HAL_RTC_Init(&hrtc);                 //RTC初始化
	if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR0)!=11)     //寄存器保证设置一次
	{

			MY_RTC_Set_Date(22,9,17,6);
			MY_RTC_Set_Time(18,31,50);
			HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,11);
	}

	
}

void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc)      //初始化IO口,时钟等参数
{
	RCC_OscInitTypeDef RCC_OscInitStructure; 
	RCC_PeriphCLKInitTypeDef  PeriphClkInit;
	
	__HAL_RCC_PWR_CLK_ENABLE();  //使能PWR时钟
	HAL_PWR_EnableBkUpAccess();   //使能后备寄存器
	
	RCC_OscInitStructure.OscillatorType=RCC_OSCILLATORTYPE_LSE;  //开启了LSE时钟
	RCC_OscInitStructure.LSEState=RCC_LSE_ON;   
	HAL_RCC_OscConfig(&RCC_OscInitStructure);                //打开时钟

	PeriphClkInit.PeriphClockSelection=RCC_PERIPHCLK_RTC;  //功能为RTC
	PeriphClkInit.RTCClockSelection=RCC_RTCCLKSOURCE_LSE;   //设置时钟源
	HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);     
	__HAL_RCC_RTC_ENABLE();

}
void MY_RTC_ALAMA_Set(u8 week,u8 hour,u8 minute,u8 second)
{
	sAlarm.Alarm=RTC_ALARM_A;  //A时钟
	sAlarm.AlarmMask = RTC_ALARMMASK_NONE;  //不需要检测的时间
	sAlarm.AlarmDateWeekDaySel=RTC_ALARMDATEWEEKDAYSEL_WEEKDAY;   //按周来
	sAlarm.AlarmDateWeekDay=week;          
	sAlarm.AlarmTime.Hours=hour;
	sAlarm.AlarmTime.Minutes=minute;
	sAlarm.AlarmTime.Seconds=second;
	sAlarm.AlarmTime.SubSeconds=0;
	sAlarm.AlarmSubSecondMask=RTC_ALARMSUBSECONDMASK_NONE; 

	HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);				//使能Alman中断通道
	HAL_NVIC_SetPriority(RTC_Alarm_IRQn,2,2);			//抢占优先级3,子优先级3
	HAL_RTC_SetAlarm_IT(&hrtc,&sAlarm,RTC_FORMAT_BIN);
}
void MY_RTC_WakeUP_Set(u16 cnt)
{
	__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc,RTC_FLAG_WUTWF);
	HAL_RTCEx_SetWakeUpTimer_IT(&hrtc,cnt,RTC_WAKEUPCLOCK_CK_SPRE_16BITS);   //第二个参数计数器的值,第三个选择时钟源
  HAL_NVIC_SetPriority(RTC_WKUP_IRQn,2,3);
  HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn);

	
}

void RTC_Alarm_IRQHandler(void)
{
	 HAL_RTC_AlarmIRQHandler(&hrtc);
}
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
	printf("闹钟到啦\r\n");
}

void RTC_WKUP_IRQHandler(void)
{
	 HAL_RTCEx_WakeUpTimerIRQHandler(&hrtc);

}
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{
	//printf("WakeUP!\r\n");
	LED0=!LED0;
	LED1=!LED1;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值