STM32入门笔记14_RTC实时时钟

BKP和RTC实时时钟

BKP

BKP简介

  • BKP(Backup Registers) 备份寄存器
  • BKP可用于存储用户应用程序数据。当VDD(2.0-3.6V) 电源被切断时,仍然由VBAT(1.8-3.6V) 维持供电。当系统在待机模式下被唤醒,或系统复位或电源复位时,也不会被复位
  • TAMPER引脚产生的侵入事件将所有备份寄存器内容清除(可做防拆卸设计)
  • RTC引脚输出RTC校准时钟、RTC闹钟脉冲或者秒脉冲
  • 存储RTC时钟校准寄存器
  • 用户数据存储容量:20字节(中容量和小容量)/ 84字节(大容量和互联型)

BKP基本结构

在这里插入图片描述

  • 每个数据寄存器存2个字节数据,中容量和小容量共十个DR,大容量和互联型共42个DR

RTC

RTC简介

  • RTC(real time clock) 实时时钟
  • RTC是一个独立的定时器,可为系统提供时钟和日历的功能
  • RTC和时钟配置系统处于后备区域,系统复位时数据不清零,VDD(2.0-3.6V)断电后可借助VBAT(1.8-3.6V)供电继续走时
  • 32位的可编程计数器,可对应Unix时间戳的秒计数器
  • 20位的可编程预分频器,可适配不同频率的输入时钟
  • 可选择三种RTC时钟源:( 通常使用LSE)
    • HSE时钟除以128(通常为8MHz/128)
    • LSE振荡器时钟(通常为32.768KHz)
    • LSI振荡器时钟(40KHz)

在这里插入图片描述

  • RTCCLK 一般信号频率一般为32.768kHz

  • RTC预分频器通过计数实现对输入信号的分频,RTC_DIV实际是一个计数器,RTC_PRL用于设置预分频值( 分频倍数 = RTC_PRL+1 )

    • 为得到每秒的计时(RTC_PRL一般为32767)
  • RTC_CNT中存放的是UNIX时间戳的秒数

  • RTC_ALR是RTC的闹钟功能,当RTC_CNT=RTC_ALR时,触发RTC_Alarm中断。若配置了RTC_Alarm中断服务,可在中断服务函数中执行需要的操作

  • RTC_Overflow但RCT_CNT溢出时会触发该中断,一般不会触发

  • RTC_Second, 每秒中断(具体时间由输入信号频率与预分频系数配置决定)

RTC框图

在这里插入图片描述

  • 一般情况信号源为LSE,且外部一般接32.768khz的石英晶振 (制作工艺和使用方便)

硬件电路

在这里插入图片描述

  • C1和C2的参数教程是参考手册,但若有硬件设计需求,建议参考所选用晶振的负载电容大小

在这里插入图片描述

在这里插入图片描述

  • 值得注意的是: 晶振本身就有百万分之几十的误差(ppm), 因此电容相差不太的情况, 所造成的误差可能也就几百万分之一

  • 电容对频率的影响: 电容越大频率越低,反之越高

  • 这里是一个UP对晶振电容大小和频率的测试视频 【晶振的负载电容到底怎么选择?】

RTC操作注意事项

  • 执行以下操作将使能对BKP和RTC的访问:

    • 设置RCC_APB1ENR的PWREN和BKPEN,使能PWR和BKP时钟

    • 设置PWR_CR的DBP,使能对BKP和RTC的访问

  • 若在读取RTC寄存器时,RTC的APB1接口曾经处于禁止状态,则软件首先必须等待RTC_CRL寄存器中的RSF位(寄存器同步标志)被硬件置1 (等待同步)

  • 必须设置RTC_CRL寄存器中的CNF位,使RTC进入配置模式后,才能写入RTC_PRL、RTC_CNT、RTC_ALR寄存器 (进入配置模式, 无需软件操作 )

  • 对RTC任何寄存器的写操作,都必须在前一次写操作结束后进行。可以通过查询RTC_CR寄存器中的RTOFF状态位,判断RTC寄存器是否处于更新中。仅当RTOFF状态位是1时,才可以写入RTC寄存器 (等待写入)

程序设计

读写BKP

在这里插入图片描述

