打印
[应用相关]

STM32 RTC小结

[复制链接]
767|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
powerful1|  楼主 | 2015-3-28 21:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
RTC可以用来设置实时时钟,并产生秒中断或闹钟中断。在芯片有电源供电的情况下,系统掉电后仍能保持时钟计时。
RTC设置需要涉及对电源(PWR)、备份区域(BKP)和RCC部分寄存器的改写。
RTC所需的晶振在RCC部分的寄存器中选择。在芯片时钟系统中对RTC的时钟提供如下图所示。RTC时钟可以从LSI, LSE和HSE分频中选择。这些需要对RCC寄存器的一些位进行设置。
RTC的预分频器、计数器和闹钟寄存器在备份区域中,以保证系统掉电后,在电池供电时仍能计数,如下图所示。在电源部分,系统复位后,将禁止向备份区域写入内容,因此,若要配置RTC,需要在电源部分允许对备份区域的写入。
备份区中有留给用户写入数据的空间。由于掉电后备份区中的内容仍保持,可以通过对用户写入数据的比较,知道备份区中的设置(尤其是RTC设置)是否存在。若不存在,需要清空备份区并重新写入;若存在,则只需再次写入备份区之外的RTC_CR。
由于用户是通过APB1接口读写RTC寄存器,在上电之后,需要先等待APB1接口与RTC同步完成,否则读取的RTC值可能有误;完成同步以RTC_CRL的RSF位置1为标志。对于写RTC寄存器,先查询RTC_CRL的RTOFF位,直到为1,说明上一次操作已经完成;再CNF置1,进入配置模式;写寄存器;CNF置0,退出配置模式;等待RTOFF位为1,说明本次写入已经完成。

沙发
powerful1|  楼主 | 2015-3-28 21:57 | 只看该作者
下面贴一个可以跑通的简化流程,完成按秒计数的功能。

