RTC -
RTC
目录
RTC
回顾
RTC
如何实现RTC制作一个时钟日历
代码编写
rtc.c完整代码
模块开发的步骤:
1、找文档
2、 在文档里面找通信方式,通信过程(协议)
3、代码>
-- 前面学的是模块的开发,串口类,IO类,ADC类设备,从这章开始,依然学习模块开发,但是方式不一样,之前代码都是自己写的,现在要学的是库开发,代码都是现成的
- 今天用库开发方式
-- 什么叫库开发,代码都是现成的
-- 那么我们还做什么呢?
- 三件事:移植,修改,使用
移植:把代码拿过来,放到工程里面
修改:修改错误或者修改一些参数配置
使用:应用
这三步都很重要
-- 在库开发阶段,可能会出现这些问题:
- 可能会出现代码看不明白,具体是代码的细节看不明白(不需要深入纠结代码)
在库开发阶段,核心就是应用
回顾
- DMA的本质是数据传输的快速通道,特点:无需CPU干预
DMA 一般不会单独出现,他一定和其他外设一块使用。
比如说:dma 去实现 printf (dma 和 usart1 TX)
RTC
-
首先查找参考手册,了解RTC

-
看核心框图

-- 单片机的时钟源有四个(外部高速(HSE),内部高速(HSI),外部低速(LSE),内部低速(LSI))
-- RTC的是时钟源有三个:外部低速(32.768khz),内部低速(40khz),外部高速(72M)/128(=562500)
如何实现RTC制作一个时钟日历
1、时钟芯片 DS1302.
2、单片机内部的 RTC
时间相关:定时器
计数器:16 位
分频系数:16 位 2^16 如果单片机的频率是72MHZ,那么经过2^16次分频后,频率为72MHZ/2^16 = 1098hz
最大的计时时间? 2^16/1098 = 59.6 S 1min
所以经过上面的计算,tim 能实现时钟日历吗? 不太行 (最大的计时时间才1min)
单片机上有一个专门用来制作时钟日历的定时器:RTC
-- RTC的特点:
- 1.计数时间长
计数器:32 位 2^32
最大的计数时间大概 136 年
分频:20 位 2^20 1hz/s
时钟源:外部低速(32.768K) 内部低速(40K) 外部高速/128(562500hz)
- 2.RTC 在单片机处于后备区域
后备区域:一般情况,单片机上电之后,禁止访问的区域,有单独供电(和单片机的供电不是同一个)
所有时钟芯片,都会存在一个问题:时间长了,就会不准。
解决问题:联网定期更新时间(获取的是世界标准时间,和北京时间有 8 个小时时差)
代码编写
-
先找到固件库

-
打开main.c文件,找到RTC的初始化函数

-
看参考手册中,找到RTC的配置过程

-
在main.c文件中找到相应的配置代码,找到配置函数,跳到相应的函数定义。


-
RTC的配置

