Forum: Mikrocontroller und Digitale Elektronik STM32F103 - System Clock mit PLL erhöhen


von Max M. (maxmicr)


Angehängte Dateien:

Lesenswert?

Ich würde gerne den System Takt mit der integrierten PLL auf Basis des 
HSI erhöhen.
Dafür benutze ich aktuell folgenden Code:
1
int main()
2
{
3
  /* Configure Clock */
4
  FLASH->ACR |= FLASH_ACR_LATENCY_1;
5
  RCC->CR &=~RCC_CR_PLLON;
6
  RCC->CFGR |= RCC_CFGR_PLLMULL_2;
7
  RCC->CR |= RCC_CR_PLLON;
8
  RCC->CFGR |= RCC_CFGR_SW_1;
9
  
10
  /* Set PIN A8 as MCO Output */ 
11
  RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
12
  GPIOA->CRH = GPIO_CRH_CNF8_1;
13
  GPIOA->CRH |= GPIO_CRH_MODE8_1 | GPIO_CRH_MODE8_0;
14
  RCC->CFGR |= RCC_CFGR_MCO_2;
15
16
  while(1){
17
    asm volatile ("nop");
18
  }
19
}

Um das Ganze zu testen, gebe ich den System Clock auf PA8 aus, dieser 
gibt allerdings nur 8MHz aus anstatt der zu erwartenden 48MHz (PLL input 
clock x6).

Beim Debuggen ist mir aufgefallen, dass PLLON immer 1 ist, selbst 
nachdem ich versuche, die PLL zu disablen - warum ist das so?

Außerdem enthält RCC_CFGR für mich nicht nachvollziehbare Werte, ist 
doch der Reset Value = 0.

von Max M. (maxmicr)


Angehängte Dateien:

Lesenswert?

Das ist mein aktueller Versuch, das Problem war, dass standardmäßig PLL 
als System Clock verwendet wird und man die PLL-Werte so nicht verändern 
kann, dafür muss man die erst deaktivieren. Drauf gebracht hat mich 
dieser Artikel: 
https://stm32f4-discovery.net/2015/05/library-59-change-pll-settings-while-stm32f4xx-is-running/

Allerdings hab ich nun seltsame Effekte.
1
void init_clock() {
2
  //FLASH->ACR |= FLASH_ACR_LATENCY_1;
3
  
4
  RCC->CR |= RCC_CR_HSION;
5
  while(!(RCC->CR & RCC_CR_HSIRDY))
6
    asm volatile ("nop");
7
  RCC->CFGR &=~ (RCC_CFGR_SW_0 | RCC_CFGR_SW_1);
8
  RCC->CR &=~RCC_CR_PLLON;
9
  while(RCC->CR & RCC_CR_PLLRDY)
10
    asm volatile ("nop");
11
  
12
  RCC->CFGR &=~ RCC_CFGR_PLLSRC;
13
  RCC->CFGR &=~(RCC_CFGR_PLLMULL_3 | RCC_CFGR_PLLMULL_2 | RCC_CFGR_PLLMULL_1 | RCC_CFGR_PLLMULL_0);
14
  RCC->CR |= RCC_CR_PLLON;
15
  
16
  while(!(RCC->CR & RCC_CR_PLLRDY))
17
    asm volatile ("nop");
18
  
19
  RCC->CFGR |= RCC_CFGR_SW_1;
20
  
21
  while(!(RCC->CFGR & RCC_CFGR_SW_1))
22
    asm volatile ("nop");
23
}

Anbei die Registerwerte nach dem Durchlaufen der Funktion.

Nach der Einstellung von PLLMULL ergibt das "PLL input clock x 2", mit 
8MHz /2 = 4MHz als Eingangstakt messe ich auch korrekte 8MHz.

Wenn ich nun
1
  RCC->CFGR |= RCC_CFGR_PLLMULL_0;

hinzufüge, erhalte ich auch korrekte 12MHz. Sobald ich aber die oben 
genannte Zeile auf
1
  RCC->CFGR |= RCC_CFGR_PLLMULL_1;

