STM32日历功能:读取、设置和输出

目录

  • 关于RTC
  • STM32CubeMAX界面
  • keil界面
  • 关于RTC

    1、RTC介绍
    RTC(Real Time Clock):实时时钟,是指可以像时钟一样输出实际时间的电子设备,一般会是集成电路,因此也称为时钟芯片。总之,RTC只是个能靠电池维持运行的32位定时器,并不像实时时钟芯片,读出来就是年月日。

    RTC就只一个定时器而已,掉电之后所有信息都会丢失,因此我们需要找一个地方来存储这些信息,于是就找到了备份寄存器(BKP)。因为它掉电后仍然可以通过纽扣电池供电,继续工作,所以能时刻保存这些数据。

    stm32F103使用外部晶体的32.768kHz的振荡器,产生一个1秒长的时间基准。

    RTC 模块和时钟配置系统(RCC_BDCR 寄存器)是在后备区域,即在系统复位或从待机模式唤醒后 RTC 的设置和时间维持不变。但是在系统复位后,会自动禁止访问后备寄存器和 RTC,以防止对后备区域(BKP)的意外写操作。所以在要设置时间之前, 先要取消备份区域(BKP)写保护。

    2、工作过程

    RTC只是一个时钟,但与RTC相连的有两个系统时钟:一个是APB1接口的PCLK1,另一个是RTC时钟。这样,RTC功能也就分为两个部分:第一部分,APB1接口部分,与APB1总线相连,MCU也就是通过这条总线对其进行读写操作。另一部分,RTC核心,其整个核心部分位于后备区域,所以只要有VBAT引脚供电,就能一直工作,由一系列可编程计数器组成,这部分又再细分为两个组件:20位的预分频模块与32位可编程计数器。预分频模块用来产生最长为1秒的RTC时间基准,而32位的可编程的计数器可被初始化为当前的系统时间。

    RTC_PRL:预分频装载寄存器
    RTC_DIV:预分频器余数寄存器
    RTC_CNT:计数器寄存器
    RTC_ALR:闹钟寄存器

    首先,在初始化时候,DIV和PRL都会装载同样的数。RTCCLK频率为32.768kHz,来驱动DIV工作,DIV为自减寄存器。当DIV减少到0时,会产生一个TR_CLK信号,该信号会触发三件事情:①将PRL的数重装在到DIV中;②触发CNT计数器+1;③触发SECF,进而产生秒中断。我们会设置一个合理的预分频数,使得TR_CLK触发时间刚好是1s。ALR中存储的是我们设置的闹钟秒数,当CNT和ALR中的数据相同时,就会触发闹钟中断或者闹钟唤醒。(关于CNT和ALR中存放的数据,为时间戳。)

    1s的时间如何计算?

    我们的RTC_CLK为32.768kHz,所以只要PRL中写入32767即可,即为2的15次方。
    我们只需要在PRL的低16位寄存器中写入0x7FFF即可。

    DIV寄存器存在的意义?
    从上述能知道TR_CLK输出必须为1s。那么我们想要的到0.15s,应该怎么实现呢?
    道理很简单,因为DIV是自减的,并且从32768一直减少到0,所需要的时间为1s。所以减少一个数,所用的时间为1/32768s,那么减少多少个数,就计时了0.15s呢?
    1/32768s * n = 0.15
    n = 0.15 * 32768
    又因为DIV寄存器是可读的,所以我们就能实现0.15s的计时。

    从框图中,还可以看到,只有秒中断和闹钟中断能触发中断,溢出是没有中断的。

    STM32CubeMAX界面

    读取STM32F103C8T6 内部的时钟(年月日时分秒),日历(星期x),1秒周期,通过串口输出到PC上位机

    设置RCC

    设置RTC
    设置RTC参数


    设置时钟树

    创建工程

    keil界面

    在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);
    

    编译运行结果如下:

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32日历功能:读取、设置和输出

    发表评论