Forum: Mikrocontroller und Digitale Elektronik RTC setzen beim STM32F407


von Markus M. (mmax)


Lesenswert?

Hi,

Ich versuche die RTC bei meinem Olimex STM32-E407 zu setzten, bekomm 
aber in der Funktion RTC_SetDateTime() immer die Ausgaben "RTC_SetTime 
failed" und "RTC_SetDate failed", die RTC_Config() geht problemlos 
durch. Auf dem Port ist ein externern Quarz mit 32kHz an 
OSC32_IN/OSC32_OUT verbaut ... LSE sollte also doch passen, oder?

1
void RTC_Config(void) {
2
    /* Enable the PWR clock */
3
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
4
5
    /* Allow access to RTC */
6
    PWR_BackupAccessCmd(ENABLE);
7
8
    /* Enable the LSE OSC */
9
    RCC_LSEConfig(RCC_LSE_ON);
10
11
    /* Wait till LSE is ready */
12
    while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {
13
    }
14
15
    /* Select the RTC Clock Source */
16
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
17
    /* ck_spre(1Hz) = RTCCLK(LSE) /(uwAsynchPrediv + 1)*(uwSynchPrediv + 1)*/
18
    uwSynchPrediv = 0xFF;
19
    uwAsynchPrediv = 0x7F;
20
21
    /* Configure the RTC data register and RTC prescaler */
22
    RTC_InitStructure.RTC_AsynchPrediv = uwAsynchPrediv;
23
    RTC_InitStructure.RTC_SynchPrediv = uwSynchPrediv;
24
    RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
25
26
    /* Check on RTC init */
27
    if (RTC_Init(&RTC_InitStructure) == ERROR) {
28
        printf("RTC Prescaler Config failed\r\n");
29
    }
30
31
    /* Enable the RTC Clock */
32
    RCC_RTCCLKCmd(ENABLE);
33
34
    /* Wait for RTC APB registers synchronisation */
35
    RTC_WaitForSynchro();
36
37
    /* Enable The TimeStamp */
38
    RTC_TimeStampCmd(RTC_TimeStampEdge_Falling, ENABLE);
39
}
40
41
void RTC_SetDateTime(uint8_t year, uint8_t month, uint8_t day, uint8_t weekday, uint8_t hour, uint8_t min, uint8_t sec) {
42
    RTC_TimeTypeDef ts;
43
    RTC_DateTypeDef ds;
44
    
45
    RTC_TimeStructInit(&ts);
46
    RTC_DateStructInit(&ds);
47
    
48
    PWR_BackupAccessCmd(ENABLE);
49
    
50
    /* Set Time hh:mm:ss */
51
    ts.RTC_H12 = RTC_H12_AM;
52
    ts.RTC_Hours = hour;
53
    ts.RTC_Minutes = min;
54
    ts.RTC_Seconds = sec;
55
    
56
    if( RTC_SetTime(RTC_Format_BIN, &ts) == ERROR ) {
57
        printf("RTC_SetTime failed\r\n");
58
    }
59
60
    /* Set Date Week/Date/Month/Year */
61
    ds.RTC_WeekDay = weekday;
62
    ds.RTC_Date = day;
63
    ds.RTC_Month = month;
64
    ds.RTC_Year = year;
65
    
66
    if( RTC_SetDate(RTC_Format_BIN, &ds) == ERROR ) {
67
        printf("RTC_SetDate failed\r\n");
68
    }
69
70
    /* Write BkUp DR0 */
71
    RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);
72
    
73
    PWR_BackupAccessCmd(DISABLE);
74
}

von holger (Gast)


Lesenswert?

Bei mir funktioniert das so:
1
/**
2
  * @brief  Configures the RTC peripheral and select the clock source.
3
  * @param  None
4
  * @retval None
5
  */
6
static void RTC_Config(void)
7
{
8
  RTC_InitTypeDef  RTC_InitStructure;
9
  RTC_TimeTypeDef  RTC_TimeStruct;
10
  RTC_DateTypeDef  RTC_DateStruct;
11
12
  /* Enable the PWR clock */
13
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
14
15
  /* Allow access to RTC */
16
  PWR_BackupAccessCmd(ENABLE);
17
18
  /* Reset RTC Domain */
19
  RCC_BackupResetCmd(ENABLE);
20
  RCC_BackupResetCmd(DISABLE);
21
22
  /* Enable the LSE OSC */
23
  RCC_LSEConfig(RCC_LSE_ON);
24
25
  /* Wait till LSE is ready */
26
  while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
27
  {
28
  }
29
30
  /* Select the RTC Clock Source */
31
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
32
33
  /* Enable the RTC Clock */
34
  RCC_RTCCLKCmd(ENABLE);
35
36
  /* Wait for RTC APB registers synchronisation */
37
  RTC_WaitForSynchro();
38
39
  /* Configure the RTC data register and RTC prescaler */
40
  /* ck_spre(1Hz) = RTCCLK(LSI) /(AsynchPrediv + 1)*(SynchPrediv + 1)*/
41
  RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
42
  RTC_InitStructure.RTC_SynchPrediv  = 0xFF;
43
  RTC_InitStructure.RTC_HourFormat   = RTC_HourFormat_24;
44
  RTC_Init(&RTC_InitStructure);
45
46
  /* Set the time to 00h 00mn 00s AM */
47
  RTC_TimeStruct.RTC_H12     = RTC_H12_AM;
48
  RTC_TimeStruct.RTC_Hours   = 9;
49
  RTC_TimeStruct.RTC_Minutes = 31;
50
  RTC_TimeStruct.RTC_Seconds = 0;
51
  RTC_SetTime(RTC_Format_BIN, &RTC_TimeStruct);
52
53
  /* Wait for RTC APB registers synchronisation */
54
  RTC_WaitForSynchro();
55
56
  RTC_DateStruct.RTC_Date = 25;
57
  RTC_DateStruct.RTC_Month = 10;
58
  RTC_DateStruct.RTC_WeekDay = 5;  // 1 is monday
59
  RTC_DateStruct.RTC_Year = 13;
60
  RTC_SetDate(RTC_Format_BIN, &RTC_DateStruct);
61
}

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

@holger: ist zwar schon eine Weile her - aber Dein Codebeispiel hat 
gerade geholfen, eine mehrstündige Fehlersuche in einer Kundenfirmware 
zu beenden.

Nebenbemerkung:
Diese RTC Backup-Register sind zäh.
Selbst das Kurzschließen der VBAT ist keine Garantie, dass die Teile 
Ihren Inhalt wirklich verlieren.

Was wirklich während der Entwicklung hilft - hartes Überschreiben der 
Register:
#ifdef  MAH_RTC_WIPE
  RTC_WriteBackupRegister( RTC_STATUS_REG, 0x4711 );
#endif


Ansonsten läuft die RTC nun fein und zieht sich im Backup-Fall ca.4µA 
aus einer CR2023.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.