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.