ändere (hier wären 16MHz zu erwarten), erhalte ich bei der Logic 
Analyzer Messung ungleiche Taktlängen (siehe Anhang).

Woher kommt das?

Edit:

Sobald ich die WaitStates für den Flash erhöhe 
(http://www.st.com/content/ccc/resource/technical/document/reference_manual/59/b9/ba/7f/11/af/43/d5/CD00171190.pdf/files/CD00171190.pdf/jcr:content/translations/en.CD00171190.pdf 
S. 57) ergibt:
1
  FLASH->ACR |= FLASH_ACR_LATENCY_1;
2
  ...
3
  RCC->CFGR |= RCC_CFGR_PLLMULL_1;

8MHz und
1
  FLASH->ACR |= FLASH_ACR_LATENCY_1;
2
  ...
3
  RCC->CFGR |= RCC_CFGR_PLLMULL_1 | RCC_CFGR_PLLMULL_0;

ergibt 4MHz (auch wieder mit unsauberen Taktlängen). Wie kann das denn 
sein?

: Bearbeitet durch User
von John Doe (Gast)


Lesenswert?

Max M. schrieb:
> Drauf gebracht hat mich
> dieser Artikel:
> https://stm32f4-discovery.net/2015/05/library-59-c...


Wie wärs damit, einfach mal das Referenzmanual richtig zu lesen? Da 
steht sowas schliesslich drin.
Aber ist heutzutage wohl out, google wird es schon richten...


> ändere (hier wären 16MHz zu erwarten), erhalte ich bei der Logic
> Analyzer Messung ungleiche Taktlängen (siehe Anhang).
>
> Woher kommt das?


Wie ist die Abtastrate Deines Analyzers?

von Max M. (maxmicr)


Lesenswert?

John Doe schrieb:
> Wie ist die Abtastrate Deines Analyzers?

24 MS/s

von John Doe (Gast)


Lesenswert?

Max M. schrieb:
> John Doe schrieb:
>> Wie ist die Abtastrate Deines Analyzers?
>
> 24 MS/s


Da ist Dein Problem. Das reicht nicht, daher das fehlerhaft Bild. Damit 
Du bei 16MHz etwas vernünftig erkennst, sollten es mindestens 50MHz, 
besser mehr sein.

Dein Taktsignal ist also völlig in Ordnung und nicht unregelmäßig.

von Carl D. (jcw2)


Lesenswert?

Max M. schrieb:
> John Doe schrieb:
>> Wie ist die Abtastrate Deines Analyzers?
>
> 24 MS/s

Shannon kennst du?

Theoretisch kannst du damit 12MHz erkennen.
Praktisch würde ich zum Messen 5..10-fach übertakten.

von Max M. (maxmicr)


Lesenswert?

John Doe schrieb:
> Dein Taktsignal ist also völlig in Ordnung und nicht unregelmäßig.

Okay, anderer Versuch. Ich hab einen Timer Interrupt mit Reload-Value 
0xFFFF.

Ich messe an einem GPIO 487.3Hz mit diesem Setup:
1
  RCC->CFGR |= RCC_CFGR_PLLMULL_3 | RCC_CFGR_PLLMULL_2 | RCC_CFGR_PLLMULL_1 | RCC_CFGR_PLLMULL_0;

also Input Clock x 16 = 64MHz

Sofern ich richtig rechne sind 487.3Hz * 2^16 ~ 32MHz. Frisst das 
löschen des Pending-Bits die anderen 32MHz "auf"?
1
void TIM2_IRQHandler (void) {
2
    TIM2->SR &=~TIM_SR_UIF;
3
    GPIOC->ODR ^= GPIO_ODR_ODR13;
4
}

Prescaler vom Timer ist 0.

: Bearbeitet durch User
von Thomas E. (picalic)


Lesenswert?

Max M. schrieb:
> Ich messe an einem GPIO 487.3Hz mit diesem Setup:

Aber zu einer Schwingung Deines gemessenen Rechteck-Signals gehören zwei 
Pegelwechsel, also zwei Interrupts, die den Pin togglen. Deine ISR wird 
also mit der doppelten gemessenen Frequenz aufgerufen!

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.