datasheet

简单初始化STM32的RTC

2016-10-04来源: eefocus关键字:初始化  STM32  RTC
RTC嘛 就跟DS1302 差不多吧...当然了可分频又有32位的计数器...报警、秒、溢出中断.....等等。RTC在APB1总线上....

 

要使用 RTC,一般来说也顺带地使用上后备寄存器—这是因为RTC 是一个简单的秒中断
定时器,年月日时分秒的信息必须要找个地方能掉电保存才有意义.STM32 的备份寄存器(BKP)是42个16位的寄存器,可用来存储84个字节的用户应用程序数据。他们处在备份域里,当VDD电源被切断,他们仍然由VBAT维持供电。当系统在待机模式下被唤醒,或系统复位或电源复位时,他们也不会被复位。 此外,BKP控制寄存器用来管理侵入检测和RTC校准功能。 复位后,对备份寄存器和RTC的访问被禁止,并且备份域被保护以防止可能存在的意外的写操作它是用后备电池供电的,只要配置好后,即使系统关电,32768 的
晶振和后备寄存器的数据也会得以维持.而且RTC的计数器是会继续秒递增的.那么要配
置RTC,就必须开放以下东西:
#include "stm32f10x_bkp.h" 这个是后备寄存器
#include "stm32f10x_pwr.h" 电源管理
#include "stm32f10x_rtc.h" RTC库

 简单初始化STM32的RTC - java - stm32学习日志

开始吧.....先是中断

void NVIC_Configuration(void)
{
 NVIC_InitTypeDef NVIC_InitStructure;
 
 /* Configure one bit for preemption priority */
 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
 
 /*RTC*/
 NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; //RTC全局中断
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 NVIC_Init(&NVIC_InitStructure);
}

然后设置 RTC

#include "STM32Lib\\stm32f10x.h"
#include "hal.h"


static u8 RTC_Blank=0;
/***********************************
**函数名:RTC_Configuration
**功能:RTC设置
**注意事项:要根据是否是第一次设置,才进入下面的RTC设定
判断是否第一次设置,只需要判断RTC后备寄存器1的值是否为事先写入的0XA5A5,如果不是,则
RTC是第一次上电,需要初始化RTC,并把实际时间转化为RTC计数值,这里没有设置实际时间,只是简单地初始化了RTC
************************************/
void RTC_Configuration(void)
{

/*PWR时钟(电源控制)与BKP时钟(RTC后备寄存器)使能*/
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

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

/*从指定的后备寄存器(BKP_DR1)中读出数据*/
 if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
 {
  /* 将外设BKP的全部寄存器重设为缺省值 */
  BKP_DeInit(); 
  
  /* 启用 LSE(外部低速晶振)*/
  RCC_LSEConfig(RCC_LSE_ON); 
  /*等待外部晶振震荡 需要等待比较长的时间*/
  while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);

  /*使用外部晶振32.768K作为RTC时钟*/
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);  
  //允许RTC
  RCC_RTCCLKCmd(ENABLE);
  //等待RTC寄存器同步 原因下文说明
  RTC_WaitForSynchro();
  //等待最近一次对RTC寄存器的写操作完成
  RTC_WaitForLastTask();

  //允许RTC的秒中断(还有闹钟中断和溢出中断可设置)
  RTC_ITConfig(RTC_IT_SEC, ENABLE);
  //又是等待上一次对RTC寄存器的写操作完成
  RTC_WaitForLastTask();
  //32768晶振预分频值是32767,不过一般来说晶振都不那么准
  RTC_SetPrescaler(32776);  //如果需要校准晶振,可修改此分频值
  RTC_WaitForLastTask();

  //写入RTC后备寄存器1 0xa5a5
  BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);  
  RTC_Blank=1; /*这个标志代表RTC是没有预设的(或者说是没有上纽扣电池) 用串口呀啥的输出来。*/

 }
 //如果RTC已经设置
   else
 {
  //等待RTC与APB同步
   RTC_WaitForSynchro();
   RTC_WaitForLastTask();
 
    //使能秒中断 
    RTC_ITConfig(RTC_IT_SEC, ENABLE);  //这句可以放到前面吗?
    RTC_WaitForLastTask(); //又等....
   }
 
 //清除标志
 RCC_ClearFlag(); 
}

 

为啥要不停的等呢??

RTC核完全独立于RTC APB1接口。 软件通过APB1接口访问RTC的预分频值、计数器值和闹钟值。但是,相关的可读寄存器只在与RTC APB1时钟进行重新同步的RTC时钟的上升沿被更新。RTC标志也是如此的。 这意味着,如果APB1接口曾经被关闭,而读操作又是在刚刚重新开启APB1之后,则在第一次的内部寄存器更新之前,从APB1上读出的RTC寄存器数值可能被破坏了(通常读到0)。

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

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

 

