STM32_RTC笔记

发布者:chunli最新更新时间:2017-11-26 来源: eefocus关键字:STM32  RTC笔记 手机看文章 扫描二维码
随时随地手机看文章

RTC这东西晕晕的,因为一个模块涉及到了RTC,BKP,RCC多个模块,之间的关系让人有点模糊
入门的知识请大家看手册,我来总结:
总之,RTC只是个能靠电池维持运行的32位定时器over!
所以,使用时要注意以下问题:
1. 上电后要检查备份电池有没有断过电。如何检查? 恩,RTC的示例代码中已经明示:
往备份域寄存器中写一个特殊的字符,备份域寄存器是和RTC一起在断电下能保存数据的。
上电后检查下这个特殊字符是否还存在,如果存在,ok,RTC的数据应该也没丢,不需要重新配置它
如果那个特殊字符丢了,那RTC的定时器数据一定也丢了,那我们要重新来配置RTC了
这个过程包括时钟使能、RTC时钟源切换、设置分频系数等等,这个可以参考FWLibexampleRTCCalendar的代码
在我的这个实例里,检查备份域掉电在Init.c的RTC_Conig()中,函数内若检测到BKP掉电,则会调用RTC_Configuration()

2. 因为RTC的一些设置是保存在后备域中的,so,操作RTC的设置寄存器前,要打开后备域模块中的写保护功能。
3. RTC设定值写入前后都要检查命令有没有完成,调用RTC_WaitForLastTask();

具体的RTC初始化代码如下:
////////////////////////////////////////////////////////////////////////////////
// RTC时钟初始化!
////////////////////////////////////////////////////////////////////////////////

void RTC_Configuration(void)
{
//启用PWR和BKP的时钟(from APB1)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

//后备域解锁
PWR_BackupAccessCmd(ENABLE);

//备份寄存器模块复位
BKP_DeInit();

//外部32.768K其哟偶那个
RCC_LSEConfig(RCC_LSE_ON);
//等待稳定
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);

//RTC时钟源配置成LSE(外部32.768K)
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

//RTC开启
RCC_RTCCLKCmd(ENABLE);

//开启后需要等待APB1时钟与RTC时钟同步,才能读写寄存器
RTC_WaitForSynchro();

//读写寄存器前,要确定上一个操作已经结束
RTC_WaitForLastTask();

//设置RTC分频器,使RTC时钟为1Hz
//RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1)
RTC_SetPrescaler(32767);


//等待寄存器写入完成
RTC_WaitForLastTask();

//使能秒中断
RTC_ITConfig(RTC_IT_SEC, ENABLE);

//等待写入完成
RTC_WaitForLastTask();

return;
}


void RTC_Config(void)
{
//我们在BKP的后备寄存器1中,存了一个特殊字符0xA5A5
//第一次上电或后备电源掉电后,该寄存器数据丢失,
//表明RTC数据丢失,需要重新配置
if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
{
//重新配置RTC
RTC_Configuration();
//配置完成后,向后备寄存器中写特殊字符0xA5A5
BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
}
else
{
//若后备寄存器没有掉电,则无需重新配置RTC
//这里我们可以利用RCC_GetFlagStatus()函数查看本次复位类型
if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
{
//这是上电复位
}
else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
{
//这是外部RST管脚复位
}
//清除RCC中复位标志
RCC_ClearFlag();

//虽然RTC模块不需要重新配置,且掉电后依靠后备电池依然运行
//但是每次上电后,还是要使能RTCCLK???????
//RCC_RTCCLKCmd(ENABLE);
//等待RTC时钟与APB1时钟同步
//RTC_WaitForSynchro();

//使能秒中断
RTC_ITConfig(RTC_IT_SEC, ENABLE);
//等待操作完成
RTC_WaitForLastTask();
}

#ifdef RTCClockOutput_Enable

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);


PWR_BackupAccessCmd(ENABLE);


BKP_TamperPinCmd(DISABLE);


BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);
#endif

return;
}


