Blue Pill - Sources d'horloge
Table des matières
TL;DR
Passer d'une source d'horloge à une autre.
Projet
A partir du montage feu rouge et bouton, un appui sur le bouton change la source d'horloge et sa LED associée. La LED intégrée à la carte est allumée quand la source est la PLL. La seule "difficultée" consiste à cadencer l'horloge à 8 MHz quelle que soit la source car SYSTICK doit générer une interruption à chaque seconde.
Fonctions
3 fonctions pour basculer d'une source à l'autre:
- void clock_hsi(void)
- void clock_hse(void)
- void clock_pll(uint32_t pll_mull, uint32_t prescalers)
Seule la dernière est détaillée et mérite quelques explications:
1 # define CLOCK_PRESCALERS RCC_CFGR_PLLXTPRE | RCC_CFGR_ADCPRE | RCC_CFGR_PPRE2 | RCC_CFGR_PPRE1 | RCC_CFGR_HPRE
2
3 void
4 clock_pll(uint32_t pll_mull, uint32_t prescalers) {
5 RCC->CFGR |= RCC_CFGR_PLLSRC; // set PLL SouRCe to HSE
6 RCC->CFGR &= ~RCC_CFGR_PLLMULL; // reset PLL MULtipLication
7 RCC->CFGR |= pll_mull << RCC_CFGR_PLLMULL_Pos; // set PLL multiplication
8
9 FLASH->ACR &= ~FLASH_ACR_LATENCY; // reset flash latency
10 if (pll_mull > RCC_CFGR_PLLMULL6) {
11 FLASH->ACR |= FLASH_ACR_LATENCY_2; // 2 wait states !!! REQUIRED !!!
12 }
13 else if (pll_mull > RCC_CFGR_PLLMULL3) {
14 FLASH->ACR |= FLASH_ACR_LATENCY_1; // 1 wait state !!! REQUIRED !!!
15 }
16
17 RCC->CFGR &= ~(CLOCK_PRESCALERS); // reset prescalers
18 RCC->CFGR |= prescalers; // set prescalers
19
20 RCC->CR |= RCC_CR_PLLON; // set PLL ON (== enable)
21 while ( !(RCC->CR & RCC_CR_PLLRDY) ); // wait for the PLLReaDY flag
22 RCC->CFGR &= ~RCC_CFGR_SW; // reset system clock SWitch
23 RCC->CFGR |= RCC_CFGR_SW_PLL; // SWitch to PLL
24 while ( !(RCC->CFGR & RCC_CFGR_SWS_PLL) ); // wait for SWitch Status to PLL
25 RCC->CR &= ~(RCC_CR_HSION); // disable HSI
26 }
- l.5: la source de la PLL est HSE car un peu de précison de fera pas de mal en cas de hautes fréquences
- l.9-15: le facteur de multiplication permet de configurer la latence de la flash
- l.17-18: j'ai fait le choix de ne pas configurer les diviseurs individuellement, je verrai à l'usage si c'est une mauvaise idée
Pour avoir une PLL à 8 MHz:
clock_pll(RCC_CFGR_PLLMULL2, RCC_CFGR_PLLXTPRE_HSE_DIV2); // 2 * (HSE / 2) == 8 MHz
Consommation
Les mesures ont été faites sans le code gérant la LED intégrée. J'avoue ne pas savoir quelle(s) conclusion(s) en tirer, signe que ce test n'est certainement pas pertinent.
| Source | Min | Max | Unité |
| HSI | 2.33 | 5.04 | mA |
| HSE | 2.45 | 4.83 | mA |
| PLL | 2.50 | 4.41 | mA |
Le code complet: https://gitlab.com/dsx/blue-pill/-/tree/master/stm32f103c8t6/01_clocks_hse_pll_btn
A suivre
La configuration de la source d'horloge et de sa fréquence est un pré-requis pour l'utilisation de certains composants. Il est temps de découvrir le lien série, USART de son petit nom.