五.STM32F030C8T6 MCU开发之RTC模块基础例程
创始人
2024-02-03 11:21:53
0

五.STM32F030C8T6 MCU开发之RTC模块基础例程

文章目录

  • 五.STM32F030C8T6 MCU开发之RTC模块基础例程
    • 0.总体功能概述
    • 1.RTC硬件介绍
      • 1.1日历的功能
      • 1.2 闹钟输出
      • 1.3 入侵检测
      • 1.4 时间戳事件检测
    • 2.RTC软件配置
      • 2.1.RTC 模块初始化配置
      • 2.2 RTC 开始时间配置
        • 2.2.1RTC 年月日 时分秒配置
      • 2.3 RTC时间获取
    • 3.RTC 验证例程
    • 4.总结
      • 4.1RTC模块只是用于时间计算可以不需要开中断。
      • 4.2 rtc只初始化一次即可?

0.总体功能概述

使用STD库–en.stm32f0_stdperiph_lib_v1.6.0。

如果需要年月日时分秒的时间记录,之前开发51单片机上面外挂一个类似DS1302的时钟芯片,再加上时间芯片的外围电路。但现在MCU不再需要这么干了。因为在STM32的内部就已经集成了年月日时分秒的时钟电路–也就是实时时钟(RTC)。

本例程将RTC时间调整为当前时间,并特定格式从串口输出,每1s输出一次;

1.RTC硬件介绍

RTC (Real Time Clock):实时时钟
实时时钟是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。
RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒后, RTC的设置和时间维持不变。
在这里插入图片描述

系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操作。执行以下操作将使能对后备寄存器和RTC的访问:
● 设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟
● 设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问。

在这里插入图片描述

实时时钟(RTC)是一个独立的定时器。

1.1日历的功能

STM32 的 RTC 模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。

1.2 闹钟输出

当 RTC 运行的时间跟预设的闹钟时间相同的时候,相应的标志位 ALRAF(在 RTC_ISR 寄存器中)和 ALRBF 会置 1。可以作为备忘提醒功能。
如果使能了闹钟输出(由 RTC_CR 的 OSEL[0:1]位控制),则 ALRAF 和 ALRBF 会连接到闹钟输出引RTC_ALARM.

RTC_ALARM 最终连接到 RTC 的外部引脚 RTC_AF1(即 PC13),输出的极性由 RTC_CR 寄存器的 POL 位配置,可以是高电平或者低电平。

1.3 入侵检测

RTC 自带两个入侵检测引脚RTC_TAMP1 的RTC_AF1(PC13)和 RTC__TAMP2的RTC_AF2(PA0)。这两个输入既可配置为边沿检测,也可配置为带过滤的电平检测。当检测到外部事件时,可复位备份寄存器,共80个字节,可用于记录用户数据。备份寄存器不会在系统复位或电源复位时复位,也不会在器件从待机模式唤醒时复位。

1.4 时间戳事件检测

为了记录外部紧急事件触发的时间。时间戳复用功能 (RTC_TS) 可映射到 RTC_AF1 或 RTC_AF2,当发生外部的入侵事件时,即发生时间戳事件时, RTC_ISR 寄存器中的时间戳标志位 (TSF) 将置 1,日历会保存到时间戳寄存器( RTC_TSSSR、RTC_TSTR 和RTC_TSDR)中。

2.RTC软件配置

配置当前时间:时间可以采取24小时格式,也可以采用12小时格式,默认采用24小时格式。

配置时间时,还会设置日期格式,是采用BCD或者二进制。

建议采用二进制即可,可以直接填入时间数值。

第一,定义一个时间的起点,比如2000年1月1日,0点0分0秒。这里要多说一句,其实这个起点可以随便定义,0也没关系。但网络上通常的做法是1970年的1月1日,至于为什么,可以了解时间戳的概念。

第二,STM32并没有专门的记录分钟、小时、日、月、年的寄存器,换句话说,他只是记录了从时间起点(计数器的初值)到当前时间的总秒数,并且能在掉电情况下持续计数运行。要想得到年、月、日信息,是需要我们自己写函数实现的。这里总感觉STM32干得有猛,很粗鲁的样子,上电的时候直接给年、月、日的变量赋值,想要哪年哪月哪日,就直接赋值,然后在这个基础上累加时间,并不断更新,这样就确定了年、月、日的信息。

但别忘了,这是在CPU上电程序运行的情况下进行的,一旦CPU掉电,程序也不再运行,年、月、日信息就不再更新。此时在工作的,只有那个32位的秒计数器。

第三,要想再次上电后正确显示年、月、日等信息,就需要上电后重新调用自己写的这个函数,根据初始化时的年、月、日初值和计数器的当前值,输出当前时间信息。

RTC一般有单独的外部电池供电。

2.1.RTC 模块初始化配置

可以选择以下三种RTC的时钟源:
— HSE时钟除以128;
— LSE振荡器时钟;
— LSI振荡器时钟(详见6.2.8节RTC时钟)。

RTC_CLOCK_SOURCE_LSE 使用外部 32.768 时钟源

RTC_CLOCK_SOURCE_LSI 使用内部RC 32.768 时钟源

	/*** @brief  Configure the RTC peripheral by selecting the clock source.* @param  None* @retval None*/