回复:《九九的STM32笔记》整理
基于STM32处理器
RTC只是个能靠电池维持运行的32位定时器over!
并不像实时时钟芯片,读出来就是年月日。。。
看过些网上的代码,有利用秒中断,在内存中维持一个年月日的日历。
我觉得,这种方法有很多缺点:
1.断电时没有中断可用
2.频繁进中断,消耗资源
3.时间运算复杂,代码需要自己写
4.不与国际接轨。。。。

so,还是用标准的UNIX时间戳来进行时间的操作吧!
什么是UNIX时间戳?
UNIX时间戳,是unix下的计时方式。。。很废话
具体点:他是一个32位的整形数(刚好和STM32的RTC寄存器一样大),表示从UNIX元年(格林尼治时间1970-1-1 0:0:0)开始到某时刻所经历的秒数
听起来很玄幻的,计算下: 32位的数从0-0xFFFFFFFF秒,大概到2038年unix时间戳将会溢出!这就是Y2038bug
不过,事实上的标准,我们还是照这个用吧,还有二十年呢。。。

UNIX时间戳:1229544206 <==> 现实时间:2008-12-17 20:03:26

我们要做的,就是把当前时间的UNIX时间戳放在RTC计数器中让他每秒++,over
然后,设计一套接口函数,实现UNIX时间戳与年月日的日历时间格式转换 这样就可以了

在RTC中实现这个时间算法,有如下好处:
1. 系统无需用中断和程序来维持时钟,断电后只要RTC在走即可
2. 具体的两种计时的换算、星期数计算,有ANSI-C的标准C库函数实现,具体可以看time.h
3. 时间与时间的计算,用UNIX时间戳运算,就变成了两个32bit数的加减法
4. 与国际接轨。。。


幸好是与国际接轨,我们有time.h帮忙,在MDK的ARM编辑器下有,IAR下也有
其中已经定义了两种数据类型:unix时间戳和日历型时间
time_t: UNIX时间戳(从1970-1-1起到某时间经过的秒数)
typedef unsigned int time_t;

struct tm: Calendar格式(年月日形式)

同时有相关操作函数
gmtime,localtime,ctime,mktime等等,方便的实现各种时间类型的转换和计算

于是,基于这个time.h,折腾了一天,搞出了这个STM32下的RTC_Time使用的时间库


这是我的RTC_Time.c中的说明:

本文件实现基于RTC的日期功能,提供年月日的读写。(基于ANSI-C的time.h)

作者:jjldc (九九)
QQ: 77058617

RTC中保存的时间格式,是UNIX时间戳格式的。即一个32bit的time_t变量(实为u32)

ANSI-C的标准库中,提供了两种表示时间的数据 型:
time_t: UNIX时间戳(从1970-1-1起到某时间经过的秒数)
typedef unsigned int time_t;

struct tm: Calendar格式(年月日形式)
tm结构如下:
struct tm {
int tm_sec; // 秒 seconds after the minute, 0 to 60
(0 - 60 allows for the occasional leap second)
int tm_min; // 分 minutes after the hour, 0 to 59
int tm_hour; // 时 hours since midnight, 0 to 23
int tm_mday; // 日 day of the month, 1 to 31
int tm_mon; // 月 months since January, 0 to 11
int tm_year; // 年 years since 1900
int tm_wday; // 星期 days since Sunday, 0 to 6
int tm_yday; // 从元旦起的天数 days since January 1, 0 to 365
int tm_isdst; // 夏令时??Daylight Savings Time flag
...
}
其中wday,yday可以自动产生,软件直接读取
mon的取值为0-11
***注意***:
tm_year:在time.h库中定义为1900年起的年份,即2008年应表示为2008-1900=108
这种表示方法对用户来说不是十分友好,与现实有较大差异。
所以在本文件中,屏蔽了这种差异。
即外部调用本文件的函数时,tm结构体类型的日期,tm_year即为2008
注意:若要调用系统库time.c中的函数,需要自行将tm_year-=1900

