CNTCNT

#include "stm32f10x.h"
#include <time.h>

uint16_t MyRTC_Time[] = {2023,1,1,23,59,55};//2023超过了uint8_t数据的范围 所以定义成16位

//将数组的时间刷新到RTC外设里 调用读取函数 将RTC外设的时间刷新到这个数组里
//值得注意的是:如果是个位数 前面不要补0 因为在C语言中以0开头的是8进制 虽然8进制的1和10进制的1一样
//但是如果写09的时候会报错,因为在八进制中数字9是无效的 所以在十进制的前边不可以随意补0

void MyRTC_Init(void)
{
    //1.开启PWR和BKP的时钟 使能BKP和RTC的访问
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
    
    PWR_BackupAccessCmd(ENABLE);
    
    if(BKP_ReadBackupRegister(BKP_DR1) != 0xa5a5)//第一次上电时 或者系统完全断电之后 BKP_DR1默认是0
    {    //if成立执行初始化 初始化之后置BKP标志位为a5a5 下次读到这个数据说明备用电池没断电
        
        
        //2.开启LSE时钟 并等待LSE时钟启动完成
        //共3个参数 LSE_OFF表示LSE振荡器关闭 LSE_ON表示打开
        //LSE_Bypass 表示时钟旁路 意思是不接晶振 直接从OSC32_IN这个引脚输入一个指定频率的信号当做时钟源
        RCC_LSEConfig(RCC_LSE_ON);
        //RCC_LSICmd(ENABLE);//启动LSI
        //等待LSE启动完成
        while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);
        //while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);//等待LSI
        
        
        //选择RTCCLK时钟源
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
        //RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);//时钟修改为LSI
        //使能时钟
        RCC_RTCCLKCmd(ENABLE);
        
        //等待同步    函数内部自带while等待 调用即可实现等待效果
        RTC_WaitForSynchro();
        //等待上一次写入操作完成
        RTC_WaitForLastTask();
        
        //要将LSE的32.768KHz频率分频为1分频,其中 减1 是因为计数值包含0
        RTC_SetPrescaler(32768 - 1);//自带进入和退出配置模式的代码
        //RTC_SetPrescaler(40000 - 1);//LSI时钟源40KHz
        RTC_WaitForLastTask();
        
        //给一个32位的秒计数器
        RTC_SetCounter(1672588795);
        RTC_WaitForLastTask();
    
        BKP_WriteBackupRegister(BKP_DR1,0xa5a5);
    }
    else//如果已经初始化过了 则无需初始化 但是最好执行等待的函数防止意外
    {
        RTC_WaitForSynchro();
        RTC_WaitForLastTask();
    }
    

    
}

void MyRTC_SetTime(void)
{
    time_t time_cnt;
    struct tm time_date;
    
    //1.把数组指定的时间填充到struct tm结构体里
    time_date.tm_year = MyRTC_Time[0] - 1900;
    time_date.tm_mon  = MyRTC_Time[1] -1;
    time_date.tm_mday = MyRTC_Time[2];
    time_date.tm_hour = MyRTC_Time[3];
    time_date.tm_sec  = MyRTC_Time[4];
    time_date.tm_min  = MyRTC_Time[5];
    //2.使用mktime函数得到秒数
    time_cnt = mktime(&time_date);
    //3.将秒数写入到RTC的CNT中
    RTC_SetCounter(time_cnt);
    RTC_WaitForLastTask();
}

void MyRTC_ReadTime(void)
{
    time_t time_cnt;
    struct tm time_date;
    
    //1.RTC_GetCounter读取CNT秒数
    time_cnt = RTC_GetCounter();
    //2.使用localtime函数得到日期时间
    time_date = *localtime(&time_cnt);    //返回值是struct tm* 所以需要先取内容
    //3.将time_date的日期时间转移到数组里 操作和上边相反即可
    MyRTC_Time[0] = time_date.tm_year + 1900;
    MyRTC_Time[1] = time_date.tm_mon  + 1;
    MyRTC_Time[2] = time_date.tm_mday;
    MyRTC_Time[3] = time_date.tm_hour;
    MyRTC_Time[4] = time_date.tm_sec ;
    MyRTC_Time[5] = time_date.tm_min ;
}

//配置LSE外部低速时钟
void RCC_LSEConfig(uint8_t RCC_LSE);
//配置LSI内部低速时钟
void RCC_LSICmd(FunctionalState NewState);
//RTCCLK配置 用于选择RTCCLK的时钟源 
void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);
//启动RTCCLK 在调用上边的选择时钟函数之后 需要调用Cmd进行使能
void RCC_RTCCLKCmd(FunctionalState NewState);


//获取标志位    调用启动时钟的函数之后需要等待标志位置1 时钟才算启动完成工作稳定
FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG);

//配置中断输出
void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState);
//进入配置模式  CNF位置1后才能写入寄存器
void RTC_EnterConfigMode(void);
//退出配置模式
void RTC_ExitConfigMode(void);
//获取CNT计数器的值    可读取时钟
uint32_t  RTC_GetCounter(void);
//写入CNT计数器的值 可设置时间
void RTC_SetCounter(uint32_t CounterValue);
//写入预分频器  会写入预分频器的PRL重装寄存器中 用于配置预分频器的分频系数
void RTC_SetPrescaler(uint32_t PrescalerValue);
//写入闹钟值    配置闹钟
void RTC_SetAlarm(uint32_t AlarmValue);
//读取预分频器中的DIV余数寄存器 是一个自减计数器 为了得到更细致的时间 
uint32_t  RTC_GetDivider(void);
//等待同步    等待RSF置1
void RTC_WaitForLastTask(void);

//下边四个均为与标志位相关的函数
void RTC_WaitForSynchro(void);
FlagStatus RTC_GetFlagStatus(uint16_t RTC_FLAG);
void RTC_ClearFlag(uint16_t RTC_FLAG);
ITStatus RTC_GetITStatus(uint16_t RTC_IT);
void RTC_ClearITPendingBit(uint16_t RTC_IT);

相关推荐

  1. CNTCNT

    2024-05-01 09:18:01       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-01 09:18:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-01 09:18:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-01 09:18:01       82 阅读
  4. Python语言-面向对象

    2024-05-01 09:18:01       91 阅读

热门阅读

  1. 修改conda源和虚拟环境路径

    2024-05-01 09:18:01       30 阅读
  2. CAPM模型步骤

    2024-05-01 09:18:01       32 阅读
  3. K8s: Kubernetes扩展之自定义资源

    2024-05-01 09:18:01       30 阅读
  4. python烟花代码

    2024-05-01 09:18:01       27 阅读
  5. Matlab : unique函数的用法

    2024-05-01 09:18:01       34 阅读
  6. selenium截屏代码

    2024-05-01 09:18:01       31 阅读
  7. selenium-webdriver 设置宽高 node

    2024-05-01 09:18:01       30 阅读
  8. selenium 4.20.0 访问外网问题

    2024-05-01 09:18:01       29 阅读
  9. Golang 设计模式(创建型)

    2024-05-01 09:18:01       26 阅读
  10. 如何使用dlib库进行人脸检测

    2024-05-01 09:18:01       29 阅读
  11. P1025 [NOIP2001 提高组] 数的划分

    2024-05-01 09:18:01       35 阅读