STM32F1-RTC and BKP实验平台;正点原子精英板,部分内容来自原子哥的书STM32 的实时时钟(RTC)是一个独立的定时器。 STM32 的 RTC 模块拥有一组连续计数的计数器,最大计数为4294967296 ,如果把计数器设置为秒计数,那么最大可以计时136年左右。这个计数器只是单纯的计数功能,如果要转化为年月日的话还是得手动转化,转换过程中还要考虑闰年问题等。
RTC 模块和时钟配置系统(RCC_BDCR 寄存器)是在后备区域,即在系统复位或从待机模式唤醒后 RTC 的设置和计数值(也就是当前时间)维持不变。但是在系统复位后,会自动禁止访问后备寄存器和 RTC,以防止对后备区域(BKP)的意外写操作。所以在要设置时间之前, 先要取消备份区域(BKP)写保护。
RTC由两部分组成,第一部分(APB1 接口)用来和 APB1 总线相连。此单元还包含一组 16 位寄存器,可通过 APB1 总线对其进行读写操作。 APB1 接口由 APB1 总线时钟驱动,用来与 APB1 总线连接,所以设置RTC的时候要打开APB1时钟。另一部分(RTC 核心)由一组可编程计数器组成,分成两个主要模块。第一个模块是 RTC 的预分频模块,它可编程产生 1 秒的 RTC 时间基准 TR_CLK。 RTC 的预分频模块包含了一个 20位的可编程分频器(RTC 预分频器)。如果在 RTC_CR 寄存器中设置了相应的允许位,则在每个
TR_CLK 周期中 RTC 产生一个中断(秒中断)。第二个模块是一个 32 位的可编程计数器,就是上面所说的计数器。
RTC 还有一个闹钟寄存器 RTC_ALR,用于产生闹钟。系统时间按 TR_CLK 周期累加并与存储在 RTC_ALR 寄存器中的可编程时间相比较,如果 RTC_CR 控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。
STM32F1的备份寄存器可以保存数据,这个数据掉电后是会丢失的,不能代替EEPROM。但是这个数据是用后备电源维持的,在主电源切断后还是不会丢失的。
RTC操作步骤;
1,打开APB1和PWR时钟
2,后备区域开锁
3,选择RTC时钟源,如果使用外部晶振的话还要打开使能等待相应的晶振起振
4,使能RTC配置允许
5,等待操作上一步完成
6,设置预分频
7,等待上一个操作完成
8,设置计数初值
9,等待上一个操作完成
10,关闭RTC配置允许
11,打开RTC中断(如果使能了中断的话)
12,配置完成,剩下的就是写中断函数了
13,中断函数;确认相应的中断,清除中断标志位。编写自己的中断处理函数RTC配置举例;RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1Periph_PWR,ENABLE);//要操作后备区域就得打开APB1和PWR时钟PWR_BackupAccessCmd(ENABLE);//操作后备区域是要开锁的BKP_DeInit();//配置前最好先复位下这里使用的是外部的低速晶振,所以需要开启并等待晶振起振RCC_LSEConfig(RCC_LSE_ON);    //外部低速晶振是需要手动开启的while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==1); //等待晶振起振选择RTC时钟源,这里选择外部晶振RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);         RCC_RTCCLKCmd(ENABLE);  在进行下一个操作前要等待上一个操作完成RTC_WaitForLastTask();RTC_WaitForSynchro();   进入RTC设置模式,这个和下面的关闭RTC设置模式是一对的,有开就有关RTC_EnterConfigMode();    因为RTC使用的外部晶振是32.768k的,要产生1s的RTC时钟需要32768分频RTC_SetPrescaler(32767); 老规矩,等待操作完成 RTC_WaitForLastTask();  设置RTC计数器的值,这里只是单纯的计时,并没有转换为日历,所以这个值随便设,但是为了能计时更长的时间还是设置为0吧RTC_SetCounter(0);        如果需要用RTC中断的话需要中断使能      RTC_ITConfig(RTC_IT_SEC, ENABLE);       等待操作完成,RTC_WaitForLastTask();        RTC_ExitConfigMode();   配置完成后就是中断函数了,void RTC_IRQHandler(){if(RTC_GetFlagStatus(RTC_FLAG_SEC)==1){RTC_ClearITPendingBit(RTC_FLAG_SEC);//中断处理函数,该干嘛的就干嘛去}}       至此,RTC时钟初始化已经配置完毕了,下面是BKP的配置步骤
1,打开APB1和PWR时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1Periph_PWR,ENABLE);2,后备区域开锁,好像这个锁不关也无所谓,反正复位后会自动上锁的
PWR_BackupAccessCmd(ENABLE);3,往相应的备份寄存器写数据就好了,入口第一个参数是选择寄存器,第二个参数是数据
BKP_WriteBackupRegister(BKP_DR1,6666);如果要读取备份寄存器的数据也很简单,入口就是选择读取哪个寄存器
BKP_ReadBackupRegister(BKP_DR1)4,ok本实验功能;设置RTC为秒计时并产生秒中断,在秒中断中通过串口向电脑发送从STM32F1上电开始到此刻的总秒数
代码如下;
#include "sys.h"
#include "delay.h"
#include "stdio.h"
/************************************************************
功能;RTC时钟产生秒中断,在中断中输出从上电开始到此刻的秒数这里只是测试RTC秒中断功能,至于怎么把秒计时转化为年月日的话,这里就不演示了串口接在PA9,PA10****************************************************************/
void init__uart1();void init_RTC()
{NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel=RTC_IRQn;//中断通道设置为RTCNVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//子优先级NVIC_Init(&NVIC_InitStruct);//这个函数在misc.c文件里RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1Periph_PWR,ENABLE);//要操作后备区域就得打开APB1和PWR时钟PWR_BackupAccessCmd(ENABLE);//操作后备区域是要开锁的if(BKP_ReadBackupRegister(BKP_DR1)!=6666)//这个是为了避免非断电复位后重新配置RTC,但是在断电重启后还是会重新配置RTC的{BKP_DeInit();//配置前最好先复位下RCC_LSEConfig(RCC_LSE_ON);  //外部低速晶振是需要手动开启的while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==1); //等待晶振起振RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);             //把外部晶振时钟作为RTC时钟RCC_RTCCLKCmd(ENABLE);  //使能RTC时钟RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成RTC_WaitForSynchro();      //等待RTC寄存器同步  RTC_EnterConfigMode();        /// 允许配置    RTC_SetPrescaler(32767);    //设置RTC预分频的值,目前外部低速晶振就是32.768k的,所以32767分频后就是1sRTC_WaitForLastTask();      //等待最近一次对RTC寄存器的写操作完成RTC_SetCounter(0);             //这个值是年月日转换后的秒数,,,这里不使用年月日所以随便设置都无所谓,但是不能太大?RTC_ITConfig(RTC_IT_SEC, ENABLE);       //使能RTC秒中断RTC_WaitForLastTask();        //等待最近一次对RTC寄存器的写操作完成?RTC_ExitConfigMode();         //关闭允许配置BKP_WriteBackupRegister(BKP_DR1,6666);//备份寄存器的RTC配置标志位}else//如果RTC已经配置过了{RTC_WaitForSynchro();  //等待最近一次对RTC寄存器的写操作完成RTC_ITConfig(RTC_IT_SEC, ENABLE);  //使能RTC秒中断RTC_WaitForLastTask();    //等待最近一次对RTC寄存器的写操作完成}
}int main(void){         delay_init();  //延时函数初始化NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级init__uart1();//串口1初始化init_RTC();while(1){}//等待中断}void RTC_IRQHandler(){static uint32_t sec_count=0;if(RTC_GetFlagStatus(RTC_FLAG_SEC)==1){RTC_ClearITPendingBit(RTC_FLAG_SEC);printf("sec_count=%d\r\n",sec_count++);//串口输出从上电开始到目前所经过的秒数}}//*****************从这里分开,下面的部分是配置串口的//串口中断处理函数void USART1_IRQHandler(void) {char re_data=0;//为了接收字符,还是定义为字符类型吧if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==1)//确认下是不是串口1接收中断{re_data=USART_ReceiveData(USART1);   //接收数据USART_SendData(USART1,re_data);           //发送接收到的数据while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET); //等待数据发送完 成}   //这个中断是不需要手动清除标志位的,因为读取数据后接收标志位会自动清零}void init__uart1()
{GPIO_InitTypeDef GPIO_InitStruct;USART_InitTypeDef USART_InitStruct;NVIC_InitTypeDef NVIC_InitStruct;//    串口IO配置,PA9,PA10RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//IO时钟打开GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//IO方式具体看《中文手册》8.1.11章节GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//IO方式具体看《中文手册》8.1.11章节GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);//配置串口1RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//打开串口时钟USART_InitStruct.USART_BaudRate=115200;    //波特率115200USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  //无硬件流USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; //接收和发送都使能USART_InitStruct.USART_Parity=USART_Parity_No;                       //无奇偶校验USART_InitStruct.USART_StopBits=USART_StopBits_1;                   //停止位1位USART_InitStruct.USART_WordLength=USART_WordLength_8b;      //数据长度8位USART_Init(USART1,&USART_InitStruct);NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;//虽然知道这个参数的意思,但是还真不知道这个参数放在哪里NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;//使能通道中断NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;//子优先级NVIC_Init(&NVIC_InitStruct);//这个函数在misc.c文件里USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//打开串口中断,第二个参数是选择中断类型,这里打开的是接收中断USART_Cmd(USART1,ENABLE);    //配置完成后一定要记得使能串口
}//重定义fputc函数 ,想要使用printf函数得添加这个函数
int fputc(int ch, FILE *f)
{      while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   USART1->DR = (u8) ch;      return ch;
}

10-STM32F1-RTC and BKP相关推荐

  1. 寒假学习之stm32( 12)----RTC与BKP

    RTC与BKP 犹记得当初学习51单片机的时候遇到的DS1302计时模块,当初第一次接触那样复杂的寄存器,也是十分困难的,现在的stm32内置了RTC模块,我们也可以认为RTC是内置的类似的DS130 ...

  2. STM32F1后备寄存器(BKP)和实时时钟(RTC)

    今天在看正点原子RTC实验的时候有个地方一直有点疑惑,他说系统主电源断电但有BAT供电时备份寄存器的内容不会丢失. 然后RTC的框图如下: 可以看到有一个"后备区域",里面有PRL ...

  3. [stm32 HAL库] RTC和BKP驱动

    CubeMX 配置 打开外部时钟 激活时钟和日历 更改RCC时钟为外部低速时钟 以上在CubeMX中的配置就已经完成,点击生成代码即可. 4.这里我需要使用串口进行调试,因此打开了串口一 工程修改 以 ...

  4. STM32学习心得二十一:实时时钟RTC和备份寄存器BKP特征、原理及相关实验代码解读

    记录一下,方便以后翻阅~ 主要内容 1) RTC特征与原理: 2) BKP备份寄存器特征与原理: 3) RTC常用寄存器+库函数介绍: 4) 相关实验代码解读. 实验内容: 因为没有买LCD屏,所以计 ...

  5. STM32——RTC实时时钟原理+BKP寄存器原理

    一.RTC实时时钟特征与原理 1.RTC(Real Time Clock):实时时钟 2.RTC是个独立的BCD定时器/计数器.RTC提供一个日历时钟,两个可编程闹钟中断,以及一个具有中断功能的周期性 ...

  6. linux下测试RTC驱动相关的命令date和hwclock常见用法简介

    之前对Linux下面时间相关的内容,一无所知,第一次见到hwclock,不知为何物,也没找到解释清楚的帖子.故此整理一下,简单介绍Linux下验证rtc驱动是否工作正常,相关的的命令:date和hwc ...

  7. 全志 添加外挂RTC Hym8563

    add 添加外挂RTC hym8563diff --git a/lichee/linux-3.10/arch/arm/configs/sun8iw11p1smp_androidm_defconfig ...

  8. 应用程序 /dev/rtc 编程 获取时间 2011-12-13 01:01:06【转】

    本文转载自:http://blog.chinaunix.net/uid-16785183-id-3040310.html 分类: 原文地址:应用程序 /dev/rtc 编程 获取时间 作者:yuwei ...

  9. NXP S32K RTC模块手册中文

    RTC不能使用唤醒pin,因此相关寄存器位不适用(如RTC_CR[WPS].RTC_CR[WPE].RTC_IER [WPON]). 此外,该装置没有集成电容,因此无法通过软件配置可调谐电容器(包括在 ...

  10. Linux应用开发【第十章】RTC应用开发

    文章目录 10 RTC应用开发 10.1 RTC的作用及时间表示 10.2 RTC的操作命令 10.2.1 系统时间和硬件时间 10.2.2 系统时间操作命令 10.2.3 硬件时间操作命令 10.3 ...

最新文章

  1. Java学习总结:38(正则表达式)
  2. GetAsyncKeyState
  3. mysql中有主键和外键吗_谈谈mysql的主键和外键
  4. 深度强化学习探索算法最新综述,近200篇文献揭示挑战和未来方向
  5. pmp每日三题(2022年3月14日)
  6. 外部中断---STM32F1
  7. Java, C#, Swift语法对比速查表
  8. speech production model
  9. c函数sscanf的高级技巧
  10. Linux系统下init进程的前世今生
  11. 浅谈对于业务中台的理解
  12. [转载] 深入理解log机制
  13. SqlServer数据库(可疑)解决办法4种
  14. esxi 虚拟机的控制台上键盘无法输入
  15. 利用计算机教室教师培训记录表,新学期教师计算机培训方案
  16. 收藏了800道Java后端经典面试题,共享给大家
  17. 温度传感器的工作原理简介
  18. python excelwriter保存路径_Python自动化处理Excel报表,我的工作更轻松了!
  19. JMeter安装配置及使用说明【最全面】
  20. rm rf 后的文件如何恢复

热门文章

  1. 艾司博讯:拼多多主图轮播视频怎么搞
  2. ping 命令的实现
  3. php html注释多行,css多行注释怎么写
  4. 2013年第四届java A组蓝桥杯省赛真题
  5. python头像变二维码_学了Python之后,美化二维码如此简单
  6. 如何在Eclipse上创建新项目
  7. 何恺明的ResNet论文,被引量刚刚突破10万大关
  8. 前端知识之angular组件库之NG-ZORRO-ANTD结构窥探(一)components
  9. 2022-2028全球与中国呼吸系统疾病治疗市场现状及未来发展趋势
  10. 学习安装unik环境——过程一