STM32F1: Clock und PortClock Settings

Gast #4967924
Ich bin gerade ein bissle am Rätselraten... und zwar initialisiere ich 
den µC mit folgenden Clocks:
1
 
2
void SystemInit(void)
3
{
4
    // 64Mhz using the HSI oscillator divided by 2 with 16x PLL, lowspeed I/O runs at 32Mhz
5
    WRITE_REG(RCC->CFGR,RCC_CFGR_PLLMULL16 + RCC_CFGR_PPRE1_DIV2);
6
    // Flash latency 2 wait states
7
    MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_1);
8
    // Enable PLL
9
    SET_BIT(RCC->CR, RCC_CR_PLLON);
10
    // Wait until PLL is ready
11
    while(!READ_BIT(RCC->CR, RCC_CR_PLLRDY)) {}
12
    // Select PLL as clock source
13
    MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
14
}

Den Portpin PORTA5 (LED) wie folgt:
1
int SetPinA5()
2
{
3
  //CFN5 Output Push/Pull
4
  *(volatile uint32_t *)0x40010800 &= ~(1<<22);
5
  
6
  //MODE5 Output 50Mhz (max 32Mhz) 
7
  *(volatile uint32_t *)0x40010800 |= (1<<20);
8
  *(volatile uint32_t *)0x40010800 |= (1<<21);
9

10
  return 0;
11
}


Nun zu folgendem Problem, wenn ich nun einen Pin toggeln lasse in meiner 
Main() komme ich nur auf 2Mhz, so ziemlich ganz genau - ganz egal was in 
GPIOA_CRL steht.
1
int main(void)
2
{
3
    SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);
4
    SetPinA5();
5

6
    while(1)
7
    {
8
      GPIOA->ODR ^= SPIN5;
9
    }
10
}


Setze ich den Takt weiter runter, Standard 8Mhz, macht sich dies 
natürlich auf dem Portpin bemerkbar und er toggelt mit 335khz.

Kann mir einer sagen warum dies so ist? Selbst meine Mega32U4 Pins haben 
da schneller getoggelt bei 16Mhz.
1. Du hast den prefetch-buffer für den Flash nicht aktiviert, d.h. bei 
zwei wait-states läuft dein Programm effektiv nur mit einem drittel des 
Systemtaktes.

2.
DraconiX schrieb:
> while(1)
>     {
>       GPIOA->ODR ^= SPIN5;
>     }

Schau dir doch einfach mal den generierten Assembler hierzu an. Die 
Veroderung von GPIO->ODR ist ein "read, modify, write" auf eine 
"volatile uint32_t. Da gehen schon paar Takte drauf und dazu kommt noch 
eine Instruktion wegen der Schleife. Per BSRR (Bit Set Reset Register) 
geht es schneller.

3.
DraconiX schrieb:
> //MODE5 Output 50Mhz (max 32Mhz)
>   *(volatile uint32_t *)0x40010800 |= (1<<20);

Die Angaben zum "Output Speed" beziehen sich eigentlich nur auf die 
Flankensteilheit (slew rate). Abgesehen davon ist
> *(volatile uint32_t *)0x40010800 |= (1<<20);
sehr unleserlich.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.