STM32的日历读取、设置和输出

一.了解时钟RTC

RTC是个独立的定时器。RTC模块拥有一个连续计数的计数器,在相应的软件配置下,可以提供时钟日历的功能。修改计数器的值可以重新设置当前时间和日期 RTC还包含用于管理低功耗模式的自动唤醒单元。
在断电情况下 RTC仍可以独立运行 只要芯片的备用电源一直供电,RTC上的时间会一直走。

RTC实质是一个掉电后还继续运行的定时器,从定时器的角度来看,相对于通用定时器TIM外设,它的功能十分简单,只有计时功能(也可以触发中断)。但其高级指出也就在于掉电之后还可以正常运行。

RTC具体流程:
RTCCLK经过RTC_DIV预分频,RTC_PRL设置预分频系数,然后得到TR_CLK时钟信号,我们一般设置其周期为1s,RTC_CNT计数器计数,假如1970设置为时间起点为0s,通过当前时间的秒数计算得到当前的时间。RTC_ALR是设置闹钟时间,RTC_CNT计数到RTC_ALR就会产生计数中断,

RTC_Second为秒中断,用于刷新时间,
RTC_Overflow是溢出中断。
RTC Alarm 控制开关机
RTC时钟选择
使用HSE分频时钟或者LSI的时候,在主电源VDD掉电的情况下,这两个时钟来源都会受到影响,因此没法保证RTC正常工作.所以RTC一般都时钟低速外部时钟LSE,频率为实时时钟模块中常用的32.768KHz,因为32768 = 2^15,分频容易实现,所以被广泛应用到RTC模块.(在主电源VDD有效的情况下(待机),RTC还可以配置闹钟事件使STM32退出待机模式).

RTC复位过程
除了RTC_PRL、RTC_ALR、RTC_CNT和RTC_DIV寄存器外,所有的系统寄存器都由系统复位或电源复位进行异步复位。
RTC_PRL、RTC_ALR、RTC_CNT和RTC_DIV寄存器仅能通过备份域复位信号复位。

系统复位后,禁止访问后备寄存器和RCT,防止对后卫区域(BKP)的意外写操作

RTC中断
秒中断:
这里时钟自带一个秒中断,每当计数加一的时候就会触发一次秒中断,。注意,这里所说的秒中断并非一定是一秒的时间,它是由RTC时钟源和分频值决定的“秒”的时间,当然也是可以做到1秒钟中断一次。我们通过往秒中断里写更新时间的函数来达到时间同步的效果

闹钟中断:
闹钟中断就是设置一个预设定的值,计数每自加多少次触发一次闹钟中断。

二.创建CubeMX工程

配置RCC
在这里插入图片描述
配置RTC
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
使能串口
在这里插入图片描述
时钟树配置
在这里插入图片描述
设置项目
在这里插入图片描述
在这里插入图片描述

三.添加代码

在main.c文件中重写fputc函数,完成printf函数的重定向

//添加头文件#include "stdio.h"
int fputc(int ch,FILE *f){
 uint8_t temp[1]={ch};
 HAL_UART_Transmit(&huart1,temp,1,2);
 return ch;
}

在main.c中定义时间和日期的结构体用来获取时间和日期

RTC_DateTypeDef GetData;  //获取日期结构体

RTC_TimeTypeDef GetTime;   //获取时间结构体

在main函数的while循环中添加以下代码.

/* Get the RTC current Time */
	    HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
      /* Get the RTC current Date */
      HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);

      /* Display date Format : yy/mm/dd */
      printf("%02d/%02d/%02d\r\n",2000 + GetData.Year, GetData.Month, GetData.Date);
      /* Display time Format : hh:mm:ss */
      printf("%02d:%02d:%02d\r\n",GetTime.Hours, GetTime.Minutes, GetTime.Seconds);

      printf("\r\n");

      HAL_Delay(1000);

在这里插入图片描述
添加输出星期几在
/* Display date Format : yy/mm/dd */
printf("%02d/%02d/%02d\r\n",2000 + GetData.Year, GetData.Month, GetData.Date);
添加

/* Display date Format : weekday */
		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");
		}

结果:
在这里插入图片描述
参考:
https://blog.csdn.net/qq_45659777/article/details/121621521?spm=1001.2014.3001.5501

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值