学习STM32第十八天

RTC外设详解

一、RTC实时时钟实验

RTC配置流程如下

  • 解锁备份域写保护
    RTC核心寄存器在备份域内,备份域归属PWR,因此需要开启PWR时钟再使能备份与中寄存器的写访问。
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);					//电源控制寄存器在APB1总线
	PWR_BackupAccessCmd(ENABLE);										//使能对备份域的访问

  • 设置时钟源
    如板载外部RTC晶振,则选择LSE时钟,同时需要对RTC时钟源配置分频系数以及时制。
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);								//RTC时钟源
//若LSE无法起振会卡死在此,则设置为内部低速时钟
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
  • 开启RTC外设
    RTC模块是一个独立的实时时钟模块,可以提供高精度时间计数和时钟功能。在配置RTC之前,一般需要等待RTC寄存器更新的同步,即确保前一个RTC操作的设置已经完成并生效
	RCC_RTCCLKCmd(ENABLE);												//使能RTC
	RTC_WaitForSynchro();												//等待RTC寄存器更新同步

  • 配置日历时间
    结构体RTC_TimeTypeDefRTC_DateTypeDef可以配置RTC外设的日历时间,再通过相应的函数将配置的参数设置到RTC外设寄存器中。先进行设置,后进行读取。

二、代码实现

  1. 初始化函数
void MyRTC_Init()
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);					//电源控制寄存器在APB1总线
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);             //备份域寄存器在AHB1总线
	
	PWR_BackupAccessCmd(ENABLE);										//使能对备份域的访问
	
	RCC_LSEConfig(RCC_LSE_ON);											//开启LSE时钟
	while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);					//等待LSE稳定启动
	
	RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);								//RTC时钟源
	RCC_RTCCLKCmd(ENABLE);												//使能RTC
	RTC_WaitForSynchro();												//等待RTC寄存器更新同步,包含对上一次写入操作完成的等待
	
	if(RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x2002)					//查看RTC是否完成初始化
	{
		MyRTCTimeConfig(24, 4, 24, 3, 16, 59, 20, RTC_H12_AM);
	}
	PWR_BackupAccessCmd(DISABLE); 										//关闭备份域访问
}
  1. 辅助函数
void MyRTCTimeConfig(uint8_t year, uint8_t month, uint8_t date, uint8_t week,
	uint8_t hour, uint8_t minute, uint8_t second, uint8_t RTC_H12)
{
	RTC_WriteProtectionCmd(DISABLE);									//打开写保护
	
	//配置RTC时钟,LSE = 32.768KHz -》 32768 = 128 * 256
	RTC_InitTypeDef RTC_InitStructure;
	RTC_EnterInitMode();												//使能RTC编辑模式
	RTC_InitStructure.RTC_AsynchPrediv = 0x7F;							//设置7位异步分频值,
	RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;				//设置为24小时制
	RTC_InitStructure.RTC_SynchPrediv = 0xFF;							//设置15位同步分频值
	RTC_Init(&RTC_InitStructure);

	//时间设定
	RTC_TimeTypeDef RTC_TimeStructure;
	RTC_TimeStructure.RTC_H12 = RTC_H12;
	RTC_TimeStructure.RTC_Hours = hour;
	RTC_TimeStructure.RTC_Minutes = minute;
	RTC_TimeStructure.RTC_Seconds = second;
	RTC_SetTime(RTC_Format_BIN, &RTC_TimeStructure);					//BCD格式设定时间
	//日期设定
	RTC_DateTypeDef RTC_DataStructure;
	RTC_DataStructure.RTC_Date = date;
	RTC_DataStructure.RTC_Month = month;
	RTC_DataStructure.RTC_WeekDay = week;
	RTC_DataStructure.RTC_Year = year;
	RTC_SetDate(RTC_Format_BCD, &RTC_DataStructure);					//BCD格式设定日期

	RTC_ExitInitMode();													//关闭RTC编辑模式
	
	RTC_WriteBackupRegister(RTC_BKP_DR0, 0x2024);						//设定一个初始化完成标志
	RTC_WriteProtectionCmd(ENABLE);										//使能写保护
}

/*			BCD转换为十进制			*/
uint8_t BCDtoDecimal(int BCDnum)
{
	uint8_t decimal = 0, temp = 1, num = 0;
	if(BCDnum >= 0x0A)													//如果大于等于10
	{
		while(BCDnum > 0)
		{
			num = BCDnum % 16;
			decimal += num * temp;
			temp *= 10;
			BCDnum /= 16;
		}
		return decimal;
	}
	return BCDnum;
}

/*			读取时间			*/
RTC_time MyRTCTimeShow(void)
{
    RTC_TimeTypeDef RTC_TimeStructure;      
    // 获取RTC日期
    RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);  
	
	RTC_time Time_temp;
	Time_temp.Hours = RTC_TimeStructure.RTC_Hours;
	Time_temp.Minutes = RTC_TimeStructure.RTC_Minutes;
	Time_temp.Seconds = RTC_TimeStructure.RTC_Seconds;
	return Time_temp;
}	
/*			读取日期			*/
RTC_date MyRTCDateShow()
{
	RTC_DateTypeDef RTC_DateStructure;
	// 获取RTC时间
    RTC_GetDate(RTC_Format_BIN, &RTC_DateStructure);
	
	RTC_date Date_temp;
	Date_temp.Date = RTC_DateStructure.RTC_Date;
	Date_temp.Month = RTC_DateStructure.RTC_Month;
	Date_temp.Year = RTC_DateStructure.RTC_Year;
	return Date_temp;
}
上一篇:MCU功耗测量


下一篇:k8s之etcd