RTC实时时钟(LCD显示)

 

目录

RTC简介

RTC时钟框图

RTC工作原理图

RTC相关寄存器(详细配置过程参考STM32参考手册)

部分代码分析

附录


 

  •  RTC简介

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

RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒后,RTC的设置和时间维持不变。
系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操作。执行以下操作将使能对后备寄存器和RTC的访问:
  ● 设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟
  ● 设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问

  • RTC时钟框图

RTC实时时钟(LCD显示)_第1张图片

时钟可配置为 

  1. HSE的128分频
  2. LSE
  3. LSI
  • RTC工作原理图

RTC实时时钟(LCD显示)_第2张图片

RTC由两个主要部分组成(参见上图)。

第一部分(APB1接口)用来和APB1总线相连。此单元还包含一组16位寄存器,可通过APB1总线对其进行读写操作(参见16.4节)。APB1接口由APB1总线时钟驱动,用来与APB1总线接口。
另一部分(RTC核心)由一组可编程计数器组成,分成两个主要模块。第一个模块是RTC的预分频模块,它可编程产生最长为1秒的RTC时间基准TR_CLK。RTC的预分频模块包含了一个20位的可编程分频器(RTC预分频器)。如果在RTC_CR寄存器中设置了相应的允许位,则在每个TR_CLK周期中RTC产生一个中断(秒中断)。第二个模块是一个32位的可编程计数器,可被初始化为当前的系统时间。系统时间按TR_CLK周期累加并与存储在RTC_ALR寄存器中的可编程时间相比较,如果RTC_CR控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。

  • RTC相关寄存器(详细配置过程参考STM32参考手册)

  1. RTC控制寄存器             (RTC_CRH,   RTC_CRL)
  2. RTC预分频装载寄存器  (RTC_PRLHRTC_PRLL)
  3. RTC预分频余数寄存器  (RTC_DIVH,  RTC_DIVL)
  4. RTC计数器寄存器         (RTC_CNTHRTC_CNTL)
  5. RTC闹钟寄存器             (RTC_ALRH RTC_ALRL)

    RTC_CRH

RTC实时时钟(LCD显示)_第3张图片

    RTC_CRL

RTC实时时钟(LCD显示)_第4张图片

RTC实时时钟(LCD显示)_第5张图片

   RTC_PRLH/RTC_PRLL

RTC实时时钟(LCD显示)_第6张图片

RTC实时时钟(LCD显示)_第7张图片

   RTC_DIVH / RTC_DIVL

RTC实时时钟(LCD显示)_第8张图片

   RTC_CNTH / RTC_CNTL

RTC实时时钟(LCD显示)_第9张图片

   RTC_ALRH/RTC_ALRL

RTC实时时钟(LCD显示)_第10张图片

  • 部分代码分析

 rtc初始化

void rtc_init()
{
	u8 t;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE); //使能PWR电源和BKP后备区
	//使能后备寄存器访问
	PWR_BackupAccessCmd(ENABLE);

	if(BKP_ReadBackupRegister(BKP_DR1) != 0x0002)  /*@@*/
	{
		BKP_DeInit();
		
		/********少代码**********/ /*已加*/
		RCC_LSEConfig(RCC_LSE_ON);	//设置外部低速晶振(LSE),使用外设低速晶振    /******* 注意 :  内部代码关闭了RTC时钟使能!*******/
		while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET&&t<250)	//检查指定的RCC标志位设置与否,等待低速晶振就绪
			{
			t++;
			delay_ms(10);
			}
		if(t>=250)return;
		
		//配置RTC时钟源
		RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
		RCC_RTCCLKCmd(ENABLE);
		
		RTC_WaitForLastTask();
		RTC_WaitForSynchro(); //等待RTC寄存器同步完成
	
		RTC_EnterConfigMode(); //允许配置
		
		RTC_ITConfig(RTC_IT_SEC|RTC_IT_ALR,ENABLE);  //开启闹钟和秒中断
		RTC_WaitForLastTask();
		RTC_SetPrescaler(32767);
		RTC_WaitForLastTask();		
		rtc_set_time(2018,12,1,19,2,30);
		
		RTC_ExitConfigMode(); //关闭配置
		
	}
	else 
	{
		/*******若已经配置过相应时间,1.则直接等待同步,ps: 只有同步时在可以读取寄存器的值 2. 开启相应中断 ************/
		RTC_WaitForSynchro();
		RTC_ITConfig(RTC_IT_SEC|RTC_IT_ALR,ENABLE);
		RTC_WaitForLastTask();
	}
	
	rtc_nvic_config();
	
	/********少代码*更新时间*******/  /*已加*/
	rtc_updata_time();//更新时间
	BKP_WriteBackupRegister(BKP_DR1,0x0002);   /*@@*/ //*用于防止重复操作    0x0002 : 随机值*//
}

rtc时间设置函数

void rtc_set_time(u16 year,u8 month,u8 day,u8 hour,u8 minute,u8 second)
{
	u32 value = 0;
	u16 i;
	
	if(year<1970 || year>2099)	return ;
	
	for(i=1970 ; i

rtc星期获取

/* 基姆拉尔森公式根据日期计算星期*/
u8 rtc_get_week(u16 year,u8 month,u8 day)
{ 
	 if(month <3)  
	 { 
		month+=   12; 
        --year; 
     } 
	return   (day+1+2*month+3*(month+1)/5+year+(year/4)-year/100+year/400)   %   7; 
}
  • 附录

RTC实时时钟实验代码(基于正点原子战舰 :  https://github.com/kks1234/STM32/tree/master/15.RTC%E6%97%B6%E9%92%9F

 

你可能感兴趣的:(嵌入式,STM32)