stm32: RTC 20% zu schnell

OP #6612430
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!
Gast #6612513
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.
#6612514
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
Gast #6612518
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)
OP #6612758
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.
OP #6612770
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren