Forum: Compiler & IDEs Bluepill STM32: welche Taktquelle?


von Jürgen (derkleinemuck)


Lesenswert?

Hallo
Kann ich in der Arduino IDE mit stm32duino Core ermitteln, welche Clock 
Source für HSC und LSC aktiv ist und welcher Takt? So ganz werde ich aus 
der KAL-Doku nicht schlau.

von Nemopuk (nemopuk)


Lesenswert?

Jürgen schrieb:
> Hallo
> Kann ich in der Arduino IDE mit stm32duino Core ermitteln, welche Clock
> Source für HSC und LSC aktiv ist und welcher Takt? So ganz werde ich aus
> der KAL-Doku nicht schlau.

Das kannst du aus den relevanten Registern auslesen. Die Register sind 
im Reference Manual beschrieben.

https://www.st.com/resource/en/reference_manual/cd00171190-stm32f101xx-stm32f102xx-stm32f103xx-stm32f105xx-and-stm32f107xx-advanced-arm-based-32Bit-mcus-stmicroelectronics.pdf

Allerdings wundert mich, dass du diese Einstellung "ermitteln" willst, 
denn sie wird doch von deinem eigenen Programm eingestellt. Du musst 
doch wissen was du eingestellt hast.

Was ist KAL?

: Bearbeitet durch User
von N. M. (mani)


Lesenswert?

Nemopuk schrieb:
> Allerdings wundert mich, dass du diese Einstellung "ermitteln" willst,
> denn sie wird doch von deinem eigenen Programm eingestellt.

Er hat vermutlich ein Arduino Projekt. Da wird das vermutlich für ihn 
übernommen und er will nun wissen was da eingestellt wird.

Jürgen schrieb:
> welche Clock Source für HSC und LSC aktiv ist und welcher Takt

Bluepill ist ein F103.
Also hätte ich vermutet da:
https://github.com/stm32duino/Arduino_Core_STM32/blob/main/system/STM32F1xx/system_stm32f1xx.c

von Alexander (alecxs)


Lesenswert?

Nemopuk schrieb:
> Was ist KAL?

Kernel Abstraction Layer?

N. M. schrieb:
> Bluepill ist ein F103.
> Also hätte ich vermutet da:

https://github.com/stm32duino/Arduino_Core_STM32/blob/main/variants/STM32F1xx/F103C4T_F103C6(T-U)/variant_BLUEPILL_F103C6.cpp#L116

PLLCLK 72 MHz, LSI 40 kHz

: Bearbeitet durch User
von Jürgen (derkleinemuck)


Lesenswert?

N. M. schrieb:
> Er hat vermutlich ein Arduino Projekt. Da wird das vermutlich für ihn
> übernommen und er will nun wissen was da eingestellt wird.
>

Genau. Und ich bin verwirrt, weil ich andere Ergebnisse bekomme.
1
RCC_ClkInitTypeDef RCC_ClkInitStruct;
2
HAL_result = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);  
3
Serial.println(RCC_ClkInitStruct.SYSCLKSource);

liefert "1", was wenn ich mich zu 
https://github.com/stm32duino/Arduino_Core_STM32/blob/main/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h 
durchhangle und weiter zu rc.h: RCC_CFGR_SW_HSE für den System Clock 
Multiplexer bedeutet. Damit sind aber keine 72MHz möglich, wie bei
HAL_RCC_GetSysClockFreq() oder F_CPU ausgegeben wird.

BTW: Die Bluepill nutzt einen STM32F103C8, was dann wohl 
https://github.com/stm32duino/Arduino_Core_STM32/blob/main/variants/STM32F1xx/F103C8T_F103CB(T-U)/variant_PILL_F103Cx.cpp 
bedeutet - aber gleiche Verwirrung

: Bearbeitet durch User
von Alexander (alecxs)


Lesenswert?

HAL_RCC_ClockConfig() liest nur die Felder die du gesetzt hast. Dein 
RCC_ClkInitStruct ist leer.

