Forum: Mikrocontroller und Digitale Elektronik STM32F413 externer Oszi ---> HSE Clock Problem


von Heint (Gast)


Lesenswert?

Hallo zusammen,

ich versuche seit geraumer Zeit den internen 16 MHz RC Oszi durch ein 
externes 8 MHz Quarz zu ersetzen.

Leider kommt das Programm nicht aus der While Schleife und geht in den 
HAL_TIMEOUT.

•
1
    /* Enable the main PLL. */
2
        __HAL_RCC_PLL_ENABLE();
3
4
        /* Get Start Tick*/
5
        tickstart = HAL_GetTick();
6
        
7
        /* Wait till PLL is ready */  
8
        
9
        while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
10
        {
11
          if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
12
          {
13
            return HAL_TIMEOUT;
14
          } 
15
        }

Meine Config sieht so aus.
Der Quarz wurde durchgemessen und ist o.k. Vielleicht habe ich vergessen 
wieder irgendetwas zu aktivieren? Vielleicht hat ja jmd eine Idee ?
Hier meine zugehörige Config. Über etwas Hilfe würde ich mich sehr 
freuen.

•
1
static void SystemClock_Config(void)
2
{
3
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
4
  RCC_OscInitTypeDef RCC_OscInitStruct;
5
6
7
  __PWR_CLK_ENABLE();
8
  
9
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
10
  
11
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
12
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
13
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
14
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
15
  RCC_OscInitStruct.PLL.PLLM = 8;
16
  RCC_OscInitStruct.PLL.PLLN = 200;
17
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
18
  RCC_OscInitStruct.PLL.PLLQ = 2;
19
  if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
20
  {
21
    Error_Handler();
22
  }
23
24
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
25
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
26
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
27
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;  
28
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;  
29
  if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
30
  {
31
    Error_Handler();
32
  }
33
}

von pegel (Gast)


Lesenswert?

Du kannst den HSE direkt an den MCO Ausgang umleiten und messen.

Wenn du deine .ioc Datei anhängst, können wir nachsehen was los ist.

von STM Apprentice (Gast)


Lesenswert?

Heint schrieb:
> Der Quarz wurde durchgemessen und ist o.k.

Es muss nicht der Fehler sein, aber kann:

Hat dein Quarz zwei externe Last-Lapazitäten gegen Masse?
Wenn nicht dann schwingt "es" manchmal nicht.

von honk (Gast)


Lesenswert?

Du benutzt den HAL-Mist, daher kann ich zu Deinem Problem nichts 
schreiben.
Aber ich empfehle dringend, das Reference Manual mal zumindest zu 
überfliegen - auch wenn das heutzutage nicht mehr en vogue ist.
Da stehen nämlich überaschenderweise nützliche Dinge drin.
Z.B.:
PLLM[5:0] -> Caution:
The software has to set these bits correctly to ensure that the VCO 
input frequency ranges from 1 to 2 MHz. It is recommended to select a 
frequency of 2 MHz to limit PLL jitter.

Pass also besser Deine Teilungsfaktoren entsprechend an.

von pegel (Gast)


Lesenswert?

Ich habe mir deinen original Quelltext angesehen und in CubeMx 
nachgestellt.

Er weist mich darauf hin, dass PLLQ <= 75MHz sein muss.
Bei dir sind es 200/2 = 100MHz.

RCC_OscInitStruct.PLL.PLLQ = 3;

ergibt 66,666 MHz und würde passen.

von Gastino G. (gastino)


Lesenswert?

STCubeMX ist eine gute Empfehlung, um wenigstens mal die ganzen Uhren 
richtig einzustellen. Das ist schon recht kompliziert, mit dem 
unübersichtlichen Bild der Referenz-Doku sowieso.

