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:
  1. void clock_hsi(void)
  2. void clock_hse(void)
  3. 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	}
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.
SourceMinMaxUnité
HSI2.335.04mA
HSE2.454.83mA
PLL2.504.41mA
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.