Forum: Mikrocontroller und Digitale Elektronik stm32: RTC 20% zu schnell


von Nicolay M. (imperator_maximus)


Lesenswert?

Hallo,
ich versuche eine Uhr auf diesem Board (STM32F030C8) zum Laufen zu 
bringen: https://github.com/bigtreetech/BIGTREETECH-S42B-V1.0
Es ist ein Closed-Loop Stepper mit OLED Display. Die perfekte 
Hardware+Sensor für eine sehr große Uhr mit Zeiger!
Nun ist der RTC 20% zu schnell. Also nach nur 10 Sekunden haben ich 12 
Sekunden.
Diese ganze STM-Welt war vollkommen neu für mich und nun nach einigen 
Tagen bin ich soweit einigermaßen drin.
Ich habe den bestehenden Firmware-Code erweitert und ansonsten mit 
MXCube LL und HAL erzeugt. Ich möchte den LL-Weg dabei schon gehen. Ich 
habe es auch probiert mit einem Interrupt zu simulieren und kam dabei 
auf 10% Abweichung.

Code:
1
void MX_RTC_Init(void)
2
{
3
  LL_RTC_InitTypeDef RTC_InitStruct = {0};
4
  /* Peripheral clock enable */
5
  LL_RCC_EnableRTC();
6
  /* USER CODE BEGIN RTC_Init 1 */
7
  /* USER CODE END RTC_Init 1 */
8
  /** Initialize RTC and set the Time and Date
9
  */
10
  RTC_InitStruct.HourFormat = LL_RTC_HOURFORMAT_24HOUR;
11
  RTC_InitStruct.AsynchPrescaler = 127;
12
  RTC_InitStruct.SynchPrescaler = 255;
13
  LL_RTC_Init(RTC, &RTC_InitStruct);
14
  LL_RTC_SetAsynchPrescaler(RTC, 127);
15
  LL_RTC_SetSynchPrescaler(RTC, 255);
16
  /* USER CODE BEGIN RTC_Init 2 */
17
  LL_RTC_DisableWriteProtection(RTC);
18
  LL_RTC_TIME_SetHour(RTC,__LL_RTC_CONVERT_BIN2BCD (18));
19
    LL_RTC_TIME_SetMinute(RTC,__LL_RTC_CONVERT_BIN2BCD(30));
20
    LL_RTC_TIME_SetSecond(RTC,__LL_RTC_CONVERT_BIN2BCD (0));
21
  LL_RTC_EnableWriteProtection(RTC);
22
  /* USER CODE END RTC_Init 2 */
23
}

Die Config aus der Firmware. MXCube erzeugt fast den selben Code, nur 
mit 16MHZ.
1
void SystemClock_Config(void)
2
{
3
  LL_FLASH_SetLatency(LL_FLASH_LATENCY_1); 
4
  if(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_1)
5
  {
6
    Error_Handler();  
7
  }
8
  LL_RCC_HSI_Enable();
9
  while(LL_RCC_HSI_IsReady() != 1)
10
  {}
11
  LL_RCC_HSI_SetCalibTrimming(16);
12
  LL_RCC_LSI_Enable();
13
  while(LL_RCC_LSI_IsReady() != 1)
14
  {}
15
  LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, LL_RCC_PLL_MUL_12);
16
  LL_RCC_PLL_Enable();
17
  while(LL_RCC_PLL_IsReady() != 1)
18
  {}
19
  LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
20
  LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
21
  LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);   
22
  while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
23
  {}
24
  LL_Init1msTick(48000000);
25
  LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);
26
  LL_SetSystemCoreClock(48000000);
27
  LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK1);
28
  NVIC_SetPriority(SysTick_IRQn, 0);
29
}
Die Sekunde lese ich so:
1
        second=LL_RTC_TIME_GetSecond(RTC);
2
        second=__LL_RTC_CONVERT_BCD2BIN(second);

Ich habe die Frage schon auf Github dort im Repo gestellt und auch in 
eine STM32-Facebook Gruppe. Auf letztere habe ich die Antwort die Frage 
bekommen, ob man damit auch ein Handy bauen kann lol
Ich kenne noch von früher Assembler-Programmierung von einigen 
Prozessoren, aber dass ist schon sehr lange her.
Dass der interne RTC nie 100% genau sein wird, ist mir schon klar. Aber 
so eine krasse Abweichung macht den vollkommen unbrauchbar. Aber ich 
denke dass ich da so richtig was falsch habe. Ich will schon zusätzlich 
einmal pro Stunde die Zeit über ein externes ESP 01 Modul an UART+NTP 
abgleichen. Es wäre aber schön, wenn die Zeit weiter läuft dazwischen - 
auch wenn mal kein Internet da ist.

Vielen Dank!

: Bearbeitet durch User
von Schorsch X. (bastelschorsch)


Lesenswert?

Irgendwie finde ich den Schaltplan nicht. Aber auf den ersten Blick hab 
ich auch keinen Uhrenquarz gefunden. Kann das sein ?

von Nicolay M. (imperator_maximus)


Lesenswert?

Ich habe auch den Schaltplan nicht gefunden. Aber wenn ich LSI nehme, 
dann brauche ich keinen externen Quartz denke ich. Das wäre dann so max 
3% ungenau was ich so lese, aber damit könnte ich leben.

von Karl (Gast)


Lesenswert?

Läuft der lsi nicht mit 40 kHz?

von Nop (Gast)


Lesenswert?

Nicolay M. schrieb:

> Nun ist der RTC 20% zu schnell.

Was erwartest Du denn? Ich sehe da im Initcode immer nur HSI und LSI, 
also die internen RC-Oszillatoren. Der HSI sollte auf 1% genau gehen bei 
25°C, was für vieles ausreicht (außer USB-Verbindungen), aber der LSI 
ist nur ein Schätzeisen. Für das, was Du willst, brauchst Du Quarze, und 
das sind externe Oszillatoren.

Schau mal ins Datasheet Deines Chips: 
https://www.st.com/en/microcontrollers-microprocessors/stm32f030c8.html

Da steht auf Seite 56 ganz unten, daß der LSI typisch 40kHz hat, aber 
zwischen 30 und 50 kHz liegen kann. Für irgendwas mit RTC ist der völlig 
unbrauchbar.

von Frank K. (fchk)


Lesenswert?

Nicolay M. schrieb:
> Ich habe auch den Schaltplan nicht gefunden. Aber wenn ich LSI nehme,
> dann brauche ich keinen externen Quartz denke ich. Das wäre dann so max
> 3% ungenau was ich so lese, aber damit könnte ich leben.

https://www.st.com/en/microcontrollers-microprocessors/stm32f030c8.html

"
Clock management

    4 to 32 MHz crystal oscillator
    32 kHz oscillator for RTC with calibration
    Internal 8 MHz RC with x6 PLL option
    Internal 40 kHz RC oscillator
"

40 statt 32kHz könnten Deine Beobachtungen erklären.

fchk

von Rolf M. (rmagnus)


Lesenswert?

Nicolay M. schrieb:
> Das wäre dann so max 3% ungenau was ich so lese, aber damit könnte ich leben.

3% sind für eine Uhr extrem ungenau. Das entspricht einer Abweichung von 
fast einer Dreiviertelstunde pro Tag.

von Karl (Gast)


Lesenswert?

Edit: ja, tut er. Früher hatte man rtfm gesagt, aber das schickt sich 
nicht mehr. Daher lege ich dir nahe, die Konfiguration der prescaler zu 
überdenken. 250 und 160 sind z.b.  schöne Faktoren (nicht Werte für die 
Register)

von Nicolay M. (imperator_maximus)


Lesenswert?

Rolf M. schrieb:
> Nicolay M. schrieb:
>> Das wäre dann so max 3% ungenau was ich so lese, aber damit könnte ich leben.
>
> 3% sind für eine Uhr extrem ungenau. Das entspricht einer Abweichung von
> fast einer Dreiviertelstunde pro Tag.
das soll auch der maximaler Wert sein, bei extremen Temperaturen, wie 
ich gelesen habe und  ich möchte einmal pro Stunde mit NTP abgleichen - 
hatte ich oben geschrieben.

von Nicolay M. (imperator_maximus)


Lesenswert?

Frank K. schrieb:

>
> 40 statt 32kHz könnten Deine Beobachtungen erklären.
>
> fchk

ja genau, aber  im CubeMX werden auch 40 kHz angezeigt und dieser 
erzeugt diese Werte (z.B. Prescaler-Werte 127/255). Wie stelle ich das 
ein?

von Nicolay M. (imperator_maximus)


Lesenswert?

Karl schrieb:
> Edit: ja, tut er. Früher hatte man rtfm gesagt, aber das schickt sich
> nicht mehr. Daher lege ich dir nahe, die Konfiguration der prescaler zu
> überdenken. 250 und 160 sind z.b.  schöne Faktoren (nicht Werte für die
> Register)

Du meinst die Async und Sync Prescaler? Ich muss zugeben, dass ich das 
Konzept dahinter nicht verstanden habe. Allerdings ist für den Async nur 
max. 127 zulässig.

von pegel (Gast)


Lesenswert?

RefMan RM0360 Kapitel 21.4.3 gibt es die Formeln.

Nicolay M. schrieb:
> Wie stelle ich das ein?

Genau dort. Die Werte minus 1 beachten.

von Nicolay M. (imperator_maximus)


Lesenswert?

pegel schrieb:
> RefMan RM0360 Kapitel 21.4.3 gibt es die Formeln.
>
> Nicolay M. schrieb:
>> Wie stelle ich das ein?
>
> Genau dort. Die Werte minus 1 beachten.

cool ich habe mal 99 (Async darf max 127 sein) und 399 eingestellt und 
das kommt jetzt gut hin (kurzer Test mit 30 Sekunden - da waren es 30 
Sekunden). Super - Danke!

von Nop (Gast)


Lesenswert?

Nicolay M. schrieb:

> das soll auch der maximaler Wert sein

Ist er aber nicht. 40kHz ist soll, kann aber 30-50kHz sein laut 
Datenblatt. Das sind -25% ... +25%.

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.