[cpp] view plaincopy


  • #include "stm32f10x.h"  
  • #include "stm32_eval.h"  
  • #include <stdio.h>  
  • #include "stm3210c_eval_lcd.h"  
  •   
  • volatile uint32_t TimeDisplay = 0;  
  • int main(void)  
  • {  
  •   /*!< At this stage the microcontroller clock setting is already configured,  
  •        this is done through SystemInit() function which is called from startup
  •        file (startup_stm32f10x_xx.s) before to branch to application main.
  •        To reconfigure the default setting of SystemInit() function, refer to
  •        system_stm32f10x.c file
  •      */      
  •   
  •     RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);  
  •     PWR_BackupAccessCmd(ENABLE);  
  •     NVIC_Configuration();  
  •   
  •     STM3210C_LCD_Init();  
  •     LCD_Clear(LCD_COLOR_WHITE);  
  •     LCD_SetTextColor(LCD_COLOR_BLUE);  
  •   if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)  
  •   {  
  •     RTC_Configuration();  
  •     Time_Adjust();  
  •     BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);  
  •   }  
  •   else  
  •   {  
  •     RTC_WaitForSynchro();  
  •     RTC_WaitForLastTask();  
  •     RTC_ITConfig(RTC_IT_SEC, ENABLE);  
  •     RTC_WaitForLastTask();  
  •   }  
  •   
  •   RCC_ClearFlag();  
  •   Time_Show();  
  •   
  • }  
  •   
  •   
  • void NVIC_Configuration(void)  
  • {  
  •   NVIC_InitTypeDef NVIC_InitStructure;  
  •   
  •   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  
  •   
  •   NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;  
  •   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  
  •   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
  •   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  •   NVIC_Init(&NVIC_InitStructure);  
  • }  
  •   
  • void RTC_Configuration(void)  
  • {  
  •   BKP_DeInit();  
  •   
  •   RCC_LSEConfig(RCC_LSE_ON);  
  •   while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)  
  •   {}  
  •   
  •   RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);  
  •   
  •   RCC_RTCCLKCmd(ENABLE);  
  •   
  •   RTC_WaitForSynchro();  
  •   
  •   RTC_WaitForLastTask();  
  •   
  •   RTC_ITConfig(RTC_IT_SEC, ENABLE);  
  •   
  •   RTC_WaitForLastTask();  
  •   
  •   RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */  
  •   
  •   RTC_WaitForLastTask();  
  • }  
  •   
  • uint32_t Time_Regulate(void)  
  • {  
  •   uint32_t Tmp_HH = 0x00, Tmp_MM = 0x00, Tmp_SS = 0x00;  
  •   return((Tmp_HH*3600 + Tmp_MM*60 + Tmp_SS));  
  • }  
  •   
  • void Time_Adjust(void)  
  • {  
  •   RTC_WaitForLastTask();  
  •   RTC_SetCounter(0);//Time_Regulate());  
  •   RTC_WaitForLastTask();  
  • }  
  •   
  • void Time_Display(uint32_t TimeVar)  
  • {  
  •   uint32_t THH = 0, TMM = 0, TSS = 0;  
  •   char buf[15];  
  •    
  •   /* Reset RTC Counter when Time is 23:59:59 */  
  •   if (TimeVar == 0x0001517F)  
  •   {  
  •      RTC_WaitForLastTask();  
  •      RTC_SetCounter(0x0);  
  •      /* Wait until last write operation on RTC registers has finished */  
  •      RTC_WaitForLastTask();  
  •   }  
  •    
  •   /* Compute  hours */  
  •   THH = TimeVar / 3600;  
  •   /* Compute minutes */  
  •   TMM = (TimeVar % 3600) / 60;  
  •   /* Compute seconds */  
  •   TSS = (TimeVar % 3600) % 60;  
  •       
  •     sprintf(buf, "%0.2d:%0.2d:%0.2d/r", THH, TMM, TSS);  
  •     LCD_DisplayStringLine(LCD_LINE_2, buf);  
  •   //printf("Time: %0.2d:%0.2d:%0.2d/r", THH, TMM, TSS);  
  • }  
  •   
  • /**
  •   * @brief  Shows the current time (HH:MM:SS) on the Hyperterminal.
  •   * @param  None
  •   * @retval None
  •   */     
  • void Time_Show(void)  
  • {  
  • //  printf("/n/r");  
  •   
  •   /* Infinite loop */  
  •   while (1)  
  •   {  
  •     /* If 1s has been elapased */  
  •     if (TimeDisplay == 1)  
  •     {  
  •       uint32_t Counter = 0;  
  •       Counter = RTC_GetCounter();  
  •       Time_Display(Counter);  
  •       TimeDisplay = 0;  
  •     }  
  •   }  
  • }  
  •   
  • void RTC_IRQHandler(void)  
  • {  
  •   if (RTC_GetITStatus(RTC_IT_SEC) != RESET)  
  •   {  
  •     RTC_WaitForLastTask();  
  •   
  •     /* Clear the RTC Second interrupt */  
  •     RTC_ClearITPendingBit(RTC_IT_SEC);  
  •   
  •     /* Toggle LED1 */  
  • //    STM_EVAL_LEDToggle(LED1);  
  •   
  •     /* Enable time update */  
  •     TimeDisplay = 1;  
  •   
  •     /* Wait until last write operation on RTC registers has finished */  
  •     RTC_WaitForLastTask();  
  •       
  •   }  
  • }  



使用特权

评论回复
板凳
quray1985| | 2015-3-29 09:31 | 只看该作者
您的总结很详细,谢谢分享

使用特权

评论回复
地板
搞IT的| | 2015-3-29 10:28 | 只看该作者
楼主辛苦!感谢分享!留着日后用!

使用特权

评论回复
5
爱金则忍| | 2015-3-29 10:34 | 只看该作者
说得好!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

88

主题

430

帖子

4

粉丝