static void RTC_Config(void)
{/* Enable the PWR clock */RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);/* Allow access to RTC */PWR_BackupAccessCmd(ENABLE);#if defined (RTC_CLOCK_SOURCE_LSI)  /* LSI used as RTC source clock*/
/* The RTC Clock may varies due to LSI frequency dispersion. */   /* Enable the LSI OSC */ RCC_LSICmd(ENABLE);/* Wait till LSI is ready */  while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET){}/* Select the RTC Clock Source */RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);SynchPrediv = 0x18F;AsynchPrediv = 0x63;#elif defined (RTC_CLOCK_SOURCE_LSE) /* LSE used as RTC source clock *//* Enable the LSE OSC */RCC_LSEConfig(RCC_LSE_ON);/* Wait till LSE is ready */  while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET){}/* Select the RTC Clock Source */RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);SynchPrediv = 0xFF;AsynchPrediv = 0x7F;#else#error Please select the RTC Clock source inside the main.c file
#endif /* RTC_CLOCK_SOURCE_LSI *//* Enable the RTC Clock */RCC_RTCCLKCmd(ENABLE);/* Wait for RTC APB registers synchronisation */RTC_WaitForSynchro();
}

2.2 RTC 开始时间配置

    /* Configure the RTC data register and RTC prescaler */RTC_InitStructure.RTC_AsynchPrediv = AsynchPrediv;RTC_InitStructure.RTC_SynchPrediv = SynchPrediv;RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;printf("rtc init\r\n");/* Check on RTC init */if (RTC_Init(&RTC_InitStructure) == ERROR){}printf("rtc RTC_TimeRegulate\r\n");RTC_TimeRegulate(); 

2.2.1RTC 年月日 时分秒配置

static void RTC_TimeRegulate(void)
{RTC_TimeTypeDef RTC_TimeStructure;RTC_DateTypeDef RTC_DateStructure;/* Set Time hh:mm:ss */RTC_TimeStructure.RTC_H12     = RTC_H12_AM;RTC_TimeStructure.RTC_Hours   = 0x08;  RTC_TimeStructure.RTC_Minutes = 0x10;RTC_TimeStructure.RTC_Seconds = 0x00;RTC_SetTime(RTC_Format_BCD, &RTC_TimeStructure);/* Set Date Week/Date/Month/Year */RTC_DateStructure.RTC_WeekDay = 01;RTC_DateStructure.RTC_Date = 0x31;RTC_DateStructure.RTC_Month = 0x12;RTC_DateStructure.RTC_Year = 0x12;RTC_SetDate(RTC_Format_BCD, &RTC_DateStructure);/* Write BkUp DR0 */RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);
}

2.3 RTC时间获取

void RTC_TimeShow(void)
{/* Get the current Time */RTC_GetTime(RTC_Format_BIN, &aShowTime);RTC_GetDate(RTC_Format_BIN, &RTC_DateStructure);}

3.RTC 验证例程

每隔1秒获取RTC时间,查看RTC时间实际变化

int rtc_main(void)
{unsigned int s_time = 0;unsigned int e_time = 0;RTC_Config();/* Configure the RTC data register and RTC prescaler */RTC_InitStructure.RTC_AsynchPrediv = AsynchPrediv;RTC_InitStructure.RTC_SynchPrediv = SynchPrediv;RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;printf("rtc init\r\n");/* Check on RTC init */if (RTC_Init(&RTC_InitStructure) == ERROR){}printf("rtc RTC_TimeRegulate\r\n");RTC_TimeRegulate(); printf("rtc start\r\n");while(1){	   s_time = get_curtime();while(1){e_time = get_curtime();	if(e_time>s_time ){if((e_time - s_time) >=1000){break;}}}printf("RTC_TimeShow\r\n");RTC_TimeShow();printf("RTC_Hours=%d:%d:%d\r\n",aShowTime.RTC_Hours,aShowTime.RTC_Minutes,aShowTime.RTC_Seconds);printf("y m d=%d %d %d\r\n",RTC_DateStructure.RTC_Year,RTC_DateStructure.RTC_Month,RTC_DateStructure.RTC_Date);}		
}

4.总结

4.1RTC模块只是用于时间计算可以不需要开中断。

如果需要用alarm功能 才需要开.

4.2 rtc只初始化一次即可?

每次上电后会读取BKP_DR1的值,判断是否为第一次启动,如果是,则配置RTC。换句话说,出现问题时,这个判断肯定出现问题,也就是备份寄存器的值丢失,导致重复配置RTC!

备份寄存器的值丢失原因:

1》 VDD和VBAT同时掉电

2》 客户代码意外修改

3》 检测到入侵事件

;
}
}


## 4.总结### 4.1RTC模块只是用于时间计算可以不需要开中断。如果需要用alarm功能 才需要开.### 4.2 rtc只初始化一次即可?每次上电后会读取BKP_DR1的值,判断是否为第一次启动,如果是,则配置RTC。换句话说,出现问题时,这个判断肯定出现问题,也就是备份寄存器的值丢失,导致重复配置RTC!备份寄存器的值丢失原因:1》 VDD和VBAT同时掉电2》 客户代码意外修改3》 检测到入侵事件首先怀疑是VBAT引脚。要是VBAT再现异常,RTC重新配置就很正常。

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...