(stm32f103学习总结)—RTC独立定时器—实时时钟实验
一、STM32F1 RTC介绍
1.1 RTC简介
STM32 的实时时钟( RTC)是一个独立的定时器。 STM32 的 RTC 模 块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的 功能。修改计数器的值可以重新设置系统当前的时间和日期。 RTC模块和时钟配置是在后备区域,无论器件状态如何(运行模式、 低功耗模式或处于复位状态),只要保证后备区域供电正常,RTC便不会 停止工作,所以通常会在后备区域供电端加一个纽扣电池,即使主电源 停止供电,后备电源也会启动供电,从而保证RTC时钟不停的运行,只有 当主电源和后备纽扣电池都没有电的时,RTC才停止工作。 从 RTC 的定时器特性来说,它是一个 32 位的计数器,只能向上计 数。它的时钟来源有三种,分别为高速外部时钟的 128 分频( HSE/128 )、 低速内部时钟 LSI 以及低速外部时钟 LSE。
1.2电源

1.3备份寄存器(BKP)简介
1.4实时时钟(RTC)
二、功能描述
1、概述
2、复位过程
3、读RTC寄存器
4、写RTC寄存器
必须设置RTC_CRL寄存器中的CNF位,使RTC进入配置模式后,才能写入RTC_PRL、RTC_CNT、RTC_ALR寄存器。
另外,对RTC任何寄存器的写操作,都必须在前一次写操作结束后进行。可以通过查询RTC_CR寄存器中的RTOFF状态位,判断RTC寄存器是否处于更新中。仅当RTOFF状态位是1时,才可以写入RTC寄存器。
三、STM32F1 RTC配置步骤
- 使能PWR和BKP时钟。调用函数:RCC_APB1PeriphClockCmd();
- 使能后备寄存器访问。调用函数:PWR_BackupAccessCmd();
- 配置RTC时钟源,使能RTC时钟。调用函数:RCC_RTCCLKConfig();RCC_RTCCLKCmd();
- 如果使用LSE,要打开LSE:RCC_LSEConfig(RCC_LSE_ON);
- 设置RTC预分频系数。调用函数:RTC_SetPrescaler();
- 设置时间。调用函数:RTC_SetCounter();
- 开启相关中断(如果需要)。调用函数:RTC_ITConfig();
- 编写中断服务函数。调用函数:RTC_IRQHandler();
- 部分操作要等待写操作完成和同步。调用函数:RTC_WaitForLastTask();RTC_WaitForSynchro();
四、程序举例
编写RTC控制程序 本章所要实现的功能是:设置RTC时间日期初值,在RTC秒中断内使用 串口打印出RTC日期和时间,D1指示灯闪烁提示系统运行。
程序框架如下 :
(1)初始化RTC,设置RTC时间日期初值 (2)开启RTC的秒中断,编写RTC中断函数, (3)在RTC中断内更新时间并打印输出 (4)编写主函数
1 #ifndef _rtc_H
2 #define _rtc_H
3
4 #include "system.h"
5
6
7 u8 RTCx_Init(void);
8 void RTC_GET(void);
9
10 typedef struct
11 {
12 u8 hour;
13 u8 min;
14 u8 sec;
15 }_calender;
16
17 extern _calender calender;
18
19
20
21 #endif
分析RTC_Init()函数:RTC初始化函数。
初始化时按照之前的RTC一般步骤进行配置,这里需要注意的是,为了区分是否是第一次执行RTC_Init()函数,必须判断后配寄存器中是否写如果某个值(向BKP_DR1寄存器写入0xA0A0,写入其他的数字也可以)如果写入不用再初始化。
为什么要区分是否执行过RTC_Init?
如果由于 断电/ 复位/唤醒等待 等因素,程序中断但RTC时钟以及后备寄存器区域还在执行;等恢复供电重新启动程序时,这不能再对RTC时钟进行初始化,否则一直初始化,那么RTC作为时钟就没什么实际作用。
1 if (BKP_ReadBackupRegister(BKP_DR1) != 0xA0A0//(从指定的后备寄存器中读出数据)判断是否初始化过
2 {
3 //第一次进行初始化(RTC_Init)
4 BKP_WriteBackupRegister(BKP_DR1, 0XA0A0); //向指定的后备寄存器中写入用户程序数据
5 }
6 else//(已经初始化过)系统继续计时
7 {
8 //不是第一次进行初始化(RTC_Init)
9 }
代码44:使用外部低速晶振(LSE)时需要检查指定的RCC相应的标志位是否设置,等待低速晶振就绪。
1 #include "rtc.h"
2 #include "systick.h"
3 #include "ustrt.h"
4
5
6 _calender calender;
7
8
9 void RTC_NVIC_Config() //设置RTC中断优先级
10 {
11 NVIC_InitTypeDef NVIC_InitStruct;
12
13 NVIC_InitStruct.NVIC_IRQChannel=RTC_IRQn;
14 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;
15 NVIC_InitStruct.NVIC_IRQChannelSubPriority=3;
16 NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE ;
17 NVIC_Init(&NVIC_InitStruct);
18
19 }
20
21 void RTC_GET() //获取 RTC 计数器的值并进行处理
22 {
23 u32 timedata;
24 timedata=RTC_GetCounter();
25 calender.hour=timedata/3600;
26 calender.min=timedata%3600/60;
27 calender.sec=timedata%3600%60;
28 }
29
30 //返回0:初始化失败
31 //返回1:初始化成功
32 u8 RTCx_Init()
33 {
34 u8 time;
35 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
36 RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);
37 PWR_BackupAccessCmd(ENABLE);
38
39
40 if(BKP_ReadBackupRegister(BKP_DR1)!=0xA0a0) //从指定的后备寄存器读数据)检查是不是第一次配置时钟
41 {
42 BKP_DeInit(); //将后备寄存器初始化
43 RCC_LSEConfig(RCC_LSE_ON); //将RCC_LSE时钟开启
44 while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET && time<250) //检测LSE时钟是否开启
45 {
46 time++;
47 delay_ms(10);
48 }
49 if(time>=250)
50 {
51 return 1;
52 }
53 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //配置RTC的时钟为LSE
54 RCC_RTCCLKCmd(ENABLE); //RTC时钟输入开启
55 RTC_WaitForLastTask(); //等待直到RTC寄存器上的上一次写操作完成。
56 RTC_WaitForSynchro(); //等待,直到RTC寄存器(RTC_CNT、RTC_ALR和RTC_PRL)与RTC APB时钟同步。
57 RTC_ITConfig(RTC_IT_SEC, ENABLE);
58 RTC_WaitForLastTask(); //等待直到RTC寄存器上的上一次写操作完成。
59 RTC_EnterConfigMode(); // 允许配置
60 RTC_SetPrescaler(32767); //设置 RTC 预分频的值
61 RTC_WaitForLastTask(); //等待直到RTC寄存器上的上一次写操作完成。
62 RTC_SetCounter(0x1111); //设置 RTC 计数器的值 初始化时间17:34:55
63 RTC_ExitConfigMode(); //退出 RTC 配置模式
64 BKP_WriteBackupRegister(BKP_DR1,0xA0a0); //向指定的后备寄存器中写入用户程序数据
65
66 }
67 else //(系统之前已经进行过相应初始化)系统继续计时
68 {
69 RTC_WaitForLastTask(); //等待直到RTC寄存器上的上一次写操作完成。
70 RTC_WaitForSynchro(); //等待,直到RTC寄存器(RTC_CNT、RTC_ALR和RTC_PRL)与RTC APB时钟同步。
71 RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能或者失能指定的 RTC 中断
72 }
73
74 RTC_NVIC_Config(); //RCT中断优先级别设置
75 RTC_GET(); //获取 RTC 计数器的值
76 return 0;
77 }
78
79 void RTC_IRQHandler(void) //RTC中断函数
80 {
81 if(RTC_GetITStatus(RTC_IT_SEC)!=0) //检查指定的 RTC 中断发生与否(秒中断)
82 {
83 RTC_GET();
84 printf("RTC_Time:%d:%d:%d\r\n",calender.hour,calender.min,calender.sec);
85 }
86 RTC_ClearITPendingBit(RTC_IT_SEC); //清除 RTC 的中断待处理位
87 }
1 #include "system.h"
2 #include "led.h"
3 #include "systick.h"
4 #include "ustrt.h"
5 #include "rtc.h"
6
7 int main()
8 {
9 u8 i=0;
10
11
12 SysTick_Init(72);
13 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
14 LED_Init();
15 ustrt_Init(9600);
16 RTCx_Init();
17
18 while(1)
19 {
20
21 i++;
22 if(i%20==0)
23 {
24 led1=!led1;
25 }
26 delay_ms(10);
27 }
28 }
(stm32f103学习总结)—RTC独立定时器—实时时钟实验的更多相关文章
- (stm32f103学习总结)—stm32定时器中断
一.定时器介绍 STM32F1的定时器非常多,由2个基本定时器(TIM6.TIM7).4个通 用定时器(TIM2-TIM5)和2个高级定时器(TIM1.TIM8)组成.基本定 时器的功能最为简单,类似 ...
- 8086实时时钟实验(一)——《x86汇编语言:从实模式到保护模式》05
1.代码清单 ;代码清单9-1 ;文件名:c09_1.asm ;文件说明:用户程序 ;创建日期:2011-4-16 22:03 ;=================================== ...
- (stm32f103学习总结)—独立看门狗(IWDG)
一.IWDG介绍 1.1 IWDG简介 STM32F1芯片内部含有两个看门狗外设,一个是独立看门狗IWDG,另 一个是窗口看门狗WWDG.两个看门狗外设(独立和窗口)均可用于检测 并解决由软件错误导致 ...
- 【iCore3 双核心板】例程十:RTC实时时钟实验——显示日期和时间
实验指导书及代码包下载: http://pan.baidu.com/s/1jHuZcnc iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...
- 【iCore4 双核心板_ARM】例程十:RTC实时时钟实验——显示时间和日期
实验现象: 核心代码: int main(void) { /* USER CODE BEGIN 1 */ RTC_TimeTypeDef sTime; RTC_DateTypeDef sDate; ; ...
- 【iCore1S 双核心板_ARM】例程十一:RTC实时时钟实验——显示时间和日期
实验现象: 核心代码: int main(void) { /* USER CODE BEGIN 1 */ RTC_DateTypeDef sDate; RTC_TimeTypeDef sTime; u ...
- 8086实时时钟实验(二)——《x86汇编语言:从实模式到保护模式》读书笔记06
上次我们说了代码,这次我们说说怎样看到实验结果. 首先编译源文件(我的源文件就在当前路径下,a盘和c盘在上一级目录下): nasm -f bin c08_mbr.asm -o c08_mbr.bin ...
- stm32——RTC实时时钟
stm32——RTC实时时钟 一.关于时间 2038年问题 在计算机应用上,2038年问题可能会导致某些软件在2038年无法正常工作.所有使用UNIX时间表示时间的程序都将将受其影响,因为它们以自19 ...
- stm32 rtc 实时时钟
STM32的实时时钟是一个独立的定时器 通常会在后备区域供电端加一个纽扣电池,当主电源没有电的时,RTC不会停止工作 若VDD电源有效,RTC可以触发秒中断.溢出中断和闹钟中断 备份寄存器BKP 备份 ...
随机推荐
- linux下确认裸盘是否使用-渐入佳境
--作者:飞翔的小胖猪 --创建时间:2021年3月9日 6.1 概述 在私有云和虚拟化环境中业务方经常会根据自己的业务情况申请磁盘用作数据存储用.如果申请了磁盘但没有使用的情况,将极大的造成资源的浪 ...
- Leaflet:Marker、Popup类
Marker.Popup.Tooltip类都是继承自Layer类:Event与Layer Marker 1.用例 L.marker([41,123]).addTo(map); 2.实例化 L.mark ...
- JZ-024-二叉树中和为某一值的路径
二叉树中和为某一值的路径 题目描述 输入一颗二叉树的根节点和一个整数,按字典序打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. 题目链 ...
- 基于NET 6.0 封装的 Fast.Framework
Fast Framework 项目地址 https://gitee.com/China-Mr-zhong/Fast.Framework Author Mr-zhong Wechat 850856667 ...
- linux echo用法和实例
echo命令用于在shell中打印shell变量的值,或者直接输出指定的字符串.linux的echo命令,在shell编程中极为常用, 在终端下打印变量value的时候也是常常用到的,因此有必要了解下 ...
- Control Flow in Tensorflow TF中的控制流解析
写在前面 本文翻译自Tensorflow团队的文章Tensorflow Control Flow Implementation,部分内容加入了笔者自己的理解,如有不妥之处还望各位指教. 目录 概览 控 ...
- spring源码干货分享-对象创建详细解析(set注入和初始化)
记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新.欢迎大家指正! 环境: spring5.X + idea 建议:学习过程中要开着源码一步一步过 Spring根据BeanDe ...
- LGP3726题解
确实牛逼......这个转化我反正肯定想不到... 考虑 \(a=b\) 的情况.发现出了平局之外都是一半赢一半输.可以得到此时的答案为: \[\frac{2^{a+b}-\sum_{i=0}^{a} ...
- LGP5653口胡
操作好像比较神秘. 发现 \(k\) 很小,考虑和 \(k\) 有关的 DP,考虑不出来. 费用提前计算,对 \(w_i\) 做后缀和,那么序列的权值就是 \(\sum_{i=1}^nyw_i\). ...
- 实践2:github管理代码仓库,包含用webpack打包项目
此篇介绍用github仓库管理代码,github是大型的项目代码管理,存储平台:简单说帮助一个团队共享,修改同一个项目,配合着gitHub Desktop非常方便: 可以做到多人删除.修改.增加同一项 ...