成员函数说明:
struct tm Time_ConvUnixToCalendar(time_t t);
输入一个Unix时间戳(time_t),返回Calendar格式日期
time_t Time_ConvCalendarToUnix(struct tm t);
输入一个Calendar格式日期,返回Unix时间戳(time_t)
time_t Time_GetUnixTime(void);
从RTC取当前时间的Unix时间戳值
struct tm Time_GetCalendarTime(void);
从RTC取当前时间的日历时间
void Time_SetUnixTime(time_t);
输入UNIX时间戳格式时间,设置为当前RTC时间
void Time_SetCalendarTime(struct tm t);
输入Calendar格式时间,设置为当前RTC时间

外部调用实例:
定义一个Calendar格式的日期变量:
struct tm now;
now.tm_year = 2008;
now.tm_mon = 11; //12月
now.tm_mday = 20;
now.tm_hour = 20;
now.tm_min = 12;
now.tm_sec = 30;

获取当前日期时间:
tm_now = Time_GetCalendarTime();
然后可以直接读tm_now.tm_wday获取星期数

设置时间:
Step1. tm_now.xxx = xxxxxxxxx;
Step2. Time_SetCalendarTime(tm_now);

计算两个时间的差
struct tm t1,t2;
t1_t = Time_ConvCalendarToUnix(t1);
t2_t = Time_ConvCalendarToUnix(t2);
dt = t1_t - t2_t;
dt就是两个时间差的秒数
dt_tm = mktime(dt); //注意dt的年份匹配,ansi库中函数为相对年份,注意超限
另可以参考相关资料,调用ansi-c库的格式化输出等功能,ctime,strftime等


关键字:STM32  RTC笔记 引用地址:STM32_RTC笔记

上一篇:STM32之SysTick
下一篇:STM32 温度传感器 探究

推荐阅读最新更新时间:2024-03-16 15:46

