Vor nicht allzu langer Zeit hat STM die nach Leistungsstandards von Mikrocontrollern sehr leistungsstarke STM32H7-Kristalllinie auf den Markt gebracht. Was mich zu ihr hingezogen hat:
- erhöhte Kernfrequenz auf 400 MHz
- RAM erhöht, bis zu 1 MB
- 16 Bit ADC
- Pin-zu-Pin-Kompatibilität mit der F7-Serie
Ich dachte perfekt, ich habe den STM32H743IIT6-Kristall anstelle des STM32F746IGT6 auf die Platine gelötet und ein neues Projekt in SW4STM32 gestartet.
Es ist zweckmäßig, die Registerkarte Taktkonfiguration des STM32CubeMX-Programms zu verwenden, um die Koeffizienten der Teiler und Faktoren des Taktsystems des Mikrocontrollers zu berechnen.
Uhreinstellungen:
- externer Quarz - 8 MHz
- Frequenzquelle für PLL1 - externer Quarz (HSE)
- Teiler für PLL1 - 4 (DIVM1)
- Multiplikator PLL1 - 400 (DIVN1)
- Ausgangsteiler - 2 (DIVP1, DIVQ1, DIVR1)
Dementsprechend beträgt die Kernfrequenz (SYSCLK) 400 MHz.

