STM32L中的系统时间——硬件RTC的使用

鼓捣了将近一天。。。因为之前用过STM32F103芯片,而这次是STM32L151,这个L系列和F系列的RTC使用方式不同。废话少说,上代码:

RTC初始化:

//硬件RTC时钟初始化
void RTC_Configuration()
{
  /* Allow access to the RTC */
  PWR_RTCAccessCmd(ENABLE);

  /* Reset RTC Backup Domain */
  RCC_RTCResetCmd(ENABLE);
  RCC_RTCResetCmd(DISABLE);

  /* LSE Enable */
  RCC_LSEConfig(RCC_LSE_ON);

  /* Wait until LSE is ready */
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);

   /* RTC Clock Source Selection */ 
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); 

  /* Enable the RTC */
  RCC_RTCCLKCmd(ENABLE);   
  
}


读写RTC时间:

//设置本地硬件RTC时间
void SetRTC(long hhmmss,long ddmmyy)
{
  RTC_TimeTypeDef RTC_TimeStruct;
  RTC_DateTypeDef RTC_DateStruct;
  RTC_TimeStruct.RTC_Hours = hhmmss/10000;
  RTC_TimeStruct.RTC_Minutes = hhmmss/100%100;
  RTC_TimeStruct.RTC_Seconds = hhmmss%100;
  RTC_TimeStruct.RTC_H12 = 0; //程序中不使用上午/下午
  RTC_SetTime(RTC_Format_BIN,&RTC_TimeStruct);
  RTC_DateStruct.RTC_Year = ddmmyy%100;
  RTC_DateStruct.RTC_Date = ddmmyy/10000;
  RTC_DateStruct.RTC_Month = ddmmyy/100%100;
  RTC_DateStruct.RTC_WeekDay = 1;//程序中不使用星期
  RTC_SetDate(RTC_Format_BIN,&RTC_DateStruct);
}

//获取本地硬件RTC时间
void GetRTC(long *hhmmss,long *yymmdd)
{
  RTC_TimeTypeDef time;
  RTC_DateTypeDef date;
  RTC_GetTime(RTC_Format_BIN,&time);
  RTC_GetDate(RTC_Format_BIN,&date);
  
  *hhmmss = time.RTC_Hours*10000 + time.RTC_Minutes*100 + time.RTC_Seconds;
  *yymmdd = date.RTC_Year*10000 + date.RTC_Month*100 + date.RTC_Date;
}


主函数:

char coord[64];//当前经纬度
long date,time;//当前UTC时间


int main(void)
{ 
	Init();
  
  SetRTC(115921,140203);
  while(1){
    GetRTC(&time,&date);
    sprintf(coord,"%06d,%06d",date,time);
    delay_s(1);
  }
}


另外我使用的是8Mhz(8000000Hz)的外部晶振作为系统时间。因此把系统时钟RCC的初始化也贴上来,有需要的读者自行取用:)

/**********************************************************************
* 名    称:RCC_Configuration()
* 功    能:配置时钟
* 入口参数: 
* 出口参数:
-----------------------------------------------------------------------
* 说明:使用库函数
***********************************************************************/
void RCC_Configuration(void)
{
   ErrorStatus HSEStartUpStatus;
   
	 RCC_DeInit();
    //使能外部晶振
   RCC_HSEConfig(RCC_HSE_ON);
    //等待外部晶振稳定
   HSEStartUpStatus = RCC_WaitForHSEStartUp();
    //如果外部晶振启动成功,则进行下一步操作
   if(HSEStartUpStatus==SUCCESS)
   {
		 //设置HCLK(AHB时钟)=SYSCLK
		 RCC_HCLKConfig(RCC_SYSCLK_Div1);

			
			   //PCLK2(APB2) = HCLK
		 RCC_PCLK2Config(RCC_HCLK_Div1);
			
        //PCLK1(APB1) = HCLK/2
		 RCC_PCLK1Config(RCC_HCLK_Div2);
		 FLASH_SetLatency(FLASH_Latency_1);
 		 FLASH_PrefetchBufferCmd(ENABLE);

     //等待PLL稳定
    // while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
		while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);			
        
		 //系统时钟SYSCLK来
     // RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
	   RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);
			
     //切换时钟后等待系统时钟稳定
     // while(RCC_GetSYSCLKSource()!=0x0C);
     while(RCC_GetSYSCLKSource()!=0x08);			 
     }
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

}



运行效果就是,使用Keil uVision4.70的debug模式,可以看到Watch窗口中的coord变量实时显示出当前的时间。


之前我还搜到将SysTick作为系统时间的方法,其实就是借助SysTick中断来自行计时,虽然也能满足项目需求(比较简单),但后来经同事提醒才发觉STM32L里面有内置的硬件RTC时钟,包含了年月日时分秒,才开始了这一天的鼓捣。

今天看了半天stm32l1xx_rtc.h和.c文件,这是在STM32L-Discovery工程里面内置的,包含了对当前芯片的RTC功能的API接口定义和实现,还有充足的注释,个人感觉这个比文档更清晰。不过这没能解决问题。

最后还是用谷歌搜STM32L和RTC搜到的这个网页,才是解决问题的关键。里面包含了STM32L中RTC初始化的代码,测试可用,算是突破。之后就顺利了。



你可能感兴趣的:(STM32)