Forum: Mikrocontroller und Digitale Elektronik STM32 RTC mit ms basis


von Sky12 (Gast)


Lesenswert?

Hallo,
ich benutze die RTC von einen STM32F103C8T6. Das Beispiel arbeitet mit 
einer 1s basis, d.h. der Counter wird jede Sekunde um ein erhöht. Ich 
möchte den jetzt so umkonfigurieren das der Counter jede Millisekunde um 
ein erhöht wird. Ich habe versucht dieses zu erreichen, in dem Ich die 
Zeile RTC_SetPrescaler(32767); zu RTC_SetPrescaler(32); geändert haben.
Dieses scheint aber nicht das gewünschte Ergenis gebracht zu haben.
Ist der Wert 32 Falsch oder muß nocht etwas anderes geändert werden?
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 period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) 
38
  RTC_SetPrescaler(32767); 
39
    
40
  // Wait until last write operation on RTC registers has finished 
41
  RTC_WaitForLastTask();
42
}

von (prx) A. K. (prx)


Lesenswert?

Lass die RTC eine Uhr sein, die wie es sich gehört Sekunden zählt, und 
verwende den Systick-Timer für die Millisekunde. Dafür ist der da.

Spätestens bei Migration auf neuere STM32 wirst du nämlich sonst 
frustriert feststellen, dass deren RTC mit BCD-Darstellung arbeitet und 
dir das ganze Konzept verhagelt.

von Sky12 (Gast)


Lesenswert?

Das hatte Ich mir vorher auch schon überlegt,
wie müßte man den dann Systick-Timer konfigureieren, wie der 
Systick-Timer für Millisekunden konfiguriert werden muß ist klar,
aber wie mache Ich das dieser synchron zum RTC Counter läuft und auch 
nur von 0-999 zählt?
Ich muß in diesen Projekt einen Intervall mit ms Auflösung und Startzeit 
haben.
1
volatile u32 SystemClockMs = 0UL;
2
3
void SysTick_Configuration(void)
4
{
5
  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
6
  SysTick_Config(SystemCoreClock / 1000);
7
}
8
9
void SysTick_Handler(void)
10
{
11
  SystemClockMs++;
12
  if(SystemClockMs >= 1000UL)
13
  {
14
    SystemClockMs = 0UL;
15
  }
16
}

von (prx) A. K. (prx)


Lesenswert?

Sky12 schrieb:

> aber wie mache Ich das dieser synchron zum RTC Counter läuft

Vorzugsweise überhaupt nicht. Wozu ist das nötig? Man kann aus 
Milliksekunden auch Sekunden ableiten - ist weitaus einfacher als 
andersrum. Diese Sekunden sind dann eben nicht ganz synchron zu den 
Sekunden der RTC.

von Kalle (Gast)


Lesenswert?

A. K. schrieb:
>> aber wie mache Ich das dieser synchron zum RTC Counter läuft
>
> Vorzugsweise überhaupt nicht. Wozu ist das nötig? Man kann aus
> Milliksekunden auch Sekunden ableiten - ist weitaus einfacher als
> andersrum. Diese Sekunden sind dann eben nicht ganz synchron zu den
> Sekunden der RTC.

Bei der Wahl interne RTC und interner Timer ist es wirklich egal, da 
beide vom gleichen Oszillator geclockt werden und somit intern 
"synchron" laufen und nicht gegeneinander driften.
Bei einer internen/externen RTC musst du den internen Timer auf den 
internen/externen Sekunden-Interrupt synchronisieren, sprich bei 
Interrupt den internen Timer einschalten und dann immer schön 
nachziehen, wenn die RTC genauer ist und der Timer driften kann.


Grüße.

von (prx) A. K. (prx)


Lesenswert?

Welchen Sinn hat die Nutzung einer separaten RTC, die auf den Systemtakt 
läuft, wenn man per Systick einen 1ms Takt erzeugt? Wenn Strom oder 
Systemtakt weg, dann ist die auch weg.

von Kalle (Gast)


Lesenswert?

A. K. schrieb:
> Welchen Sinn hat die Nutzung einer separaten RTC, die auf den Systemtakt
> läuft, wenn man per Systick einen 1ms Takt erzeugt? Wenn Strom oder
> Systemtakt weg, dann ist die auch weg.