Neben dem STM32CubeMX gibt es auch das Firmware-Paket STM32CubeH7, das eine Vielzahl von Beispielen für die Arbeit mit Peripheriegeräten für den STM32H7 enthält. Von ihm wurde die Initialisierungssequenz des Taktsystems des Mikrocontrollers übernommen.
Informationen und Kommentare stammen aus folgenden Quellen:
- SystemClock_Config aus dem STM32CubeH7-Firmware-Paket
- Referenzhandbuch STM32H743 / 753 und STM32H750 erweiterte ARM-basierte 32-Bit-MCUs
- - Datenblatt STM32H743xI
Also fangen wir an.
1. Externen Quarz einschalten und auf die Bereitschaft warten.
// Enable HSE RCC->CR |= RCC_CR_HSEON; // Wait till HSE is ready while((RCC->CR & RCC_CR_HSERDY) == 0);
2. Angabe der Frequenzquelle für PLL1 - externer Quarz.
3. Der Divisorwert wird auf 4 gesetzt.
//PLLM = 4 RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1_5; //0 RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1_4; //0 RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1_3; //0 RCC -> PLLCKSELR |= RCC_PLLCKSELR_DIVM1_2; //1 RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1_1; //0 RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1_0; //0
4. Der Faktor N und die Teiler P, Q, R.
//PLL1DIVR bits //DIVN1[8:0] 0 - 8 PLLN = 400 //DIVP1[6:0] 9 - 15 PLLP = 2 //DIVQ1[6:0] 16 - 22 PLLQ = 2 //DIVR1[6:0] 24 - 30 PLLR = 2 RCC -> PLL1DIVR |= 0x0101038F;
5. Bruchfrequenzteiler PLL (falls erforderlich)
// /* Configure PLL PLL1FRACN */ //__HAL_RCC_PLLFRACN_CONFIG(RCC_OscInitStruct->PLL.PLLFRACN)
6. Anzeige des Eingangsfrequenzbereichs PLL1
7. Anzeige des Ausgangsfrequenzbereichs PLL1
8. Ausgangsteiler PLL1 einschalten: P, Q, R.
/* Enable PLL System Clock output. */ // __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVP); //Bit 16 DIVP1EN: PLL1 DIVP divider output enable RCC->PLLCFGR |= RCC_PLLCFGR_DIVP1EN; /* Enable PLL1Q Clock output. */ //__HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVQ); RCC->PLLCFGR |= RCC_PLLCFGR_DIVQ1EN; /* Enable PLL1R Clock output. */ // __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVR); RCC->PLLCFGR |= RCC_PLLCFGR_DIVR1EN;
9. Die Einbeziehung des Bruchteilers.
10. Starten Sie PLL1 und warten Sie auf die Bereitschaft
PLL1 ist konfiguriert und läuft. Wählen Sie nun die SYSCLK-Frequenzquelle und richten Sie die Busteiler ein.
11. Teilen Sie durch 2 HPRE
//RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; // MODIFY_REG(RCC->D1CFGR, RCC_D1CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider); //HPRE[3:0]: D1 domain AHB prescaler //1000: rcc_hclk3 = sys_d1cpre_ck / 2 RCC -> D1CFGR |= RCC_D1CFGR_HPRE_3; //1 RCC -> D1CFGR &= ~RCC_D1CFGR_HPRE_2; //0 RCC -> D1CFGR &= ~RCC_D1CFGR_HPRE_1; //0 RCC -> D1CFGR &= ~RCC_D1CFGR_HPRE_0; //0
12. Ohne Division D1CPRE
//RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; //MODIFY_REG(RCC->D1CFGR, RCC_D1CFGR_D1CPRE, RCC_ClkInitStruct->SYSCLKDivider); //D1CPRE[3:0]: D1 domain Core prescaler //0xxx: sys_ck not divided (default after reset) RCC -> D1CFGR &= ~RCC_D1CFGR_D1CPRE_3; //0 RCC -> D1CFGR &= ~RCC_D1CFGR_D1CPRE_2; //0 RCC -> D1CFGR &= ~RCC_D1CFGR_D1CPRE_1; //0 RCC -> D1CFGR &= ~RCC_D1CFGR_D1CPRE_0; //0
13. Stellen Sie PLL1 als SYSCLK-Quelle ein und warten Sie auf die Bereitschaft
//RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; //MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource); //SW[2:0]: System clock switch //011: PLL1 selected as system clock (pll1_p_ck) RCC->CFGR &= ~RCC_CFGR_SW_2; //0 RCC->CFGR |= RCC_CFGR_SW_1; //1 RCC->CFGR |= RCC_CFGR_SW_0; //1 while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL1);
14. Teilen Sie durch 2 D1PPRE
//D1PCLK1 Configuration //RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; //MODIFY_REG(RCC->D1CFGR, RCC_D1CFGR_D1PPRE, RCC_ClkInitStruct->APB3CLKDivider); //Bits 6:4 D1PPRE[2:0]: D1 domain APB3 prescaler //100: rcc_pclk3 = rcc_hclk3 / 2 RCC -> D1CFGR |= RCC_D1CFGR_D1PPRE_2; RCC -> D1CFGR &= ~RCC_D1CFGR_D1PPRE_1; RCC -> D1CFGR &= ~RCC_D1CFGR_D1PPRE_0;
15. Teilen Sie durch 2 D2PPRE1
//PCLK1 Configuration //RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; //MODIFY_REG(RCC->D2CFGR, RCC_D2CFGR_D2PPRE1, (RCC_ClkInitStruct->APB1CLKDivider)); //Bits 6:4 D2PPRE1[2:0]: D2 domain APB1 prescaler //100: rcc_pclk1 = rcc_hclk1 / 2 RCC -> D2CFGR |= RCC_D2CFGR_D2PPRE1_2; RCC -> D2CFGR &= ~RCC_D2CFGR_D2PPRE1_1; RCC -> D2CFGR &= ~RCC_D2CFGR_D2PPRE1_0;
16. Teilen Sie durch 2 D2PPRE2
//PCLK2 Configuration //RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; //MODIFY_REG(RCC->D2CFGR, RCC_D2CFGR_D2PPRE2, (RCC_ClkInitStruct->APB2CLKDivider)); //Bits 10:8 D2PPRE2[2:0]: D2 domain APB2 prescaler //100: rcc_pclk2 = rcc_hclk1 / 2 RCC -> D2CFGR |= RCC_D2CFGR_D2PPRE2_2; RCC -> D2CFGR &= ~RCC_D2CFGR_D2PPRE2_1; RCC -> D2CFGR &= ~RCC_D2CFGR_D2PPRE2_0;
17. Teilen Sie durch 2 D3PPRE
//D3PCLK1 Configuration //RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; //MODIFY_REG(RCC->D3CFGR, RCC_D3CFGR_D3PPRE, (RCC_ClkInitStruct->APB4CLKDivider) ); //Bits 6:4 D3PPRE[2:0]: D3 domain APB4 prescaler //100: rcc_pclk4 = rcc_hclk4 / 2 RCC -> D3CFGR |= RCC_D3CFGR_D3PPRE_2; RCC -> D3CFGR &= ~RCC_D3CFGR_D3PPRE_1; RCC -> D3CFGR &= ~RCC_D3CFGR_D3PPRE_0;
Um sicherzustellen, dass die Konfiguration und der Start erfolgreich waren, verwenden wir den Ausgang des MCO2-Mikrocontrollers. Dieser Ausgang sollte eine Frequenz von 26,666 MHz mit einem Ausgangsteiler von 15 haben.

Großartig. Die Frequenz ist vorhanden, dann wird alles richtig gemacht.