本文主要是介绍学习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); //使能RTCRTC_WaitForSynchro(); //等待RTC寄存器更新同步
- 配置日历时间
结构体RTC_TimeTypeDef
和RTC_DateTypeDef
可以配置RTC外设的日历时间,再通过相应的函数将配置的参数设置到RTC外设寄存器中。先进行设置,后进行读取。
二、代码实现
- 初始化函数
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); //使能RTCRTC_WaitForSynchro(); //等待RTC寄存器更新同步,包含对上一次写入操作完成的等待if(RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x2002) //查看RTC是否完成初始化{MyRTCTimeConfig(24, 4, 24, 3, 16, 59, 20, RTC_H12_AM);}PWR_BackupAccessCmd(DISABLE); //关闭备份域访问
}
- 辅助函数
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 * 256RTC_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;
}
这篇关于学习STM32第十八天的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!