STM32——EXTI外部中断:中断方式翻转LED灯
任务目的 使用EXTI(External Interrupt)外部中断方式, 通过中断服务函数对GPIO口进行控制, 使得LED灯可以进行亮灭翻转. 原理图分析 问题分析结束之后还是先来看原理图的分析. 首先是LED灯部分: 由图中可知, 若要控制红灯(PB5), 则只需输出引脚输出为0(低电平)即可. 然后再看下按键部分: 从图中可知, 按键未按时为低电平, 按下按键时为高电平. 符合下拉输入的逻辑. EXTI外部中断 简介 外部中断指的是通过GPIO检测输入的脉冲变化,从而引起中断. 触发方式为边沿触发. 中断 笔者使用的STM32(F103VET6)单片机使用的是Cortex-M3内核,中断资源丰富. 外部中断/事件
[单片机]
<font color='red'>STM32</font>——EXTI外部中断:中断方式翻转LED灯
一文解析STM32启动流程
可执行程序 - cpu执行第一条用户代码 这个流程中着重讲述的是 HEX 文件如何被烧写到 STM32 内部的指定地址处。(烧写到 STM32 中的可执行文件不仅只有 HEX 格式,还有 axf、bin。针对不同格式的可执行文件,用不同的工具进行烧写)。 而本篇文章将要详细地描述一个流程: cpu执行第一条用户代码 - 调用 __main 函数- __rt_entry - main函数 这里需要注意一下,__main 是 c 库中的一个函数,和 main 函数是有区别的!!! 启动文件内容描述 上图中的汇编关键字最好记住,因为比较常用。 在此基础上,我们继续深入一点。 DCD指令 STM32 启动文件中使用 DCD 指令的
[单片机]
一文解析<font color='red'>STM32</font>启动流程
STM32设置为I2C从机
硬件平台:STM32F401 编辑器 : keil 5.18 操作系统:win7 一、I2C协议 在传输数据的时候,SDA线必须在时钟的高电平周期保持稳定,SDA的高或低电平状态只有在SCL 线的时钟信号是低电平时才能改变 。 起始和停止条件   SCL 线是高电平时,SDA 线从高电平向低电平切换,这个情况表示起始条件;   SCL 线是高电平时,SDA 线由低电平向高电平切换,这个情况表示停止条件。 寻址方式(7/10位地址方式)   第一个字节的头7 位组成了从机地址,最低位(LSB)是第8 位,它决定了传输的 普通的和带重复开始条件的7位地址格式方向。第一个字节的最低位是“0”,表示主机会写信息到
[单片机]
STM32基本定时器 HAL库
1.定时器分类 STM32F1系列中,除了互联型的产品,共有8个定时器,分为基本定时器、通用定时器和高级定时器。 基本定时器是一个16位只能向上计数的定时器,只能定时,没有外部IO。 通用定时器是一个16位可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,每个定时器有四个外部IO。 高级定时器是一个16位可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,还可以有三相电机互补输出信号,每个定时器有8个外部IO。 2.基本定时器功能框图 时钟源:定时器时钟TIMxCLK(内部时钟CK_INT),是经APB1预分频器后分频提供,APB1预分频系数为1,则频率不变,否则*2; 计数器时钟:定
[单片机]
<font color='red'>STM32</font>基本定时器 HAL库
STM32信息安全—加解密硬件模块
STM32的真随机数产生器 TRNG 基于物理噪声源的随机数产生器 生成32位随机数 AHB从设备,不使用时可关闭它以节省功耗 广泛运用于加解密算法和协议中:密钥的生成;“Challenge- Acknowledge”认证模式中,充当Challenges(质询);初始向量(IV);随机数 STM32的对称加解密加速器 AES 支持的算法模式有:AES – ECB、CBC、CTR;AES – GCM、CCM、GMAC;密钥长度:128位,256位可选 支持DMA加载输入和读取输出 该模块经过NIST FIPS认证 集成该对称加解密硬件加速模块的STM32系列有 STM32的对称加解密加速器 Crypto 支
[单片机]
STM32, Flash DFU芯片,内部flash,代码升级
这次要讲讲如何用USB升级单片机代码。以前曾经做过串口升级,网络升级,升级的基本原理都类似,只不过升级的工具不同罢了,串口升级当然是用串口了,网络升级用的是TCP/IP,USB升级当然用的是USB了。下面就来讲讲USB升级的实现。 修改部分部分都在USB_User组里: STM32 Internal Flash DFU芯片内部flash代码升级 - ziye334 - ziye334的博客我们一个一个文件讲过来。 首先讲讲hw_config.c,这个文件跟之前工程差不多。由于演示的需要,我们在这个文件里初始化一个按键引脚,并定义按键读取函数,该按键决定代码是否升级,如果程序一开始,该按键按下,则进入升级模式,否则跳转到升级
[单片机]
STM32 PWM输出函数
1、参考资料 《STM32F1开发指南-库函数版本》-第14章 PWM输出实验 《STM32中文参考手册V10》-第14章 通用定时器 2、STM32 PWM工作过程 ·STM32 PWM工作过程(通道1为例) CCR1:捕获比较(值)寄存器(x=1,2,3,4):设置比较值。 CCMR1: OC1M 位: 对于PWM方式下,用于设置PWM模式1【110】或者PWM模式2【111】 CCER:CC1P位:输入/捕获1输出极性。0:高电平有效,1:低电平有效。 CCER:CC1E位:输入/捕获1输出使能。0:关闭,1:打
[单片机]
<font color='red'>STM32</font> PWM输出函数
ST最新开发工具为了解基于STM32 ARM Cortex-M3 MCU开方便之门
完整的低成本的评估开发工具通过图形界面探索微控制器的性能和功能 中国,2007年11月6日 — 意法半导体(纽约证券交易所:STM)今天公布了一个价格非常低廉的微控制器开发套件STM32 PerformanceStick,这套开发工具是近日推出的基于ARM Cortex-M3内核的STM32系列微控制器的配套产品。ST设计这套紧凑的开发工具是为了便于用户了解新微控制器的功能和性能,特别值得一提的是,用户可以通过一个图形界面查看微控制器在不同条件下的性能特性。为了鼓励和帮助设计工程师修改和重新编写应用程序源代码,工具包还含有示例应用软件和一套完整的Hitex软件工具。 STM32 PerformanceStick是一套功能完整
[焦点新闻]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved