STM32基于固件库学习笔记(11)RTC实时时钟

发布者:翅膀小鹰最新更新时间:2020-06-14 来源: eefocus关键字:STM32  固件库  RTC  实时时钟 手机看文章 扫描二维码
随时随地手机看文章

实时时钟(RTC)

小容量产品是指闪存存储器容量在16K至32K字节之间的STM32F101xx、STM32F102xx和STM32F103xx微控制器

中容量产品是指闪存存储器容量在64K至128K字节之间的STM32F101xx、STM32F102xx和STM32F103xx微控制器

大容量产品是指闪存存储器容量在256K至512K字节之间的STM32F101xx和STM32F103xx微控制器。

互联型产品是指STM32F105xx和STM32F107xx微控制器。


主要特性

● 可编程的预分频系数:分频系数最高为20 。

● 32位的可编程计数器,可用于较长时间段的测量。

● 2个分离的时钟:用于APB1接口的PCLK1和RTC时钟(RTC时钟的频率必须小于PCLK1时钟频率的四分之一以上)。

● 可以选择以下三种RTC的时钟源:

─ HSE时钟除以128;

─ LSE振荡器时钟;

─ LSI振荡器时钟

● 2个独立的复位类型:

─ APB1接口由系统复位;

─ RTC核心(预分频器、闹钟、计数器和分频器)只能由后备域复位。

● 3个专门的可屏蔽中断:

─ 闹钟中断,用来产生一个软件可编程的闹钟中断。

─ 秒中断,用来产生一个可编程的周期性中断信号(最长可达1秒)。

─ 溢出中断,指示内部可编程计数器溢出并回转为0的状态。


STM32 RTC 时钟简介

STM32 的实时时钟(RTC)是一个独立的定时器。STM32 的 RTC 模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。


RTC 模块和时钟配置系统(RCC_BDCR 寄存器)是在后备区域,即在系统复位或从待机模式唤醒后 RTC 的设置和时间维持不变。但是在系统复位后,会自动禁止访问后备寄存器和 RTC,以防止对后备区域(BKP)的意外写操作。所以在要设置时间之前, 先要取消备份区域(BKP)写保护。


RTC 由两个主要部分组成(参见上图 ),第一部分(APB1 接口)用来和 APB1 总线相连。此单元还包含一组 16 位寄存器,可通过 APB1 总线对其进行读写操作。APB1 接口由 APB1 总线时钟驱动,用来与 APB1 总线连接。


另一部分(RTC 核心)由一组可编程计数器组成,分成两个主要模块。第一个模块是 RTC 的预分频模块,它可编程产生 1 秒的 RTC 时间基准 TR_CLK。RTC 的预分频模块包含了一个 20位的可编程分频器(RTC 预分频器)。如果在 RTC_CR 寄存器中设置了相应的允许位,则在每个TR_CLK 周期中 RTC 产生一个中断(秒中断)。第二个模块是一个 32 位的可编程计数器,可被初始化为当前的系统时间,一个 32 位的时钟计数器,按秒钟计算,可以记录 4294967296 秒,约合 136 年左右,作为一般应用,这已经是足够了的。


复位过程

除了RTC_PRL、RTC_ALR、RTC_CNT和RTC_DIV寄存器外,所有的系统寄存器都由系统复位或电源复位进行异步复位。RTC_PRL、RTC_ALR、RTC_CNT和RTC_DIV寄存器仅能通过备份域复位信号复位。


读RTC寄存器

RTC核完全独立于RTC APB1接口。

软件通过APB1接口访问RTC的预分频值 、 计数器值和闹钟值。但是,相关的可读寄存器只在与RTC APB1时钟进行重新同步的RTC时钟的上升沿被更新。RTC标志也是如此的。


这意味着,如果APB1接口曾经被关闭,而读操作又是在刚刚重新开启APB1之后,则在第一次的内部寄存器更新之前,从APB1上读出的RTC寄存器数值可能被破坏了(通常读到0)。下述几种


情况下能够发生这种情形:

● 发生系统复位或电源复位。

● 系统刚从待机模式唤醒。

4.3 ● 系统刚从停机模式唤醒。

所有以上情况中,APB1接口被禁止时(复位、无时钟或断电)RTC核仍保持运行状态。

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


注: RTC 的 APB1 接口不受 WFI 和 WFE 等低功耗模式的影响。

配置RTC寄存器

必须设置RTC_CRL寄存器中的CNF位,使RTC进入配置模式后,才能写入RTC_PRL、RTC_CNT、RTC_ALR寄存器。

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


配置过程: 配置过程:

查询RTOFF位,直到RTOFF的值变为’1’

置CNF值为1,进入配置模式

对一个或多个RTC寄存器进行写操作

清除CNF标志位,退出配置模式

查询RTOFF,直至RTOFF位变为’1’以确认写操作已经完成。

仅当CNF标志位被清除时,写操作才能进行,这个过程至少需要3个RTCCLK周期。

RTC标志的设置

在每一个RTC核心的时钟周期中,更改RTC计数器之前设置RTC秒标志(SECF)。

在计数器到达0x0000之前的最后一个RTC时钟周期中,设置RTC溢出标志(OWF)。

在计数器的值到达闹钟寄存器的值加1(RTC_ALR+1)之前的RTC时钟周期中,设置RTC_Alarm和RTC闹钟标志(ALRF)。对RTC闹钟的写操作必须使用下述过程之一与RTC秒标志同步:

● 使用RTC闹钟中断,并在中断处理程序中修改RTC闹钟和/或RTC计数器。

● 等待RTC控制寄存器中的SECF位被设置,再更改RTC闹钟和/或RTC计数器。


RTC 正常工作的一般配置步骤

1. 使能BPK PWR时钟、中断初始化


//必须先使能电源时钟和备份区域时钟

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  //中断初始化 

  NVIC_InitTypeDef NVIC_InitStruct;

  NVIC_InitStruct.NVIC_IRQChannel =RTC_IRQn;

  NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStruct);


2. 取消备份区写保护


  PWR_BackupAccessCmd(ENABLE); //使能 RTC 和后备寄存器访问


3. 复位备份区域,开启外部低速振荡器


  BKP_DeInit();//复位备份区域

  RCC_LSEConfig(RCC_LSE_ON);//开启外部低速振荡器

  while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);//检查指定的 RCC 标志位设置与否,等待低速晶振就绪


4. 配置RCT时钟源


  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //选择 LSE 作为 RTC 时钟  

  RCC_RTCCLKCmd(ENABLE); //使能 RTC 时钟

  RTC_WaitForLastTask(); //等待最近一次对 RTC 寄存器的写操作完成

  RTC_WaitForSynchro(); //等待 RTC 寄存器同步

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

  RTC_WaitForLastTask(); //等待最近一次对 RTC 寄存器的写操作完成


5. 设置 RTC 的分频,以及配置 RTC 时钟


  RTC_EnterConfigMode();/// 允许配置

  RTC_SetPrescaler(32767);//设置 RTC 时钟分频数 晶振32.768KHz

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

  RTC_SetCounter(0);//最后在配置完成之后


6. 更新配置,设置RTC中断分组


  RTC_ExitConfigMode();//退出配置模式,更新配置 

//往备份区域写用户数据

  void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data);

//读取备份区域指定寄存器的用户数据

 BKP_ReadBackupRegister(uint16_t BKP_DR);


7. 编写中断服务函数

注:中断标志

RTC_FLAG_RTOFF RTC 操作 OFF 标志位

RTC_FLAG_RSF 寄存器已同步标志位

RTC_FLAG_OW 溢出中断标志位

RTC_FLAG_ALR 闹钟中断标志位

RTC_FLAG_SEC 秒中断标志位


void RTC_IRQHandler(void)

{

  if (RTC_GetITStatus(RTC_IT_SEC) != RESET) //秒钟中断

  {

    data++;

    printf("time:%dt",data);

  }

  RTC_ClearITPendingBit(RTC_IT_SEC); //清中断

  RTC_WaitForLastTask();

}


完整程序

#include "stm32f10x.h"  

#include "stdio.h"

int fputc(int ch, FILE *f)

{

  while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);

  USART_SendData(USART1,(uint8_t)ch);

  return ch;

}

void delay_ms(u16 time)

{    

   u16 i = 0;  

   while(time--)

   {

      i = 12000;  

      while(i--);    

   }

}

u16 data = 0;

void Usart_Init()

  GPIO_InitTypeDef GPIO_ITDef1;

  GPIO_InitTypeDef GPIO_ITDef;

  USART_InitTypeDef  USART_ITDef;

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置NVIC中断分组2:2位抢占优先级,2位响应优先级

//挂载时钟(复用PA) 串口时钟使能,GPIO 时钟使能,复用时钟使能

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);

//PA9 TXD初始化

  GPIO_ITDef.GPIO_Pin = GPIO_Pin_9;//PA9 TXD

  GPIO_ITDef.GPIO_Mode = GPIO_Mode_AF_PP;////复用推挽输出

  GPIO_ITDef.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA,&GPIO_ITDef);

//PA10 TXD初始化

  GPIO_ITDef1.GPIO_Pin = GPIO_Pin_10;//PA10 RXD

  GPIO_ITDef1.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入

  GPIO_Init(GPIOA,&GPIO_ITDef1);

  

//USART初始化

  USART_ITDef.USART_BaudRate = 115200;//波特率

  USART_ITDef.USART_WordLength = USART_WordLength_8b;//发送数据长度

  USART_ITDef.USART_StopBits = USART_StopBits_1; //一个停止位   

  USART_ITDef.USART_Parity = USART_Parity_No; //无奇偶校验位     

  USART_ITDef.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制

  USART_ITDef.USART_Mode = USART_Mode_Tx| USART_Mode_Rx ;//发送模式 

  USART_Init(USART1,&USART_ITDef);

  USART_Cmd(USART1, ENABLE);//使能串口

}

void RTC_Init(void)

{

  //1.使能BPK PWR时钟

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  

  NVIC_InitTypeDef NVIC_InitStruct;

  NVIC_InitStruct.NVIC_IRQChannel =RTC_IRQn;

  NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStruct);

  //2.取消备份区写保护

  PWR_BackupAccessCmd(ENABLE); //使能 RTC 和后备寄存器访问

  //3.复位备份区域,开启外部低速振荡器

  BKP_DeInit();//复位备份区域

  RCC_LSEConfig(RCC_LSE_ON);//开启外部低速振荡器

  while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);//检查指定的 RCC 标志位设置与否,等待低速晶振就绪

  //4.配置RCT时钟源

  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //选择 LSE 作为 RTC 时钟  

  RCC_RTCCLKCmd(ENABLE); //使能 RTC 时钟

  

  RCC_RTCCLKCmd(ENABLE); //使能 RTC 时钟

  RTC_WaitForLastTask(); //等待最近一次对 RTC 寄存器的写操作完成

  RTC_WaitForSynchro(); //等待 RTC 寄存器同步

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

  RTC_WaitForLastTask(); //等待最近一次对 RTC 寄存器的写操作完成

  

  //5.设置 RTC 的分频,以及配置 RTC 时钟

  RTC_EnterConfigMode();/// 允许配置

  RTC_SetPrescaler(32767);//设置 RTC 时钟分频数 晶振32.768KHz

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

  

  RTC_SetCounter(0);//最后在配置完成之后

  //6.更新配置,设置RTC中断分组。

  RTC_ExitConfigMode();//退出配置模式,更新配置  

}  

int main(void)

{

  Usart_Init();

  RTC_Init();

  while(1)

  {

   ;   

  }     

}

//每秒触发一次

void RTC_IRQHandler(void)

{

  if (RTC_GetITStatus(RTC_IT_SEC) != RESET) //秒钟中断

  {

    data++;//每一秒+1

    printf("time:%dt",data);//串口打印当前时间值

  }

  RTC_ClearITPendingBit(RTC_IT_SEC); //清中断

  RTC_WaitForLastTask();

}


常用资料:

  STM32F10x_StdPeriph_Lib_V3.5.0(官方固件库)

  链接:《STM32固件库使用手册的中文翻译版》    提取码:4lkx

  链接:(keil5 IAR 等常用助手)           提取码:xzgj

  链接:《STM32中文参考手册V10》         提取码:j748

关键字:STM32  固件库  RTC  实时时钟 引用地址:STM32基于固件库学习笔记(11)RTC实时时钟

上一篇:STM32F4学习笔记之GPIO(使用固件库)
下一篇:STM32基于固件库学习笔记(3)串口的收发功能+WiFi基础配置

推荐阅读最新更新时间:2024-11-02 00:55

STM32 对内部FLASH读写接口函数
简介:因为要用内部FLASH代替外部EEPROM,把参数放在STM32的0x08000000+320K处,其中20K是bootloader,300K是应用程序。 原理:先要把整页FLASH的内容搬到RAM中,然后在RAM中改动,然后擦除整页FLASH,再把改动后的内容写入原Flash页。下面程序调试通过。 /******************************************************************************* * Function Name : I2C_EE_BufferRead * Description : Reads a block of data from th
[单片机]
STM32单片机的PSAM卡驱动模块设计
引言 刷卡消费随着人们生活水平的提高已经成为常用的支付方式之一。为了保证刷卡消费的安全性,将PSAM卡内嵌于各种终端刷卡设备中。PSAM(Purchase SecureAccess Module,销售点终端安全存取模块),由IC卡发行主管部门或者应用主管机构发行,是可以用于对IC卡进行脱机消费交易认证的安全认证卡,主要应用于商用POS、网点终端、直连终端等设备上,支持多级发卡机制,适用于多应用的环境,符合识别卡、带触点的集成电路卡标准、ISO/IEC 7816—1/2/3/4以及《中国人民银行PSAM卡规范》。 1 PSAM卡简介 PSAM卡是接触式CPU卡的一种。CPU卡也称智能卡,卡内集成电路带有微处理CPU,存储单元
[单片机]
<font color='red'>STM32</font>单片机的PSAM卡驱动模块设计
STM32 系统架构及存储器映射
一、STM32系统架构 STM32系统架构如下图所示: 主系统有以下部分构成: DCode总线 该总线将M3内核的DCode总线与闪存存储器数据接口相连 ICode总线 该总线将M3内核的ICode总线与闪存存储器指令接口相连,指令取指在该总线上完成 系统总线S-bus 此总线连接Cortex™-M3内核的系统总线(外设总线)到总线矩阵,总线矩阵协调着内核和DMA间的访问。 DMA总线 DMA1和DMA2 此总线将DMA的AHB主控接口与总线矩阵相联,总线矩阵协调着CPU的DCode和DMA到SRAM、闪存和外设的访问。 总线矩阵 此总线矩阵协调内核系统总线和DMA主控总线之间的访问仲裁。此仲裁利用轮换算法。此总线矩阵
[单片机]
适用于STM32 MCU的NanoEdge人工智能软件
Cartesiam已针对STM32微控制器开发板推出优化的NanoEdge人工智能软件。 据Cartesiam称,NanoEdge AI Studio专为没有机器学习相关资源的公司而设计。 “在许多改进中,它直接通过STM32串行USB端口和Cartesiam的自动数据符合性和质量验证工具的增强版,将实时数据记录到NanoEdge AI Studio中。” ST的Nucleo-F401RE和Nucleo-L432KC开发板现已完全支持。 该软件套件可在Windows 10或Ubuntu上运行,用户能够生成并验证嵌入式系统的机器学习库。 用户可以选择上述开发板之一并下载自定义的NanoEdge AI库,可以构建可在板
[单片机]
低功耗STM32L151+RTC唤醒应用总结
该文档是本人做一个睡眠+RTC唤醒的低功耗项目总结心得,如有出入请指出。 STM32L提供5种低功耗模式:低功耗运行模式、睡眠模式、低功耗睡眠模式、停止模式、待机模式。 待机模式电流最低,但是待机模式时MCU处于不受控制的状态,所有的IO都工作在高阻抗的状态下,只有几个专用的引脚能够将mcu唤醒,而且每次唤醒相当于系统复位,RAM中的数据全部丢失,在有外部器件连接的情况下,器件引脚可能会吸收大量的电流,反而达不到低功耗要求。所以最好别用待机模式。 待机模式时MCU有一些缺点,就选择了停止模式。停止模式的功耗仅次于待机模式。在STOP模式下,PLL、HSI、HSE都被停止,RAM和寄存器的值保留。 网上有些开发经
[单片机]
读写STM32内部flash读写代码
由于老师的要求,所以写了一份读写STM32内部FLASH的代码,这样的话就可以把STM32里面没有用来保存代码段的部分用来存储数据了。 由于《stm32flash编程手册》是很久很久以前看的,现在也没心情去仔细看那份手册了。大概浏览了一下,只看到了STM32里面的flash是以16位为单位读写的。 为什么记住这个,因为之前想写一个字节老是出错,所以翻翻手册,果然看到不能写1个字节数据。而且还发现,flash写地址为奇数时也会出错。所以这份代码里面 写flash的地址只能是偶数。浏览过程中还发现,手册里面说写flash和擦除flash的时候会影响cpu的运行速度,没仔细看(真心不想看)。其他具体手册里面的资料的话没有了, 看有没有高
[单片机]
STM32 启动代码选择以及每块字节数
● 小容量产品是指闪存存储器容量在16K 至32K 字节之间的STM32F101xx、STM32F102xx和 STM32F103xx微控制器。 对应后缀ld ● 中容量产品是指闪存存储器容量在64K 至128K字节之间的STM32F101xx、STM32F102xx 和STM32F103xx微控制器。 对应后缀md ● 大容量产品是指闪存存储器容量在256K至512K字节之间的STM32F101xx和STM32F103xx 微控制器。对应后缀hd 闪存存储器容量在768K至1m字节之间的STM32F101xx和STM32F103xx 微控制器。对应后缀xl ● 互联型产品是STM32F105xx和STM32F107xx微控制器。
[单片机]
STM32的串口(UART)及串口通信原理
一、通信接口介绍 1、处理器与外部设备通信的两种方式: 并行通信 - 传输原理:数据各个位同时传输。 -优点:速度快 -缺点:占用引脚资源多 串行通信 - 传输原理:数据按位顺序传输(一位一位传输)。 -优点:占用引脚资源少 -缺点:速度相对较慢 2、串行通信三种传送方式: 单工: 数据传输只支持数据在一个方向上传输 半双工: 允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切
[单片机]
<font color='red'>STM32</font>的串口(UART)及串口通信原理
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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