Hier mal meine Konfiguration, ebenfalls 8 MHz HSE und intern 100 MHz 
SysClk, und Peripherie 100 MHz, abgesehen von APB1 Peripherie (50 MHz):
1
//RCC_CR
2
#define SYS_CLK_PLLI2SON  0u  //!< PLLI2S enable
3
#define SYS_CLK_PLLON    1u  //!< main PLL enable
4
#define SYS_CLK_CSSON    1u  //!< clock security system enable
5
#define SYS_CLK_HSEBYP    1u  //!< HSE clock bypass
6
#define SYS_CLK_HSEON     1u  //!< HSE clock enable
7
#define SYS_CLK_HSION     0u  //!< HSI clock enable
8
9
//PLL config
10
#define SYS_CLK_PLLQ    4u  //!< PLL division factor for USB OTG FS, and SDIO clocks (PLLQ)
11
#define SYS_CLK_PLLSRC    1u  //!< PLL source (PLLSRC)
12
#define SYS_CLK_PLLP    0u  //!< PLL multiplication factor for main system clock (PLLP)
13
#define SYS_CLK_PLLN    100u  //!< PLL multiplication factor for VCO (PLLN)
14
#define SYS_CLK_PLLM    4u  //!< division factor for the main PLL (PLLM)
15
16
//PLLI2S config
17
#define SYS_CLK_PLLI2SR    2u  //!< PLLI2S division factor for I2S clocks (PLLI2SR)
18
#define SYS_CLK_PLLI2SN    192u  //!< PLLI2S multiplication factor for VCO (PLLI2SN)
19
#define SYS_CLK_PLLI2SM     16u  //!< PLL prescaler for audio (PLLI2S) clock (PLLI2SM)
20
21
//RCC_CFGR
22
#define SYS_CLK_MCO2PRE     6u  //!< MCO2 prescaler (MCO2PRE)
23
#define SYS_CLK_MCO1PRE     6u  //!< MCO1 prescaler (MCO1PRE)
24
#define SYS_CLK_MCO1     3u  //!< MCO1 source (MCO1)
25
#define SYS_CLK_RTCPRE     8u  //!< RTC prescaler (RTCPRE)
26
#define SYS_CLK_APB2     0u  //!< APB high speed prescaler (APB2)
27
#define SYS_CLK_APB1     4u  //!< APB low speed prescaler (APB1)
28
#define SYS_CLK_HPRE     0u  //!< AHB prescaler (HPRE)
29
#define SYS_CLK_SW     2u  //!< system clock switch (SW)

Sind alles die Registerwerte, den HAL benutze ich nicht.

von Neverever (Gast)


Lesenswert?

pegel schrieb:
> Ich habe mir deinen original Quelltext angesehen und in CubeMx
> nachgestellt.
>
> Er weist mich darauf hin, dass PLLQ <= 75MHz sein muss.
> Bei dir sind es 200/2 = 100MHz.
>
> RCC_OscInitStruct.PLL.PLLQ = 3;
>
> ergibt 66,666 MHz und würde passen.


Ach, und wie passt das mit dem Reference Manual zusammen?

Caution:
The USB OTG FS requires a 48 MHz clock to work correctly. The SDIO and 
the random number generator need a frequency lower than or equal to 48 
MHz to work correctly.

Wie oben schon angemerkt wurde: RM lesen!

von pegel (Gast)


Lesenswert?

Bis jetzt war noch nicht die Rede davon, ob er etwas davon benutzen 
möchte.

von Heint (Gast)


Lesenswert?

Besten Dank für eure Antworten.

Ich habe die HAL rausgeworfen, kriege das aber dennoch nicht zum laufen.
Vorher habe ich übrigens noch Port H aktiviert, da der Oszilator dort ja 
angeschlossen ist.
AHB1_GPIOH |= 0x00000080U;


