一、时钟RTC
RTC (Real Time Clock):实时时钟
RTC是个独立的定时器。RTC模块拥有一个连续计数的计数器,在相应的软件配置下,可以提供时钟日历的功能。修改计数器的值可以重新设置当前时间和日期 RTC还包含用于管理低功耗模式的自动唤醒单元。
1.1 简介
实时时钟的缩写是RTC(Real_Time Clock)。RTC 是集成电路,通常称为时钟芯片。 -实时时钟是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。 RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒后, RTC的设置和时间维持不变。 系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操作。执行以下操作将使能对后备寄存器和RTC的访问: ● 设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟 ● 设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问。
1.2 RTC特征
可编程的预分频系数:分频系数最高为220。 ● 32位的可编程计数器,可用于较长时间段的测量。 ● 2个分离的时钟:用于APB1接口的PCLK1和RTC时钟(RTC时钟的频率必须小于PCLK1时钟 频率的四分之一以上)。 ● 可以选择以下三种RTC的时钟源: — HSE时钟除以128; — LSE振荡器时钟; — LSI振荡器时钟(详见6.2.8节RTC时钟)。 ● 2个独立的复位类型: — APB1接口由系统复位; — RTC核心(预分频器、闹钟、计数器和分频器)只能由后备域复位(详见6.1.3节)。 ● 3个专门的可屏蔽中断: — 闹钟中断,用来产生一个软件可编程的闹钟中断。 — 秒中断,用来产生一个可编程的周期性中断信号(最长可达1秒)。 — 溢出中断,指示内部可编程计数器溢出并回转为0的状态。
1.3 RTC组成
APB1接口:用来和APB1总线相连。通过APB1接口可以访问RTC的相关寄存器(预分频值,计数器值,闹钟值)。 RTC核心:由一组可编程计数器组成。分两个主要模块。 第一个是RTC预分频模块,它可以编程产生最长1秒的RTC时间基TR_CLK。如果设置了秒中断允许位,可以产生秒中断。 第二个是32位的可编程计数器,可被初始化为当前时间。系统时间按TR_CLK周期累加并与存储在RTC_ALR寄存器中的可编程时间相比,当匹配时候如果设置了闹钟中断允许位,可以产生闹钟中断。
RTC内核完全独立于APB1接口,软件通过APB1接口对RTC相关寄存器访问。但是相关寄存器只在RTC APB1时钟进行重新同步的RTC时钟的上升沿被更新。所以软件必须先等待寄存器同步标志位(RTC_CRL的RSF位)被硬件置1才读。
二、CubeMX创建工程
- 初始化时间,设置时间为21年11月3号21点3分,周五
三、代码
3.1 重点函数代码
- 可见在stm32f1xx_hal_rtc.h,可以看到以下函数
3.2 修改添加代码
- 在main.c里面添加代码,重写fputc函数,完成printf函数的重定向
int fputc(int ch,FILE *f){
uint8_t temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,2);
return ch;
}
- 在main.c的main函数中定义时间和日期的结构体用来获取时间和日期
RTC_DateTypeDef GetData;
RTC_TimeTypeDef GetTime;
HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);
printf("%02d/%02d/%02d\r\n",2000 + GetData.Year, GetData.Month, GetData.Date);
printf("%02d:%02d:%02d\r\n",GetTime.Hours, GetTime.Minutes, GetTime.Seconds);
printf("\r\n");
HAL_Delay(1000);
三、烧录运行
- 烧录:老规矩,烧录时Boot0一定要置1.
- 运行:Boot0置0,并RESET.
- 实验结果:
四、输出星期
4.1 添加代码
if(GetData.WeekDay==1){
printf("星期一\r\n");
}else if(GetData.WeekDay==2){
printf("星期二\r\n");
}else if(GetData.WeekDay==3){
printf("星期三\r\n");
}else if(GetData.WeekDay==4){
printf("星期四\r\n");
}else if(GetData.WeekDay==5){
printf("星期五\r\n");
}else if(GetData.WeekDay==6){
printf("星期六\r\n");
}else if(GetData.WeekDay==7){
printf("星期日\r\n");
}
4.2 烧录运行
小小的总结
- STM32CubeMX建立项目很方便,基本上完成了一大半的工作,我们只需要添加一些代码就可以了。通过调用HAL库函数,获取时间日期,最后用printf函数输出。
- 仍要注意的是Boot0置1或置0的情况,每次切换都需要RESET一下。
参考文献
- STM32日历读取,设置和输出
- STM32使用RTC(hal)
|