RTC

发布时间 2023-07-04 10:20:53作者: ike_li

一、

二、

#ifndef RTC_H
#define RTC_H
/*
正点原子STM32F407最小系统板
RTC实时时钟,是一个独立的BCD定时器 /计数器。
RTC提供一个日历时钟、两个可编程闹钟中断,以及一个具有中断功能的周期
性可编程唤醒标志。RTC还包含用于管理低功耗模式的自动唤醒单元。

两个32位寄存器包含二进码十进数格式(BCD)的秒、分钟、小时(12或24小时制)、星期几、日期、月份和年份。此外,还可提供
二进制格式的亚秒值。同时系统可以自动将月份的天数补偿为28、29(闰年)、30和31天。并且还可以进行夏令时补偿。其他32位寄存
器还包含可编程的闹钟亚秒、秒、分钟、小时、星期几和日期。

还可以使用数字校准功能对晶振精度的偏差进行补偿。上电复位后,所有RTC寄存器都会受到保护,以防止可能的非正常写
访问。

无论器件是外于运行模式、低功耗模式或者复位模式,只要电源电压保持在正常工作范围,RTC就不会停上工作。

BCD:二进制的十进制码
BIN:二进制
HEX:十六进制

BCD码表示时间:
       15:39
0001 0101:0011 1001


*/
#include "stm32f4xx.h"                  // Device header
uint8_t rtc_init(void);
ErrorStatus rtc_set_time(uint8_t hour,uint8_t min,uint8_t sec,uint8_t ampm);
ErrorStatus rtc_set_date(uint8_t year,uint8_t month,uint8_t date,uint8_t week);
uint8_t bcd_to_bin(uint8_t bcd_data);
#endif

 

#include "rtc.h"

uint8_t rtc_init(void)
{

    uint16_t retry = 0X1FFF; 
    
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//使能PWR时钟
    PWR_BackupAccessCmd(ENABLE);//使能后备寄存器访问 

    //读取后备寄存器,RTC_BKP_DR0为寄存器的标志位,如果读取标志位不为我们设置的0x5051
    //0x5051是自己随便想的值,如果是第一次配置,不可能读取出来就是随便设置的值
    if( RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x5051 )    
    {
        RCC_LSEConfig(RCC_LSE_ON);//LSE 开启    
        while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)    //检查指定的RCC标志位设置与否,等待低速晶振就绪
        {
            retry++;
            //延时10ms            
            for(uint16_t i = 0;i < 10000;i++)
            {
               __NOP;
            }
        }
        if(retry == 0)return 0;        //LSE 开启失败. 

        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);    //设置RTC时钟(RTCCLK),选择LSE作为RTC时钟    
        RCC_RTCCLKCmd(ENABLE);    //使能RTC时钟 

        RTC_InitTypeDef RTC_InitStructure;
        RTC_InitStructure.RTC_AsynchPrediv = 0x7F;//RTC异步分频系数(1~0X7F)
        RTC_InitStructure.RTC_SynchPrediv  = 0xFF;//RTC同步分频系数(0~7FFF)
        RTC_InitStructure.RTC_HourFormat   = RTC_HourFormat_24;//RTC设置为,24小时格式
        RTC_Init(&RTC_InitStructure);

        rtc_set_time(15,18,06,RTC_H12_PM);    //RTC_H12_AM RTC_H12_PM 设置时间
        rtc_set_date(23,6,30,5);    //设置日期

        RTC_WriteBackupRegister(RTC_BKP_DR0,0x5051);//第一次配置完成
        //断电重启以后,不在重复执行该程序; 0x5051对应if判断中设置的状态位;
        //在这里,如果想要每次重启以后都能执行上述时间,可以通过每次都设置新的状态位值来实现
    } 

    return 1;

}

//RTC时间设置
//hour,min,sec:小时,分钟,秒钟
//ampm:@RTC_AM_PM_Definitions  :RTC_H12_AM/RTC_H12_PM
//返回值:SUCEE(1),成功
//ERROR(0),进入初始化模式失败 
ErrorStatus rtc_set_time(uint8_t hour,uint8_t min,uint8_t sec,uint8_t ampm)
{
    RTC_TimeTypeDef RTC_TimeTypeInitStructure;
    
    RTC_TimeTypeInitStructure.RTC_Hours = hour;
    RTC_TimeTypeInitStructure.RTC_Minutes = min;
    RTC_TimeTypeInitStructure.RTC_Seconds = sec;
    RTC_TimeTypeInitStructure.RTC_H12 = ampm;
    
    return RTC_SetTime(RTC_Format_BIN,&RTC_TimeTypeInitStructure);
    
}

//RTC日期设置
//year,month,date:年(0~99),月(1~12),日(0~31)
//week:星期(1~7,0,非法!)
//返回值:SUCEE(1),成功
//ERROR(0),进入初始化模式失败 
ErrorStatus rtc_set_date(uint8_t year,uint8_t month,uint8_t date,uint8_t week)
{
    
    RTC_DateTypeDef RTC_DateTypeInitStructure;
    RTC_DateTypeInitStructure.RTC_Year = year;
    RTC_DateTypeInitStructure.RTC_Month = month;
    RTC_DateTypeInitStructure.RTC_Date = date;    
    RTC_DateTypeInitStructure.RTC_WeekDay = week;
    
    return RTC_SetDate(RTC_Format_BIN,&RTC_DateTypeInitStructure);
}
/*
BCD码表示时间:
       15:39
0001 0101:0011 1001 
*/
uint8_t bcd_to_bin(uint8_t bcd_data)
{
    return (bcd_data-(bcd_data>>4)*6);
}

 

/*

STM32F407ZGT6
168MHz
Flash size 1024Kbytes
RAM size 192KB

*/
#include "main.h"
#include <string.h>

#include "delay.h"
#include "led.h"
#include "key.h"
#include "timer2.h"
#include "timer3.h"

#include "usart1.h"
#include "usart2_timer.h"
#include "usart3.h"


#include "rtc.h"

int main(void)
{

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    sys_tick_init();
    timer2_init();
    usart1_init(115200);
    led_init();
    key_init();
    delay_ms(200);

    uint8_t ret = rtc_init();
    printf("rtc_init:%d\r\n",ret);    
    while (1)
    {
    
        RTC_TimeTypeDef times_t;        
        RTC_GetTime(RTC_Format_BIN,&times_t);
        
        printf("rtc_get_time:H:%02d,M:%02d,S:%02d,H12:%02d\r\n",times_t.RTC_Hours,times_t.RTC_Minutes,times_t.RTC_Seconds,times_t.RTC_H12);

        RTC_DateTypeDef dates_t;        
        RTC_GetDate(RTC_Format_BIN,&dates_t);    
        
        
        printf("rtc_get_date:Y:%02d,M:%02d,D:%02d,WeekDay:%02d\r\n",dates_t.RTC_Year,dates_t.RTC_Month,dates_t.RTC_Date,dates_t.RTC_WeekDay);
        
        delay_ms(1000);
        
    }
  
  
}