-
选择我们用到的加到我们的工程中
if (BKP_ReadBackupRegister(BKP_DR1) != 0x1234){//1、使能访问/* Enable PWR and BKP clocks */RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//时钟/* Allow access to BKP Domain */PWR_BackupAccessCmd(ENABLE); //电源 //前两行开启访问//2、时钟源和分频/* Enable LSE */RCC_LSEConfig(RCC_LSE_ON);/* Wait till LSE is ready */while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET){}/* Select LSE as RTC Clock Source */RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);/* Enable RTC Clock */RCC_RTCCLKCmd(ENABLE);/* Wait for RTC registers synchronization */RTC_WaitForSynchro();/* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();/* Set RTC prescaler: set RTC period to 1sec */RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) *//* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();
- 设置计数初值

//3、计数初值/* Change the current time */RTC_SetCounter(1728444875);//赋一个初值,一个秒数/* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();BKP_WriteBackupRegister(BKP_DR1, 0x1234);
- 读取时间
struct tm a = {0};void get_time(void)
{uint32_t sec = RTC_GetCounter();//struct tm *p = &a;a = *(localtime((time_t*)&sec));printf("%04d/%02d/%02d %02d:%02d:%02d\r\n",a.tm_year+1900,a.tm_mon+1,a.tm_mday,a.tm_hour+8,a.tm_min,a.tm_sec);}
- 更新时间,因为该单片机没有纽扣电池,断电后数值就会丢失,重新上电后就会从初始值开始计数
//用来更新RTC时间的void updata_time(uint32_t sec)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//时钟/* Allow access to BKP Domain */PWR_BackupAccessCmd(ENABLE); //电源 /* Change the current time */RTC_SetCounter(sec);//赋一个初值,一个秒数/* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();}
- main.c
rtc_init();while(1){if(rtctime >=999){rtctime = 0;get_time();}if(keytime>=50)//50ms执行一次{keyflag = get_key();switch(keyflag){case 1:updata_time(1728455609);break;case 2: break;}}}
-- tip:
-
如果要修改时钟源

-
计数的初值是什么(是一个时间戳,我们只需要将当前时间的时间戳赋值进去即可)

rtc.c完整代码
#include "rtc.h"
#include "time.h"void rtc_init(void)
{if (BKP_ReadBackupRegister(BKP_DR1) != 0x1234){//1、使能访问/* Enable PWR and BKP clocks */RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//时钟/* Allow access to BKP Domain */PWR_BackupAccessCmd(ENABLE); //电源 //前两行开启访问//2、时钟源和分频/* Enable LSE */RCC_LSEConfig(RCC_LSE_ON);/* Wait till LSE is ready */while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET){}/* Select LSE as RTC Clock Source */RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);/* Enable RTC Clock */RCC_RTCCLKCmd(ENABLE);/* Wait for RTC registers synchronization */RTC_WaitForSynchro();/* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();/* Set RTC prescaler: set RTC period to 1sec */RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) *//* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();//3、计数初值/* Change the current time */RTC_SetCounter(1728444875);//赋一个初值,一个秒数/* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();BKP_WriteBackupRegister(BKP_DR1, 0x1234);
}// //4、中断或者闹钟(需要就写,不需要就不写)
//
// //中断----------------------------------------------
//
// RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断// /* Wait until last write operation on RTC registers has finished */
// RTC_WaitForLastTask();
//
// NVIC_InitTypeDef NVIC_InitStructure;// /* Configure one bit for preemption priority */
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);// /* Enable the RTC Interrupt */
// NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
//
// //---------------------------------------------------}//中断服务函数//void RTC_IRQHandler(void)
//{
// if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
// {
// /* Clear the RTC Second interrupt */
// RTC_ClearITPendingBit(RTC_IT_SEC);// /* Wait until last write operation on RTC registers has finished */
// RTC_WaitForLastTask();
//
// }
//}struct tm a = {0};void get_time(void)
{uint32_t sec = RTC_GetCounter();//struct tm *p = &a;a = *(localtime((time_t*)&sec));printf("%04d/%02d/%02d %02d:%02d:%02d\r\n",a.tm_year+1900,a.tm_mon+1,a.tm_mday,a.tm_hour+8,a.tm_min,a.tm_sec);}//因为该单片机没有纽扣电池,断电后数值就会丢失,重新上电后就会从初始值开始计数
//用来更新RTC时间的void updata_time(uint32_t sec)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//时钟/* Allow access to BKP Domain */PWR_BackupAccessCmd(ENABLE); //电源 /* Change the current time */RTC_SetCounter(sec);//赋一个初值,一个秒数/* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();}
用RTC实现闹钟功能
- 这里要使用闹钟中断
-- 1、在初始化函数中加入中断和闹钟的初始化

-- 2、写中断服务函数,这里用RTC的中断服务函数即可,不用专门用闹钟的中断服务函数

-- 3、在主函数中只要将初始化函数写入main函数中,就可以达到闹钟的效果
-- 主要代码
#include "rtc.h"
#include "relay.h"
#include "delay.h"uint16_t naozhong = 0;void rtc_init(void)
{//if (BKP_ReadBackupRegister(BKP_DR1) != 0x1233){//1、使能访问/* Enable PWR and BKP clocks */RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//时钟/* Allow access to BKP Domain */PWR_BackupAccessCmd(ENABLE); //电源 //前两行开启访问//2、时钟源和分频/* Enable LSE */RCC_LSEConfig(RCC_LSE_ON);/* Wait till LSE is ready */while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET){}/* Select LSE as RTC Clock Source */RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);/* Enable RTC Clock */RCC_RTCCLKCmd(ENABLE);/* Wait for RTC registers synchronization */RTC_WaitForSynchro();/* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();/* Set RTC prescaler: set RTC period to 1sec */RTC_SetPrescaler(32768); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) *//* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();//3、计数初值/* Change the current time */RTC_SetCounter(1728444875);//赋一个初值,一个秒数/* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();BKP_WriteBackupRegister(BKP_DR1, 0x1233);
}//4、中断或者闹钟(需要就写,不需要就不写)//中断----------------------------------------------RTC_ITConfig(RTC_IT_ALR | RTC_IT_SEC, ENABLE); //使能RTC秒中断/* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();RTC_SetAlarm(1728444875+10);RTC_WaitForLastTask();NVIC_InitTypeDef NVIC_InitStructure={0};/* Configure one bit for preemption priority */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* Enable the RTC Interrupt */NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);//---------------------------------------------------}//中断服务函数void RTC_IRQHandler(void)
{if (RTC_GetITStatus(RTC_IT_SEC) != RESET){/* Clear the RTC Second interrupt */RTC_ClearITPendingBit(RTC_IT_SEC);//秒中断/* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();}if (RTC_GetITStatus(RTC_IT_ALR) != RESET)//闹钟中断{uint32_t aa = RTC_GetCounter();RTC_SetAlarm(aa+10);RTC_WaitForLastTask();relay_init();relay_on();Delay_nms(100);relay_off();RTC_WaitForLastTask();/* Clear the RTC Second interrupt */RTC_ClearITPendingBit(RTC_IT_ALR);/* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();}
}
相关文章:
RTC -
RTC 目录 RTC 回顾 RTC 如何实现RTC制作一个时钟日历 代码编写 rtc.c完整代码 模块开发的步骤: 1、找文档 2、 在文档里面找通信方式,通信过程(协议) 3、代码> -- 前面学的是模块的开发,串口类,I…...
图像处理中常用的统计矩
目录 原点矩中心矩常用的统计矩偏度(Skewness)定义解释 峰度(Kurtosis)定义解释 统计矩的应用MATLAB相关函数 原点矩(Moment about the Origin)和中心矩(Central Moment)是概率论和数…...
Ubuntu 详解| Ubuntu ssh| Ubuntu apt命令大全| Ubuntu性能优化| Ubuntu换镜像源
Ubuntu 是Debian开源linux系统体系下的子分支之一 Debian-ubuntu 和它一样的还有 kali(一款渗透测试软件) Debian-kali 小白参考 :Centos 7.9 安装 图解版 小白必看 最新_centos7.9-CSDN博客文章浏览阅读2.5k次,点赞…...
Linux安全命令(Linux Security Commands)
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…...
2024最新版安装教程!Python安装+PyCharm安装使用教程!!(非常简单)
Python下载安装 一、进入Python官网首页,下载最新版的Python 官方网址:Download Python | Python.org 鼠标悬浮在Downloads,选择最新版本 注意:由于Python官网服务器设立在国外,所以下载速度非常慢,我这…...
C++:STL:vector类常用函数介绍(附加部分重要函数模拟实现)
cplusplus.com/reference/vector/vector/https://cplusplus.com/reference/vector/vector/ vector在实际中非常的重要,在实际中我们熟悉常见的接口就可以,有了string的基础,vector其实大体使用方法上二者是类似的: 这里我们先给…...
[工程构建] 使用 pkg-config 的 cmake 模板
可执行文件 # 1) cmake basic cmake_minimum_required(VERSION 3.12) #cmake version check set(CXX_STANDARD 17) #c standard version)# 2) project info #auto generated variables as below: #PROJECT_NAME: "hello" #hello_BINARY_DIR: build root dir #hello_…...
MATLAB 注释快捷键
matlab 前言单行注释多行注释 快捷键使用菜单 前言 单行注释 % 这是一个单行注释 x 10; % 这是另一个单行注释多行注释 %{ 这是一个多行注释 它可以包含多行文本 x 10; % 这行代码也会被注释掉 %}快捷键 在 MATLAB 编辑器中,可以使用快捷键来快速注释和取消注…...
8.优化存储过程的性能(8/10)
优化存储过程的性能 1.引言 存储过程是数据库系统中预先编写好的SQL语句集合,它们被保存在数据库服务器上,可以在需要时被调用执行。存储过程的使用可以提高数据库操作的效率,减少网络通信,并且可以封装复杂的逻辑,使…...
Django发送邮件代理服务器配置
根路由下配置 MAIL_BACKEND django.core.mail.backends.smtp.EmailBackend EMAIL_HOST smtp.qq.com EMAIL_HOST_USER 66897079qq.com EMAIL_HOST_PASSWORD aavlzhzvqorbcahcEMAIL_PORT 465 EMAIL_USE_SSL True发送邮件 message "<p>尊敬的用户您好ÿ…...
uniapp__微信小程序使用秋云ucharts折线图双轴
1、子组件 <template><view class"charts-box"><qiun-data-charts type"line":opts"computedOpts":chartData"chartData"/></view> </template><script> export default {props: {chartData: {t…...
云原生运维 - 旅程(简约版)
1. 入门阶段 理论学习: 了解云计算和容器技术的基本概念。学习Docker基础知识,包括容器创建、镜像管理等。阅读Kubernetes官方文档的入门部分,了解Kubernetes的核心概念。 实操练习: 安装Docker环境。运行你的第一个Docker容器…...
2014年国赛高教杯数学建模B题创意平板折叠桌解题全过程文档及程序
2014年国赛高教杯数学建模 B题 创意平板折叠桌 某公司生产一种可折叠的桌子,桌面呈圆形,桌腿随着铰链的活动可以平摊成一张平板(如图1-2所示)。桌腿由若干根木条组成,分成两组,每组各用一根钢筋将木条连接…...
PyCharm打开及配置现有工程(详细图解)
本文详细介绍了如何利用Pycharm打开一个现有的工程,其中包括编译器的配置。 PyCharm打开及配置现有工程 1、打开工程2、配置编译器 1、打开工程 双击PyCharm软件,点击左上角 文件 >> 打开(O)… 选中想要打开的项目之后点击“确定” 2、配置编译器…...
CSP-J
CSP那些事儿 OI赛制是啥OI赛制下的CCF-CSPCSP简介CSP-J考试(仅山东)考试时间考试地点考试结构 写在最后有趣的代码: OI赛制是啥 OI赛制,不详细说了,就是一股脑做好几个题,一起提交的比赛(通俗易…...
Linux系统:Linux中ln命令用法
ln命令功能 将一个文件或目录在同一个文件系统或者另一个不同的文件系统的某个位置建立一个链接,类似windows系统中的超链接,这样当我们在链接处访问被链接的目录或文件时就可以通过此链接来访问,不必要再进入要访问的文件系统中。 建立链接…...
在SpringBoot+VUE中 实现登录-RSA的加密解密
步骤-先理清楚在动手 前端首先调用后端的公钥接口,在前端加密密码传输至后端登录接口后端用私钥解密码拿着用户名去数据库查询出来的盐值加密的 密码1用私钥解密密码登录密码加盐值得到 密码2比较密码1与密码2,相同则登录成功,跳转首页|其他页面 前端实…...
基于Android11简单分析audio_policy_configuration.xml
开篇先贴上一个高通的例子,后续基于此文件做具体分析。 1 <?xml version"1.0" encoding"UTF-8" standalone"yes"?> 2 <!-- Copyright (c) 2016-2019, The Linux Foundation. All rights reserved 3 Not a Contribut…...
kafka-manager修改zookeeper端口号后启动仍然连接2181端口
问题描述: zookeeper默认端口号修改为了2182,kafka-manager的配置文件application.conf中也已经修改了zkhosts为新的端口号,然而启动kafka-manger时报错连接连接超时,发现连接的还是2181端口,很奇怪?&…...
RabbitMQ 入门(三)SpringAMQP
一、Spring AMQP 简介 SpringAMQP是基于RabbitMQ封装的一套模板,并且还利用SpringBoot对其实现了自动装配,使用起来非常方便。 SpringAmqp的官方地址:https://spring.io/projects/spring-amqp SpringAMQP提供了三个功能: - 自动…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
