Lanqiao Cup Embedded-Real Time Clock RTC

Basic knowledge

Introduction

RTC is an independent timer of STM32, which can realize the clock calendar function under the corresponding software configuration. Lanqiao Cup mainly investigates his clock function on RTC. For details, please refer to the 9th Provincial Competition Questions of Embedded. The investigation of RTC is not difficult, but it must also be mastered.
What needs to be remembered is the difference between RTC and ordinary timers: the RTC module and the clock configuration system are in the backup area, that is, after the system is reset or wakes up from standby mode, the RTC settings and time remain unchanged. However, after the system is reset, access to the backup register and RTC is prohibited to prevent accidental operations on the backup area, so the write protection of the backup area should be removed before setting the RTC. ( These contents are all written in the STM32 reference manual. I hope you can use the reference manual proficiently. It is very useful for both objective and subjective questions! )

RTC configuration steps:

  1. Enable PWR and BKP clock
  2. Enable backup register access
  3. Configure RTC clock source and enable RTC clock
  4. Configure RTC prescaler coefficient
  5. Set time
  6. Enable related interrupts
  7. Write interrupt service function
  8. Note: Some operations need to wait for the write operation to complete and synchronize

Code:

In the RTC driver file is the following:

#define HH 11  //时
#define MM 59  //分
#define SS 50  //秒

extern uint32_t TimeDisplay;//标志位,在产生秒中断时更新时间

void RTC_Config()
{
    
    
 NVIC_InitTypeDef NVIC_InitStructure;
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);//使能PWR和BKP的时钟
 PWR_BackupAccessCmd(ENABLE);//使能后备寄存器访问
 BKP_DeInit();
 
 RCC_LSICmd(ENABLE);//选择LSI为时钟
 while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);//等待LSI低速时钟准备就绪
 
 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
 
 RCC_RTCCLKCmd(ENABLE);
 RTC_WaitForSynchro(); //等待同步
 RTC_WaitForLastTask(); //等待写完成
 
 RTC_ITConfig(RTC_IT_SEC, ENABLE);
 RTC_WaitForLastTask();//等待写完成
 /* Set RTC prescaler: set RTC period to 1sec */
 RTC_SetPrescaler(39999); /* RTC period = RTCCLK/RTC_PR = (40 KHz)/(39999+1) */
 RTC_WaitForLastTask();//等待写完成
 
 RTC_SetCounter(HH*3600+MM*60+SS);//设置时间
 RTC_WaitForLastTask();//等待写完成
 
 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组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 Time_Display(u32 TimeVar)//LCD显示函数
{
    
    
 char text[20];
 u32 THH = 0, TMM = 0, TSS = 0;
  /* Compute  hours */
 THH = TimeVar / 3600;
 /* Compute minutes */
 TMM = (TimeVar % 3600) / 60;
 /* Compute seconds */
 TSS = (TimeVar % 3600) % 60;
  sprintf(text,"Time: %0.2d:%0.2d:%0.2d",THH, TMM, TSS);
 LCD_DisplayStringLine(Line6,(u8 *)text);
 }
void RTC_IRQHandler(void)//RTC的秒中断
{
    
    
  if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
  {
    
    
  RTC_ClearITPendingBit(RTC_IT_SEC);
  TimeDisplay = 1;  //时间更新标志置位
    /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
    /* 23:59:59 */
  if (RTC_GetCounter() == 0x00015180)//写成24*3600也是可以的
  {
    
    
   RTC_SetCounter(0x0);
   RTC_WaitForLastTask();
  }
 }
}

Write this in the main function:

 while(1)
 {
    
    
  if(TimeDisplay == 1)//RTC计数器每加1s,会进入中断更新标志位,在主函数中便会显示当前计数器的值。
  {
    
    
   Time_Display(RTC_GetCounter());
   TimeDisplay = 0;  //清除标志位
  }
 }

Show results

Insert picture description here

Guess you like

Origin blog.csdn.net/qq_43690936/article/details/105317394