(STM32F4) Real-time Clock
老實說Real-time Clok這項功能,我也只有在PC和手機上有見過,其他的應用產品上我也很少見到。
言歸正傳在STM32F4 RTC這項功能在IC內部就有內建,在早期的8051是如果要做RCT是需要外接IC的。
而RTC只需要透過register setting就可以達成12 or 24 format也有提供2個 alrm interrupt, wake up。
由上面的Function diagram可以得知幾個重要的地方。
1. 紫色的框框是我們主要必須配置的Block
2. Alarm 有 A & B 可以使用且有 ALRAF ALRBF,2個flag可以知道是否有發生Event
3. 反黑的2個 block 是我們取得RTC時間的Register
4. 在block最上方有一個backup register和RTC tamper control register做了一下功課,理解是因為RTC與SRAM有關因為必須存放資料。而STM32F4有一塊區域叫做backup domain這塊區域是由power switch做控制分成Standby/VBAT/low power(LP)。所以必須要enable power control register backup access。
RTC配置
1 void RTC_Config(void) 2 { 3 RTC_InitTypeDef RTC_InitStructure; 4 RTC_TimeTypeDef RTC_TimeStructure; 5 RTC_DateTypeDef RTC_DateStructure; 6 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE); 7 PWR_BackupAccessCmd(ENABLE); 8 RCC_LSICmd(ENABLE); 9 while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); 10 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); 11 RCC_RTCCLKCmd(ENABLE); 12 RTC_WaitForSynchro(); 13 14 if(RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x1234) 15 { 16 RTC_WriteProtectionCmd(DISABLE); 17 RTC_EnterInitMode(); 18 19 RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; 20 RTC_InitStructure.RTC_AsynchPrediv = 0x7D-1; 21 RTC_InitStructure.RTC_SynchPrediv = 0xFF-1; 22 RTC_Init(&RTC_InitStructure); 23 24 RTC_TimeStructure.RTC_Seconds = 0x00; 25 RTC_TimeStructure.RTC_Minutes = 58; 26 RTC_TimeStructure.RTC_Hours = 0x01; 27 RTC_TimeStructure.RTC_H12 = RTC_H12_AM; 28 RTC_SetTime(RTC_Format_BIN,&RTC_TimeStructure); 29 30 RTC_DateStructure.RTC_Date = 17; 31 RTC_DateStructure.RTC_Month = 11; 32 RTC_DateStructure.RTC_WeekDay= RTC_Weekday_Thursday; 33 RTC_DateStructure.RTC_Year = 17; 34 RTC_SetDate(RTC_Format_BIN,&RTC_DateStructure); 35 36 RTC_ExitInitMode(); 37 RTC_WriteBackupRegister(RTC_BKP_DR0,0x1234); 38 RTC_WriteProtectionCmd(ENABLE); 39 } 40 PWR_BackupAccessCmd(DISABLE); 41 }
RTC有防讀寫保護所以在設定時必須要進入/出init mode
1 RTC_EnterInitMode(); 2 RTC_ExitInitMode();
再網上我最有疑問的設定是下列這句
1 if(RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x1234)
這句設定是指說DR0必須要判斷是否為第一次寫入設定如果不是則進入if繼續做初始化。否則就不做初始化設定。
因為我的板子是使用F4系列的Discovery所以我的RTC沒有LSE可以用,所以我的設定是LSI (internal和External Clock)。
1 int main(void) 2 { 3 LED_Config(); 4 Delay_Init(); /* initialize delay function */ 5 USART_Config(); 6 RTC_Config(); 7 printf("\n--------------------------------------------------\n"); 8 printf("\n STM32F4 RTC Function test \n"); 9 printf("\n--------------------------------------------------\n"); 10 11 while(1) 12 { 13 RTC_GetTime(RTC_Format_BIN, &data_time); 14 RTC_GetDate(RTC_Format_BIN, &data_date); 15 printf("%d-%02d-%02d ,", data_date.RTC_Year + 2000, data_date.RTC_Month, data_date.RTC_Date); 16 printf("%02d:%02d:%02d\n", data_time.RTC_Hours, data_time.RTC_Minutes, data_time.RTC_Seconds); 17 DelayMs(1000); 18 } 19 }