/*******************************************************************************
* Function Name  : RTC_IRQHandler    RTC中断
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
extern volatile bool Sec; //1S标志
void RTC_IRQHandler(void)
{
 if(RTC_GetITStatus(RTC_IT_SEC) != RESET) //RTC发生了秒中断(也有可能是溢出或者闹钟中断)

/*RTC_IT_OW溢出中断/RTC_IT_ALR闹钟中断/RTC_IT_SEC秒中断*/
 {
  RTC_ClearITPendingBit(RTC_IT_SEC);
  Sec=TRUE;
  
  //以免RTC计数溢出,这里限制了RTC计数值的大小.0x0001517f实际就是一天的秒数
     if(RTC_GetCounter() >= 0x0001517f) 
     {
       RTC_SetCounter(0x0);

       RTC_WaitForLastTask();
     }
 }
}

 

#include "STM32Lib\\stm32f10x.h"
#include "hal.h"

volatile bool Sec=FALSE;

int main(void)
{
 ChipHalInit();   //片内硬件初始化
 ChipOutHalInit();  //片外硬件初始化
 
 TestRtc();    //测试RTC
 for(;;)
 {
  if(Sec==TRUE)
  {
   Sec=FALSE;
   GPIOA->ODR^=GPIO_Pin_8; //闪灯
  }
 }
}

 

最简单 最基层的CRT写好了..........其实还有好多很酷的功能 比如是否掉电重启 是否是SeSET 复位 等 应该在CRT前 都检测好........

关键字:初始化  STM32  RTC

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/article_2016100430021.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32 FSMC LCD 液晶的驱动—ILI9320
下一篇:STM32--SYSTICK超简易定时器

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

stm32中ADC初始化程序

输入引脚 ->ADC_IN10 */                       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚GPIO_Init(GPIOC, &GPIO_InitStructure); /* ADC初始化*/ //CR1寄存器设置tmpreg1 = ADC1->CR1;tmpreg1 &
发表于 2019-04-12

STM32应用简章之GPIO初始化

//初始化IO模式:上拉/下拉输入。调用函数: void KEY_Init(void) //IO初始化{      GPIO_InitTypeDef GPIO_InitStructure;      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);//使能PORTA,PORTE时钟      GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_2|GPIO_Pin_3
发表于 2019-04-10

ZigBee串口说明

一、串口的初始化//系统初始化byte osal_init_system( void ){……osalInitTasks();//系统任务初始化……} //任务初始化void osalInitTasks( void ){……#if defined( MT_TASK )//如果定义了MT_TASK就初始化MT任务,所以要使用uart必须编译MT_TASKMT_TaskInit( taskID++ );#endif……}//MT_TASK初始化void MT_TaskInit( byte task_id ){MT_TaskID = task_id;//分配任务ID……SPIMgr_Init();//SPI(UART)管理
发表于 2019-04-09

STM32中 初始化ADXL345芯片

初始化ADXL345芯片void ADXL345init(){      Single_WriteI2C(0x31,0x0B);//低电平输出,13位全分辨率,输出数据右对齐,16g量程 Single_WriteI2C(0X2C,0x0A);//数据输出速率为100HZ,10ms读一次数据    Single_WriteI2C(0X2D,0x28);//链接使能,测量模式    Single_WriteI2C(0X2E,0x80);//INT_ENABLE,使能动态监测终端    Single_WriteI2C(0X1E
发表于 2019-03-28

STM32 HSE初始化失败的解决以及HSI初始化

偶然遇到一个问题,假设HSE初始化失败怎么办,库函数内没有提供处理只是写了   if (HSEStatus == (uint32_t)0x01){。。。} else  { /* If HSE fails to start-up, the application will have wrong clock          configuration. User can add here some code to deal with this error */  }让我们自己处理。平常我们都是用SysClk =72M。这是
发表于 2019-03-18
STM32 HSE初始化失败的解决以及HSI初始化

STM32F4学习笔记4——STM32的AD用DMA方式时的请注意初始化顺序

我突然意识到我的数据好像一直没有错位,看到这个我又试验了一下,发现把DMA_Cmd(DMA1_Channel1, ENABLE);放置到哪儿都是一样的啊~~~ 这个是原帖部分: STM32的AD用DMA方式时的请注意初始化顺序 珍情岁月(84848098) 17:19:23DMA_DeInit(DMA1_Channel1);  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_Result; 
发表于 2019-02-19

小广播

何立民专栏

单片机及嵌入式宝典

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

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