Z.B. Kalender und Alarm, wenn es nicht in Software sein soll. Übrigens 
kann die RTC komplett in der Backup-Domain laufen, also nicht unbedingt 
weg wenn keine VDD mehr da ist.


Grüße.

von (prx) A. K. (prx)


Lesenswert?

Kalle schrieb:

> Z.B. Kalender und Alarm, wenn es nicht in Software sein soll.

Welcher Kalender? Die RTC der STM32F10x ist ein simpler binärer 
Sekundenzähler. Da kalendert nix. Und der eine Vergleich für den 
Alarm...

> Übrigens
> kann die RTC komplett in der Backup-Domain laufen, also nicht unbedingt
> weg wenn keine VDD mehr da ist.

Doch weg, wenn wie hier vom Systakt versorgt, denn der gehört nicht zur 
Backup-Domain. Das meinte ich doch, dass die RTC primär mit separatem 
Quarz Sinn ergibt, nicht so sehr ohne.

von Sky12 (Gast)


Lesenswert?

Ich habe das Problem gefunden, weshalb der RTC_SetPrescaler(32); nicht 
funktionierte. Die Spannungsversorgung muß nach dem Programmieren einmal 
komplett getrennt werden, dann läuft der Counter in der neuen 
Geschwindigkeit.

Leider löse Ich damit das Problem nicht ganz zu meiner Zufriedenheit den 
Ich benötige leider auch ein Datum.

Variante 1.
RTC mit Sekunden Taktung und Systick
Problem hier ist, es kann nicht direkt mit den RTC Counter gearbeitet 
werden, d.h. nach erreicheren der Startzeit muß der Systick benutzt 
werden. Dabei entsteht eine Ungenauigkeit beim wechsel von RTC- zum 
Systick Counter, da der RTC-Counter dann nicht unbedingt 0ms hat.

Variante 2.
RTC mit Millisekunden Takten, voteil hierbei ist, das direkt mit den 
RTC-Counter gearbeitet werden kann. Nachteil ist leider das der 
RTC-Counter nur 32-Bit hat und zusammen mit Millisekunden dann kein 
Datum gespeichert werden kann.

Bei beiden Varianten muß gebastelt werden, ich hatte gadacht das ich mir 
genau das erspare, wenn ich einen Mikrocontroller mit Hardware RTC 
nehme.
Da habe ich wohl geirrt.

von Sky12 (Gast)


Lesenswert?

@A. K.
Die Bezeichnung Calender aus dem Application Note ist wirklich nicht 
besonders passend, aber ein Datum ist da drin, wenn im RTC-Counter die 
Sekunden z.B. ab den Jahr 2000 gespeichert werden, dann läßt sich daraus 
ein Datum berechnen.

Problematisch ist halt, das im 32-Bit RTC-Counter nicht genug Platz für 
Millisekunden vorhanden ist. Es könnten maximal ca. 50 Tage in ms 
gespeichert werden.

von John-eric K. (mockup)


Lesenswert?

Und wenn du zB. alle 60s durch die RTC einen Alarm auslöst und damit den 
Timer Synchronisierst?

Sprich Alarm Interrupt und Timer auf 0 setzen.

von Reinhard Kern (Gast)


Lesenswert?

Sky12 schrieb:
> Bei beiden Varianten muß gebastelt werden, ich hatte gadacht das ich mir
> genau das erspare, wenn ich einen Mikrocontroller mit Hardware RTC
> nehme.
> Da habe ich wohl geirrt.

Hallo,

geirrt hast du wohl was die sogenannte RTC angeht (nachgeprüft habe ich 
das nicht, aber so sind die Aussagen hier). Am besten ist dir geholfen 
mit einer kompletten RTC mit Sek, Min, usw bis zum Jahr, und mit 
Batterieversorgung. Da gibt es extern unzählige Versionen, eingebaut in 
Prozessoren dagegen kaum. So eine RTC liefert dir auch ausgeschaltet 
nach 2 Jahren noch korrekt Datum und Uhrzeit.

Allerdings haben die meisten keine ms, schon weil sie einen 32kHz-Quarz 
haben. Das ist im Prinzip kein Problem, wenn man wirklich ms mit Bezug 
zur Uhrzeit braucht (wofür eigentlich, so pünktlich muss keiner 
aufstehen). Man stellt einfach mit jedem Sekundentakt der RTC einen 
16bit-Wert auf 0 und zählt ihn mit dem 1 ms-Systemtimer hoch.

Gruss Reinhard

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.