找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3992|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

STM32 實時時鐘RTC原理和編程要旨

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:91350 發(fā)表于 2015-10-29 19:03 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
   RTC是工業(yè)領(lǐng)域?qū)崟r控制離不開的一個外設(shè),相當(dāng)于一個獨立的定時器,STM32的RTC外設(shè)由一組連續(xù)計數(shù)的計數(shù)器組成,具體來說,由兩個部分組成:第一部分指APB1接口用來和APB1總線相連,此單元還包含一組1位寄存器,可通過APB1總線對其進(jìn)行讀寫操作,APB1接口由APB1總線時鐘驅(qū)動,用來與APB1總線相連;另一部分由一組可編程計數(shù)器組成,主要分為兩個模塊:第一個模塊為RTC的預(yù)分頻模塊,它可編程產(chǎn)生最長為1s的RTC時間基準(zhǔn)TR_CLK,RTC的預(yù)分頻模塊包含了一個20位的可編程分頻器(RTC預(yù)分頻器),如果在RTC_CR寄存器中設(shè)置了相應(yīng)的允許位,則在每個TR_CLK周期中RTC產(chǎn)生一個中斷,即所謂的秒中斷;第二個模塊是一個32位的可編程計數(shù)器,可被初始化為當(dāng)前的系統(tǒng)時間。系統(tǒng)時間按TR_CLK周期累加并與存儲在RTC_ALR寄存器中的可編程時間相比較,如果TR_CLK控制寄存器中設(shè)置了相應(yīng)允許位,比較匹配時將產(chǎn)生一個鬧鐘中斷,具體見下圖所示;


#include "stm32f10x_lib.h"
#include "platform_config.h"
#include

vu32 TimeDisplay = 0;
u32 hour = 0, minute = 0, second = 0;
void RCC_Configuration(void);
void GPIO_Configuration(void);
void RTC_Configuration(void);
void NVIC_Configuration(void);
void Time_Adjust(void);
void Time_Display(u32 TimeVar);
void Time_Regulate(u32 Tmp_HH,u32 Tmp_MM,u32 Tmp_SS);
int main(void)
{
  RCC_Configuration();
  NVIC_Configuration();
  GPIO_Configuration();
  RTC_Configuration();
  if (BKP_ReadBackupRegister(BKP_DR1) !=0xA5A5)
  {
   
   Time_Adjust();
   BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
  }
  else
  {  
   
   RTC_WaitForSynchro();
   
   RTC_ITConfig(RTC_IT_SEC, ENABLE);
   
   RTC_WaitForLastTask();
  }
   
   Time_Regulate(12,45,30);
  while (1)
  {
    if(TimeDisplay == 1)
    {
     
     Time_Display(RTC_GetCounter());
     TimeDisplay = 0;
    }
  }
}

void RCC_Configuration(void)
{
  ErrorStatus HSEStartUpStatus;

  RCC_DeInit();

  RCC_HSEConfig(RCC_HSE_ON);

  HSEStartUpStatus = RCC_WaitForHSEStartUp();
  if (HSEStartUpStatus == SUCCESS)
  {
   
   FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
   
   FLASH_SetLatency(FLASH_Latency_2);
   
   RCC_HCLKConfig(RCC_SYSCLK_Div1);
   
   RCC_PCLK2Config(RCC_HCLK_Div1);
   
   RCC_PCLK1Config(RCC_HCLK_Div2);
   
   RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
   
   RCC_PLLCmd(ENABLE);
   
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {}
   
   RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
   
    while(RCC_GetSYSCLKSource() != 0x08)
    {}
  }

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|
                        RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC , ENABLE);

}

void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
#ifdef  VECT_TAB_RAM

  NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);
#else

  NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
#endif

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  NVIC_InitStructure.NVIC_IRQChannel =RTC_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;
  NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
  GPIO_Init(GPIO_LED,&GPIO_InitStructure);
}

void RTC_Configuration(void)
{

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR |RCC_APB1Periph_BKP, ENABLE);

  PWR_BackupAccessCmd(ENABLE);

  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_WaitForLastTask();
}


void Time_Adjust(void)
{

  RTC_WaitForLastTask();

  RTC_SetCounter(0);

  RTC_WaitForLastTask();
}

void Time_Regulate(u32 Tmp_HH,u32 Tmp_MM,u32 Tmp_SS)
{

  u32 RTC_Counter;
  RTC_Counter = Tmp_HH*3600 + Tmp_MM*60 +Tmp_SS;

  RTC_WaitForLastTask();

  RTC_SetCounter(RTC_Counter);

  RTC_WaitForLastTask();
}

void Time_Display(u32 TimeVar)
{

  hour = TimeVar / 3600;

  minute = (TimeVar % 3600) / 60;

  second = (TimeVar % 3600) % 60;
}


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表