Forum: Mikrocontroller und Digitale Elektronik STM32 RTC initialisieren?


von Pascal R. (pacco)


Lesenswert?

Guten morgen,

Hab vor ein paar Tagen angefangen mich mit dem STM32 auseinander zu 
setzten. Das klappt soweit auch ganz gut.

Habe ein fertiges Board mit einem STM32F103RBT6 und einer Pufferbatterie 
für die Uhr drauf.
Dabei waren einige Beispiel Hex Files. Unter anderem auch eins für die 
Uhr. Das funktioniert auch soweit.
Nur im eigenen Programm bekomm ich das nicht so richtig hin. Sitz jetzt 
schon die ganze Nacht dran und hab fast jeden Googleeintrag dazu gelesen 
(aber nicht unbedingt verstanden :))

Jetzt mal zu den Deteils:
Programmiere mit Keil uVision4, also c was relativ neu für mich ist. Hab 
vorher recht viel mit Basic (Bascom, VB...) gemacht.

Die Zeit lese ich mit TimeVar=RTC->CNTL; aus was auch soweit 
funktioniert. Zählt zumindest im Sekundentakt hoch.
Allerdings fängt das ganze nach einem Reset immer wieder bei null an. 
Wie gesagt im Beispiel läuft die Zeit bei ausgeschaltetem Controller 
über die Pufferbatterie weiter.

Wie sieht das jetzt mit dem Einstellen oder Initialisieren der RTC aus.

Muss ich der extra sagen dass sie über VBat weiter laufen soll oder muss 
ich beim Einschalten die Zeit aus irgend einem Speicher laden?

Bin da langsam recht ratlos und wäre für Hilfe dankbar

Grüße
Pacco

von Mike R. (thesealion)


Lesenswert?

Dann zeig uns doch mal, wie du die RTC einstellst / initialisierst.

Eigentlich zeigen die Beispiele von ST recht schön, wie man die RTC und 
die Backup Domain benutzen muss.

von Pascal R. (pacco)


Lesenswert?

Das ganze sieht bis jetzt so aus:
1
/******************************************************************************/
2
/*                                                                            */
3
/*                             Real-Time Clock                                */
4
/*                                                                            */
5
/******************************************************************************/
6
7
/*******************  Bit definition for RTC_CRH register  ********************/
8
#define  RTC_CRH_SECIE                       ((uint8_t)0x01)               /*!<Second Interrupt Enable */
9
#define  RTC_CRH_ALRIE                       ((uint8_t)0x02)               /*!<Alarm Interrupt Enable */
10
#define  RTC_CRH_OWIE                        ((uint8_t)0x04)               /*!<OverfloW Interrupt Enable */
11
12
/*******************  Bit definition for RTC_CRL register  ********************/
13
#define  RTC_CRL_SECF                        ((uint8_t)0x01)               /*!<Second Flag */
14
#define  RTC_CRL_ALRF                        ((uint8_t)0x02)               /*!<Alarm Flag */
15
#define  RTC_CRL_OWF                         ((uint8_t)0x04)               /*!<OverfloW Flag */
16
#define  RTC_CRL_RSF                         ((uint8_t)0x08)               /*!<Registers Synchronized Flag */
17
#define  RTC_CRL_CNF                         ((uint8_t)0x10)               /*!<Configuration Flag */
18
#define  RTC_CRL_RTOFF                       ((uint8_t)0x20)               /*!<RTC operation OFF */
19
20
/*******************  Bit definition for RTC_PRLH register  *******************/
21
#define  RTC_PRLH_PRL                        ((uint16_t)0x000F)            /*!<RTC Prescaler Reload Value High */
22
23
/*******************  Bit definition for RTC_PRLL register  *******************/
24
#define  RTC_PRLL_PRL                        ((uint16_t)0xFFFF)            /*!<RTC Prescaler Reload Value Low */
25
26
/*******************  Bit definition for RTC_DIVH register  *******************/
27
#define  RTC_DIVH_RTC_DIV                    ((uint16_t)0x000F)            /*!<RTC Clock Divider High */
28
29
/*******************  Bit definition for RTC_DIVL register  *******************/
30
#define  RTC_DIVL_RTC_DIV                    ((uint16_t)0xFFFF)            /*!<RTC Clock Divider Low */
31
32
/*******************  Bit definition for RTC_CNTH register  *******************/
33
#define  RTC_CNTH_RTC_CNT                    ((uint16_t)0xFFFF)            /*!<RTC Counter High */
34
35
/*******************  Bit definition for RTC_CNTL register  *******************/
36
#define  RTC_CNTL_RTC_CNT                    ((uint16_t)0xFFFF)            /*!<RTC Counter Low */
37
38
/*******************  Bit definition for RTC_ALRH register  *******************/
39
#define  RTC_ALRH_RTC_ALR                    ((uint16_t)0xFFFF)            /*!<RTC Alarm High */
40
41
/*******************  Bit definition for RTC_ALRL register  *******************/
42
#define  RTC_ALRL_RTC_ALR                    ((uint16_t)0xFFFF)            /*!<RTC Alarm Low */

