一、实时时钟RTC的原理
实时时钟是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。
RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒后,RTC的设置和时间维持不变。
二、任务内容
1)读取RTC初始时间,验证是否为 1970年1月1日零分零秒;
2)将RTC时间调整为当前时间,并以 2021年x月x日x分x秒的格式从串口输出(或输出到OLED屏),每1s改变一次;
3)如果输出内容中需加入“星期x”,请修改代码。
三、创建项目
-
设置串口Usart1
-
配置RTC
-
配置时钟
-
project管理
-
Code Generator建议勾选
-
点击右上角GENERANT CODE生成工程
四、任务一
- 代码
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* 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);
}
我重写了printf
#include "stdio.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
int fputc(int ch,FILE *f){
uint8_t temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,2);
return ch;
}
注意,如果重写了printf,build前一定要勾选Use MiscroLiB
- 效果
STM32的RTC只有一个32位的计数器用来计时,没有寄存器来存年月日时分秒等。通过设置可以让这个计数器1秒加1,从0-0XFFFFFFFF大概可以计时136年。程序要设置一个时间起点表示0,一般设置起始时间为1970-01-01 0:0:0。
而我这是2000,我认为应该是用cubeMx生成的原因,默认值是这个。
五、任务二
- 在rtc.c中修改为当前时间
- 代码
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* 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);
}
- 效果
六、任务三
- 代码:
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* 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("星期%0d",GetData.WeekDay);
printf("\r\n");
HAL_Delay(1000);
}