#include "stm32f10x.h" 
#include "delay.h"
#include "OLED.h"int main(void)
{OLED_Init();// RCCRCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);  // 使能BKPRCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);  // 使能PWRPWR_BackupAccessCmd(ENABLE);   // 配置DBPBKP_WriteBackupRegister(BKP_DR1, 0x01);  // 写入数据 中容量 DR1-DR10 第二次注释该行OLED_ShowHexNum(1, 1, BKP_ReadBackupRegister(BKP_DR1), 4);   // 读BKP DR寄存器// 在提供备用电源的情况下,断电和复位不会情况BKP里的数据while(1){}
}
  • PWR_BackupAccessCmd(ENABLE) 实际配置了CR寄存器的DBP位
/*** @brief  Enables or disables access to the RTC and backup registers.* @param  NewState: new state of the access to the RTC and backup registers.*   This parameter can be: ENABLE or DISABLE.* @retval None*/
void PWR_BackupAccessCmd(FunctionalState NewState)
{/* Check the parameters */assert_param(IS_FUNCTIONAL_STATE(NewState));*(__IO uint32_t *) CR_DBP_BB = (uint32_t)NewState;
}

读写RTC

在这里插入图片描述

MyRTC.c

#include "stm32f10x.h"
#include <time.h>
uint16_t MyRTC_Time[] = {2023, 9, 18, 20, 40, 58};/**
* @brief 设置时间
*/
void MyRTC_SetTime(void)
{time_t time_cnt;struct tm time_date;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_min = MyRTC_Time[4];  // 分time_date.tm_sec = MyRTC_Time[5];   // 秒time_cnt = mktime(&time_date) - 8 * 60 * 60;  // 转换为时间戳 减去东八偏移RTC_SetCounter(time_cnt);  // 将数据写入RTC的CNTRTC_WaitForLastTask();  // 等待写入完成}/**
* @brief 读取时间
*/
void MyRTC_ReadTime(void)
{time_t time_cnt;struct tm time_date;time_cnt = RTC_GetCounter() + 8 * 60 * 60;  // 加上东八区偏移time_date = *localtime(&time_cnt);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_min ;  // 分MyRTC_Time[5] = time_date.tm_sec ;   // 秒}/**
* @brief 初始化RTC
*/
void MyRTC_Init(void)
{// RCCRCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);PWR_BackupAccessCmd(ENABLE);  // 设置CR寄存器的DBP位if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) // 避免时间重复写入{RCC_LSEConfig(RCC_LSE_ON);  // 开启LSE时钟 外接32.768khz晶振 LSE默认不上电while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);  // 等待LSE起振RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // 设置RTC时钟源为LSERCC_RTCCLKCmd(ENABLE);  // 使能时钟RTC_WaitForSynchro();  // 等待同步RTC_WaitForLastTask(); // 等待写入完成 RTC_SetPrescaler(37628-1);  // 设置分频系数RTC_WaitForLastTask();MyRTC_SetTime();  // 设置时间 BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);}else{RTC_WaitForSynchro();  // 等待同步RTC_WaitForLastTask(); // 等待写入完成 }
}

MyRTC.h

#ifndef __MYRTC_H
#define __MYRTC_Hextern uint16_t MyRTC_Time[];void MyRTC_Init(void);
void MyRTC_SetTime(void);
void MyRTC_ReadTime(void);
void MyRTC_Init(void);#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyRTC.h"int main(void)
{OLED_Init();MyRTC_Init();OLED_ShowString(1, 1, "Date:XXXX-XX-XX");OLED_ShowString(2, 1, "Time:XX:XX:XX");OLED_ShowString(3, 1, "CNT :");OLED_ShowString(4, 1, "DIV :");while (1){MyRTC_ReadTime();OLED_ShowNum(1, 6, MyRTC_Time[0], 4);OLED_ShowNum(1, 11, MyRTC_Time[1], 2);OLED_ShowNum(1, 14, MyRTC_Time[2], 2);OLED_ShowNum(2, 6, MyRTC_Time[3], 2);OLED_ShowNum(2, 9, MyRTC_Time[4], 2);OLED_ShowNum(2, 12, MyRTC_Time[5], 2);OLED_ShowNum(3, 6, RTC_GetCounter(), 10);OLED_ShowNum(4, 6, RTC_GetDivider(), 10);  // 余数寄存器}
}

资料

【晶振的负载电容到底怎么选择?】

【STM32入门教程-2023持续更新中】

STM32F10xxx参考手册(中文).pdf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/132927.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利达卓越:关注环保事业,持续赋能科技

随着全球环境问题的日益突出,绿色金融作为一种新兴的金融模式逐渐受到各国的重视。绿色金融是指在金融活动中,通过资金、信贷和风险管理等手段,支持环境友好和可持续发展的项目和产业。绿色金融的出现是为了应对气候变化、资源短缺、污染问题等现实挑战,促进经济的绿色转型和可…

自定义无边框窗口

效果&#xff1a; 可拖动拉伸 ui&#xff1a;设计如下 样式表&#xff1a;在ui CustomDialog 里设置的 #widget_title{background: #E6F1EB;border-top-left-radius: 20px;border-top-right-radius: 20px;}#widget_client{background-color: rgb(255, 255, 255);border-bottom…

房产中介租房小程序系统开发搭建

随着移动互联网的发展&#xff0c;租房小程序已经成为许多房产中介公司转型线上的重要工具。通过租房小程序&#xff0c;房产中介公司可以方便地展示房源信息、吸引租户、达成交易。那么&#xff0c;如何通过乔拓云网开发租房小程序呢&#xff1f;下面是详细的开发指南。 1.进入…

Linux Centos7 下使用yum安装的nginx平滑升级

1. 查看当前nginx版本 1nginx -v2. 查看centos版本 1cat /etc/redhat-release3. 创建一个新的文件nginx.repo&#xff0c;其中第三行的7是因为我的centos版本是7点多的&#xff0c;你看自己是多少就改多少 1vim /etc/yum.repos.d/nginx.repo23[nginx]4namenginx repo 5baseu…

区块链游戏的开发流程

链游&#xff08;Blockchain Games&#xff09;的开发流程与传统游戏开发有许多相似之处&#xff0c;但它涉及到区块链技术的集成和智能合约的开发。以下是链游的一般开发流程&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&…

STM32--WDG看门狗

文章目录 WDG简介IWDGIWDG的超时计算WWDGWWDG超时和窗口值设定独立看门狗工程WWDG工程 WDG简介 WDG看门狗&#xff08;Watchdog Timer&#xff09;是一种常见的硬件设备&#xff0c;在STM32F10系列中&#xff0c;有两种看门狗&#xff0c;分别是独立看门狗和窗口看门狗&#x…

Jetson Orin NX 开发指南(8): Mavros 的安装与配置

一、前言 由于 Jetson 系列开发板常作为自主无人机的机载电脑&#xff0c;而无人机硬件平台如 PX4 和 ArduPilot 等通过 MAVLink 进行发布无人机状态和位姿等信息&#xff0c;要实现机载电脑与 MAVLink 的通信&#xff0c;必须借助 Mavros 功能包&#xff0c;因此&#xff0c;…

uniapp EventChannel 页面跳转参数事件传递navigateBack,navigateTo 成功后通知事件区别

问题&#xff1a;navigateBack&#xff08;&#xff09;emit事件在onload()监听不到 从A页面跳转到B页面&#xff0c;在B点击产生数据后&#xff0c;跳转回到A&#xff0c;并告诉A点击的数据是什么&#xff0c;使用&#xff1a; navigateBack&#xff08;&#xff09;。 &…

Vue3 + Nodejs 实战 ,文件上传项目--实现图片上传

目录 技术栈 1. 项目搭建前期工作(不算太详细) 前端 后端 2.配置基本的路由和静态页面 3.完成图片上传的页面&#xff08;imageUp&#xff09; 静态页面搭建 上传图片的接口 js逻辑 4.编写上传图片的接口 5.测试效果 结语 博客主页&#xff1a;専心_前端,javascript,mys…

UTF-8的编码与解码

文章目录 一、什么是unicode二、什么是编码三、.unicode和utf-8编码是什么关系四、示例五、编码规则是什么 一、什么是unicode UNICDOE是一个字符集&#xff0c;它定义了世界上所有字符的唯一编号&#xff0c;每一个字符编号称为码点 详细参考- https://www.cnblogs.com/Illid…

【【萌新的SOC学习之GPIO之MIO控制LED实验程序设计】】

萌新的SOC学习之GPIO之MIO控制LED实验程序设计 如何设置完GPIO并且传递数据 我们先了解GPIO引脚的配置 每一个GPIO引脚都可以设置成输入输出 &#xff0c;只有GPIO8 7 只能作为输出 我们现在做一个例子 GPIO 的bank我们知道有4个 bank0 1 2 3 DIRM_0 就是第一个bank 需要写入…

如何压缩视频?视频压缩变小方法汇总

视频是我们日常生活中不可或缺的一部分&#xff0c;但视频文件往往会占用大量存储空间&#xff0c;这在传输和分享过程中可能成为一个瓶颈。 为了解决这一问题&#xff0c;我们可以通过压缩的方式减小视频大小&#xff0c;视频压缩是指在保证视频质量的前提下&#xff0c;通过…