Bin mir nicht sicher ob das alles ist. Ist wie gesagt etwas neu für mich

von hp-freund (Gast)


Lesenswert?

Mike S. schrieb:
> wie man die RTC und
> die Backup Domain benutzen muss.

http://www.coocox.org/show_exam/RTC/383.html

Das Problem ist die Initialisierung selbst.

Ab hier:
if (RTC_ReadBackupRegister(RTC_BKP_DR0) ......

wird entschieden was bei Reset passiert und ob die Uhr schon gestellt 
ist.

von ./. (Gast)


Lesenswert?

> Eigentlich zeigen die Beispiele von ST recht schön, wie man die RTC und
> die Backup Domain benutzen muss.

Das Beispiel moechte ich mal sehen.

An den interessanten Stellen haben die Examples von ST immer aufgehoert.

von Mike R. (thesealion)


Lesenswert?

./. schrieb:
>
> Das Beispiel moechte ich mal sehen.
>
> An den interessanten Stellen haben die Examples von ST immer aufgehoert.


Was sind denn für dich die interessanten Stellen?

das hier stammt direkt aus der StdLib:
1
  if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
2
  {
3
    /* Backup data register value is not correct or not yet programmed (when
4
       the first time the program is executed) */
5
6
    printf("\r\n\n RTC not yet configured....");
7
8
    /* RTC Configuration */
9
    RTC_Configuration();
10
11
    printf("\r\n RTC configured....");
12
13
    /* Adjust time by values entered by the user on the hyperterminal */
14
    Time_Adjust();
15
16
    BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
17
  }
18
  else
19
  {
20
    /* Check if the Power On Reset flag is set */
21
    if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
22
    {
23
      printf("\r\n\n Power On Reset occurred....");
24
    }
25
    /* Check if the Pin Reset flag is set */
26
    else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
27
    {
28
      printf("\r\n\n External Reset occurred....");
29
    }
30
31
    printf("\r\n No need to configure RTC....");
32
    /* Wait for RTC registers synchronization */
33
    RTC_WaitForSynchro();
34
35
    /* Enable the RTC Second */
36
    RTC_ITConfig(RTC_IT_SEC, ENABLE);
37
    /* Wait until last write operation on RTC registers has finished */
38
    RTC_WaitForLastTask();
39
  }

und hier noch die dazu gehörigen Initialisierung (aus der gleichen 
Datei)
1
void RTC_Configuration(void)
2
{
3
  /* Enable PWR and BKP clocks */
4
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
5
6
  /* Allow access to BKP Domain */
7
  PWR_BackupAccessCmd(ENABLE);
8
9
  /* Reset Backup Domain */
10
  BKP_DeInit();
11
12
  /* Enable LSE */
13
  RCC_LSEConfig(RCC_LSE_ON);
14
  /* Wait till LSE is ready */
15
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
16
  {}
17
18
  /* Select LSE as RTC Clock Source */
19
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
20
21
  /* Enable RTC Clock */
22
  RCC_RTCCLKCmd(ENABLE);
23
24
  /* Wait for RTC registers synchronization */
25
  RTC_WaitForSynchro();
26
27
  /* Wait until last write operation on RTC registers has finished */
28
  RTC_WaitForLastTask();
29
30
  /* Enable the RTC Second */
31
  RTC_ITConfig(RTC_IT_SEC, ENABLE);
32
33
  /* Wait until last write operation on RTC registers has finished */
34
  RTC_WaitForLastTask();
35
36
  /* Set RTC prescaler: set RTC period to 1sec */
37
  RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
38
39
  /* Wait until last write operation on RTC registers has finished */
40
  RTC_WaitForLastTask();
41
}

Damit hat man einen Zähler, der alle Sekunde um 1 erhöht wird.
Was man jetzt damit macht, z.B. das ganze in ein Datum umrechnet, das 
bleibt jedem selbst überlassen.
Oder man muss halt schauen wie andere das gelöst haben. Das hat aber 
nicht mit der Funktion der RTC an sich zu tun.

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.