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!