•
1
static void SystemClock_Config(void)
2
{
3
  RCC_PLLCFGR |= 0x22403208;
4
  //RCC_PLLCFGR |= 0010 0010 0100 0000 0011 0010 0000 1000; 
5
  //Bit 31     0          Reserved
6
  //Bit 30:28  010        PLLR Division Factor = 2
7
  //Bit 27:24  0010       PLLQ Division Factor = 2
8
  //Bit 23     0          Reserved 
9
  //Bit 22     1          HSE oscillator clock selected as PLL and PLLI2S clock entry
10
  //Bit 21:18  0000       Reserved
11
  //Bit 17:16  00         PLLP Division Factor = 2
12
  //Bit 15     0          Reserved
13
  //Bit 14:6   011001000  PLL PLLN Multiplication Faktor = 200
14
  //Bit 5:0    001000     PLL PLLM Division Factor = 8
15
16
  RCC_CFGR |= 0x36481012;
17
  //RCC_CFGR    |=  0011 0110 0100 1000 0001 0000 0001 0010;   
18
  //Bit 31:30   00      MCO2 System Clock selected
19
  //Bit 29:27   110     MCO2 Prescaler = 4
20
  //Bit 26:24   110     MCO1 Prescaler = 4 
21
  //Bit 23      0       Reserved
22
  //Bit 22:21   10      MCO1 HSE Oszilator Clock selcted
23
  //Bit 20:16   01000   HSE division for RTC Clock = 8
24
  //Bit 15:13   000     APB2 Prescaler = 1
25
  //Bit 12:10   100     APB1 Prescaler = 2
26
  //Bit 9:8     00      Reserved
27
  //Bit 7:4     0001    AHB Prescaler = 1
28
  //Bit 3:2     00      System clock switch status (set an cleared by hardware)
29
  //Bit 1:0     10      PLL selected as system clock   
30
31
  RCC_PLLI2SCFGR |= 0x22003010;
32
  //RCC_PLLI2SCFGR |= 0010 0010 0000 0000 0011 0000 0001 0000;
33
  //Bit 0:5     010000      PLLI2SM Division factor for the main PLL input clock = 16 
34
  //Bit 14:6    011000000  PLLI2SN Multiplication factor = 192
35
  //Bit 21:15   0000000    Reserved
36
  //Bit 22      0          PLLI2S entry clock source HSE or HSI (depending on PLLSRC of PLLCFGR)
37
  //Bit 23      0          Reserved
38
  //Bit 27:24   0010       PLLI2SQ = 2
39
  //Bit 30:28   010        PLLI2SR = 2
40
  //Bit 31      0          Reserved  
41
  
42
  RCC_CR |= 0x05090000; 
43
  //RCC_CR      |= 0000 0101 0000 1001 0000 0000 0000 0000;
44
  //Bit 31:28  0000       Reserved
45
  //Bit 26     01         PLLI2SON = 1 enable
46
  //Bit 25     0          PLLReady (set by hardware)
47
  //Bit 24     1          PLLON Main PLL enable = 1
48
  //Bit 23:20  0000       Reserved
49
  //Bit 19     1          CSSON clock security system = 1 (enable)
50
  //Bit 18     0          HSEBYP HSE clock Bypas = 0 (HSE oscillator not bypassed)
51
  //Bit 17     0          HSERDY HSE clock ready flag. Set by hardware to indicate that the HSE oscillator ist stable
52
  //Bit 16     1          HSEON HSE clock enable = 1 (HSE oscillator on)
53
  //Bit 15:8   00000000   Internal high speed clock calibration
54
  //Bit 7:3    00000      Internal high speed clock trimming
55
  //Bit 2      0          Reserved
56
  //Bit 1      0          HSIRDY set by hardware (0=HSI not ready ; 1=HSI Ready)
57
  //Bit 0      0          HSION Set by hardware in case of failure of HSE oscilator etc....}

von Heint (Gast)


Angehängte Dateien:

Lesenswert?

Das HSE Bit wird zwar gesetzt, aber im nächsten Schritt wieder gelöscht. 
Dann fliegt das Programm in den NMI_Handler.

Sofern das Quarz nicht stabil läuft, sollte nicht einfach der HSI 
verwendet werden. Ich verstehe nicht, warum der NMI_Handler aufgerufen 
wird.

von Heint (Gast)


Lesenswert?

Gastino G. schrieb:
> //PLL config
> #define SYS_CLK_PLLQ    4u  //!< PLL division factor for USB OTG FS, and
> SDIO clocks (PLLQ)
> #define SYS_CLK_PLLSRC    1u  //!< PLL source (PLLSRC)
> #define SYS_CLK_PLLP    0u  //!< PLL multiplication factor for main
> system clock (PLLP)
> #define SYS_CLK_PLLN    100u  //!< PLL multiplication factor for VCO
> (PLLN)
> #define SYS_CLK_PLLM    4u  //!< division factor for the main PLL (PLLM)

Mal vom obigen Problem abgesehen, kann das nicht ganz stimmen:

Wenn HSE = 8MHz, dann ist SYSCLK = 8 MHz / PLLM * PLLN / PLLP  =
                          SYCLK  = 8 MHz / 4    * 100  / 1     = 200 MHz

Müssen beim Schreiben in die Register irgendwelche delay-Zeiten o.ä 
eingehalten werden?

von Christopher J. (christopher_j23)


Lesenswert?

Heint schrieb:
> Ich verstehe nicht, warum der NMI_Handler aufgerufen
> wird.

Wenn du keine Fault-Handler implementiert hast, dann landest du eben im 
Default-Handler und das sieht dann so aus als wärest du im NMI gelandet, 
weil der NMI eben auch durch den Default-Handler ersetzt wird.


Heint schrieb:
> RCC_PLLCFGR |= 0x22403208;

Bitte keine magic numbers und lass mal den kompletten Code sehen

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.