: Bearbeitet durch User
von Jürgen (derkleinemuck)


Lesenswert?

Aha.
Ich habe mit dem hier rumexperimentiert:
1
void setup() {
2
  Serial.begin(115200);
3
  Serial.print("F_CPU=");
4
  Serial.println(F_CPU);
5
  Serial.print("HAL_RCC_GetSysClockFreq()=");
6
  Serial.println(HAL_RCC_GetSysClockFreq());
7
  Serial.print("HAL_RCC_GetHCLKFreq=");
8
  Serial.println(HAL_RCC_GetHCLKFreq());
9
  Serial.print("HAL_RCC_GetPCLK1Freq=");
10
  Serial.println(HAL_RCC_GetPCLK1Freq());
11
  Serial.print("HAL_RCC_GetPCLK2Freq=");
12
  Serial.println(HAL_RCC_GetPCLK2Freq());
13
14
  HAL_StatusTypeDef HAL_result;            
15
16
  RCC_OscInitTypeDef RCC_OscInitStruct;
17
18
HAL_result = HAL_RCC_OscConfig(&RCC_OscInitStruct); 
19
Serial.println(RCC_OscInitStruct.HSEPredivValue);
20
Serial.println(RCC_OscInitStruct.HSICalibrationValue);  // 4
21
Serial.println(RCC_OscInitStruct.HSEState); // 0
22
Serial.println(RCC_OscInitStruct.HSIState); //0
23
Serial.println(RCC_OscInitStruct.LSEState);
24
Serial.println(RCC_OscInitStruct.LSIState);
25
Serial.println(RCC_OscInitStruct.OscillatorType); // 1 
26
27
Serial.println(RCC_OscInitStruct.PLL.PLLMUL);   // 134227185
28
Serial.println(RCC_OscInitStruct.PLL.PLLSource);  // 0  HSI clock divided by 2 selected as PLL entry clock source */
29
Serial.println(RCC_OscInitStruct.PLL.PLLState);  // 3
30
31
RCC_ClkInitTypeDef RCC_ClkInitStruct;
32
HAL_result = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);  // Catch the result
33
Serial.println(RCC_ClkInitStruct.SYSCLKSource);   // 1 < HSE selected as system clock */
34
35
}
Nicht schick aber es gibt folgende Ausgaben:
1
F_CPU=72000000
2
HAL_RCC_GetSysClockFreq()=72000000
3
HAL_RCC_GetHCLKFreq=72000000
4
HAL_RCC_GetPCLK1Freq=36000000
5
HAL_RCC_GetPCLK2Freq=72000000
6
4294967295
7
4
8
0
9
0
10
1073821696
11
134228100
12
1
13
134227205
14
0
15
3
16
1

Wie geht es denn richtig?

von Alexander (alecxs)


Lesenswert?

Garbage in garbage out. HAL_RCC_OscConfig() und HAL_RCC_ClockConfig() 
sind rein zum setzen gedacht.

von Jürgen (derkleinemuck)


Lesenswert?

Jürgen schrieb:
> Wie geht es denn richtig?

von Alexander (alecxs)


Lesenswert?

Es gibt die HAL_RCC_GetOscConfig() und HAL_RCC_GetClockConfig() 
Funktionen, aber auch die nützen nur etwas wenn die Werte über HAL 
gesetzt wurden.

Jürgen schrieb:
> 
https://github.com/stm32duino/Arduino_Core_STM32/blob/main/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h

hier findest Du die passenden Makros um Register direkt auszulesen, z.B. 
__HAL_RCC_GET_SYSCLK_SOURCE()

Beitrag #7996244 wurde vom Autor gelöscht.
von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Jürgen schrieb:

>...
> Wie geht es denn richtig?

Bare-metal fuer F1 und F3 etwa wie
1
/*!
2
 * \brief  Update SystemCoreClock according to Clock Register Values
3
 *
4
 * This function reads out the CPUs clock and PLL registers and assembles
5
 * the actual clock speed values into the SystemCoreClock local variable.
6
 */
7
static void SystemCoreClockUpdate(void)
8
{
9
    uint32_t tmp = 0, pllmult = 0, pllinput = 0;
10
#if defined(RCC_CFGR2_PREDIV1)
11
    uint32_t pllmuxinput;
12
    uint32_t prediv1;
13
    uint32_t prediv2, pll2multval;
14
    /* Use value * 2 to get integer value for multiplication factor 6.5 */
15
    const uint8_t pll1mult[16] = { 0,  0,  8, 10, 12, 14, 16, 18,  0,  0,  0,  0,  0, 13, 0 ,  0};
16
    const uint8_t pll2mult[16] = { 0,  0,  0,  0,  0,  0,  8,  9, 10, 11, 12, 13, 14,  0, 16, 20};
17
    uint32_t prediv1factor = 0;
18
#endif
19
20
    /* Get SYSCLK source -------------------------------------------------------*/
21
    tmp = RCC->CFGR & RCC_CFGR_SWS;
22
23
    switch (tmp)
24
    {
25
        case RCC_CFGR_SWS_HSI:  /* HSI used as system clock */
26
            sys_clock = HSI_VALUE;
27
            break;
28
        case RCC_CFGR_SWS_HSE:  /* HSE used as system clock */
29
            sys_clock = HSE_VALUE;
30
            break;
31
        case RCC_CFGR_SWS_PLL:  /* PLL used as system clock */
32
            /* Get PLL clock source and multiplication factor ----------------------*/
33
            pllmult = RCC->CFGR & RCC_CFGR_PLLMULL;
34
            pllmult = pllmult / RCC_CFGR_PLLMULL_0;
35
#if defined(RCC_CFGR2_PREDIV1)
36
            pllmult = pll1mult[pllmult];
37
#else
38
            pllmult = pllmult + 2;
39
            if (pllmult > 16)
40
                pllmult = 16;
41
#endif
42
            switch (RCC->CFGR & RCC_CFGR_PLLSRC) {
43
            case 0 :
44
                pllinput = HSI_VALUE / 2;
45
                break;
46
#if defined(RCC_CFGR2_PREDIV1)
47
            case RCC_CFGR_PLLSRC :
48
                pllmuxinput = HSE_VALUE;
49
                prediv1 =  RCC->CFGR2 &  RCC_CFGR2_PREDIV1;
50
                prediv1 =  prediv1 / RCC_CFGR2_PREDIV1_0;
51
                switch (RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC) {
52
                case RCC_CFGR2_PREDIV1SRC_PLL2:
53
                    prediv2 = (RCC->CFGR2 & RCC_CFGR2_PREDIV2) / RCC_CFGR2_PREDIV2_0;
54
                    pll2multval = (RCC->CFGR2 & RCC_CFGR2_PLL2MUL) / RCC_CFGR2_PLL2MUL_0;
55
                    pllmuxinput = (HSE_VALUE * pll2mult[pll2multval]) / (prediv2 + 1);
56
                    pllinput = pllmuxinput / (prediv1 + 1);
57
                    break;
58
                case RCC_CFGR2_PREDIV1SRC_HSE:
59
                    /* HSE oscillator clock selected as PREDIV1 clock entry */
60
                    pllinput = HSE_VALUE / (prediv1factor + 1);
61
                }
62
                pllinput = pllmuxinput / (2 *(prediv1 + 1));
63
                break;
64
#else
65
            case RCC_CFGR_PLLSRC :
66
                if (RCC_CFGR_PLLXTPRE_HSE_DIV2 == (RCC->CFGR & RCC_CFGR_PLLXTPRE)) {
67
                    pllinput = HSE_VALUE / 2;
68
                } else {
69
                    pllinput = HSE_VALUE;
70
                }
71
                break;
72
#endif
73
            }
74
            sys_clock = pllinput * pllmult ;
75
            break;
76
    }
77
 //   SetClockShift();
78
}

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.