STM32 risparmio energetico: STM32F4 black-pill gestione clock e frequenze

Spread the love

Un fattore essenziale dei nostri microcontrollori è il consumo energetico. Come al solito, ho iniziato ad analizzare questo aspetto senza entrare nel dettaglio della modalità sleep ma con alcune soluzioni alternative offerte dal microcontrollore.

STM32F4 black pill power saving: gestione delle frequenze dell'orologio
STM32F4 black pill power saving: gestione delle frequenze del clock

La scalabilità della frequenza nell’STM32 è più complessa che in altri microcontrollori, in particolare perché l’architettura è più complessa, e STM32 ha scelto di fornire lo strumento per semplificare quella gestione e non per mascherare la complessità.

Ecco la mia selezione di STM32 STM32F103C8T6 STM32F401 STM32F411 ST-Link v2 ST-Link v2 official

Ecco i miei multimetri testati Aneng SZ18

Quindi la prima cosa da fare per approcciare questo argomento è scaricare STM32CubeIDE perché, anche se non sviluppi con l’interprete nativo di STM32, il core Arduino avvolge la funzione del core nativo (ciò genera uno spazio maggiore nella memoria Flash), e garantisce la possibilità di utilizzare un generatore di codice.

STM32CubeIDE

STM32CubeIDE è uno strumento di sviluppo all-in-one multi-OS che fa parte dell’ecosistema software STM32Cube. STM32CubeIDE è una piattaforma di sviluppo C/C++ con configurazione periferica, generazione di codice, compilazione del codice, e funzioni di debug per microcontrollori e microprocessori STM32.

Puoi scaricarlo da questo link.

Configura STM32F4 black-pill

Questo IDE ti permette di programmare il chip nativo STM32, ma non usiamo il chip direttamente, quindi abbiamo bisogno di ricreare la scheda di prototipazione.

Ad esempio, il chip come STM32F4 non ha un oscillatore esterno (LSE e HSE), ma la scheda di prototipazione STM32F411CEU6 black pill ha queste periferiche integrate.

Puoi controllare lo schema nell’articolo dettagliato su STM32F411CEU6.

STM32F4 schema: sistema e cristallo RTC
STM32F4 schema: sistema e cristallo RTC

Per semplificare il tuo lavoro, condivido un file di progetto con tutto configurato come previsto: STM32F411 black pill.

Carica il progetto usando
File --> Nuovo --> Progetto STM32 da file di configurazione STM32CubeMX esistente (.ioc)

STM32CubeIde: importa file di configurazione .ioc

Ora hai un progetto completamente inizializzato ma vuoto. Puoi fare doppio clic sul file .ioc, e atterrerai sulla scheda Pinout & Configuration del configuratore.

STM32CubeIde device configuration: STM32F4 black pill
Configurazione del dispositivo STM32CubeIde: STM32F4 black pill

Puoi ottenere il diagramma a blocchi / flusso completo e modificabile del clock facendo clic sulla configurazione del clock.

STM32CubeIde device configuration: Clock configuration of STM32F4 black pill
Configurazione del dispositivo STM32CubeIde: Configurazione del clock di STM32F4 black pill

Il diagramma mostra quattro clocks, due interni LSI e HSI, e due esterni HSE e LSE.

Ma prima di analizzare quel diagramma, stiamo esaminando l’architettura di base di un STM32.

Architettura STM32F4

Per capire l’architettura, usiamo un diagramma a blocchi.

stm32f411ce: block diagram
stm32f411ce: diagramma a blocchi

Alcune parti centrali non sono utilizzate in questo tutorial, e le descrivo qui.

  • DMA (Direct Memory Access, accesso diretto alla memoria) consente a dispositivi hardware di velocità diverse di comunicare; non deve dipendere dal carico di interruzione del CPU.
  • SRAM(Static Random-Access Memory, Memoria ad accesso casuale statica) Il cosiddetto “ stato statico ” significa che questo tipo di memoria, fintanto che rimane alimentata, I dati memorizzati in esso possono rimanere costanti;
  • FSMC (Flexible Static Memory Controller, Controllore di memoria statica flessibile ), Abilità di lavorare con storage sincrono o asincrono e connessione di scheda PC a 16 posizioni, STM32 Di FSMC L’interfaccia di supporto include SRAM, NAND FLASH, NOR FLASH, e PSRAM Uguale storage.
  • DRAM(Dynamic Random Access Memory, Memoria ad accesso casuale dinamico) I dati memorizzati in esso devono essere aggiornati periodicamente.
    Tuttavia, Quando l’alimentazione si interrompe, SRAM I dati memorizzati scompariranno ancora (detto memoria volatile); è lo stesso di poter memorizzare dati dopo un’interruzione dell’alimentazione ROM O memoria flash FLASH È diverso.
  • I-Bus: prende M4, L’interfaccia dei comandi del bus di istruzioni e FLASH, Usato per il prelievo di istruzioni.
    D-Bus: prende M4 L’interfaccia dati del bus dati del kernel e FLASH, caricamento costante, e debugging.

Le parti rimanenti sono ciò di cui abbiamo bisogno, e tutti i periferici sono gestiti con due bus APBx; naturalmente, questi bus sono sincronizzati con i clocks e vengono utilizzati per gestire tutto. E ora possiamo approfondire la configurazione del clock.

Diagramma dei clocks

Come già descritto, possiamo esaminare le fonti di quattro clocks.

  • Clock esterno ad alta velocità (HSE): L’oscillatore a cristallo esterno viene utilizzato come sorgente del clock, e la frequenza dell’oscillatore a cristallo è nell’intervallo da 4 a 26 MHz, e generalmente si utilizza l’oscillatore a cristallo da 25 MHz.
  • Clock interno ad alta velocità (HSI): Generato dall’oscillatore RC interno con una frequenza di 16 MHz, ma non è stabile, e l’accuratezza non è alta.
  • Clock esterno a bassa velocità (LSE): L’oscillatore a cristallo esterno viene utilizzato come sorgente del clock, principalmente fornito al modulo del clock in tempo reale, quindi si utilizza generalmente 32.768 kHz.
  • Clock interno a bassa velocità (LSI): Generato dall’oscillatore RC interno, anche principalmente fornito al modulo del clock in tempo reale, con una frequenza di circa 32kHz, fornisce un clock a basso consumo.

Ora possiamo aggiungere nuovamente il diagramma a blocchi di STM32CubeIde con la configurazione predefinita di STM32F411 black-pill.

STM32F4 black pill gestione delle frequenze: diagramma dell'orologio
STM32F4 black pill gestione delle frequenze: diagramma del clock

Con questo diagramma, possiamo seguire il flusso del clock a partire da PLL Source Mux.

Sorgente del clock PLL

Ci sono due sorgenti del clock PLL: una è HSE, l’altra è HSI, e una è HSI che è il segnale del clock ad alta velocità interno con una frequenza di 16MHz. La frequenza varierà a seconda della temperatura e delle condizioni ambientali. Generalmente, non viene utilizzato come sorgente del clock di PLL, quindi si seleziona HSE come sorgente del clock di PLL.

PLL principale

Questo dispositivo ha un divisore principale da 2 a 63 prima del PLL principale poi può essere applicato un grande fattore di moltiplicazione del PLL da 50 a 432. Ma una soluzione migliore rispetto a STM32F1 sono i divisori separati uno per AHB e uno solo per l’USB. Quindi l’HSE di 25MHz viene diviso per 25 poi moltiplicato da 192 e diviso per 2 per il bus principale e per 4 per l’USB, una soluzione efficiente rispetto ad altri dispositivi. SYSCLK = 25MHz / 25 * 192 /2 = 96MHz.

Sistema di sicurezza del clock (CSS)

Se il clock HSE fallisce, l’oscillatore HSE viene automaticamente disattivato, e l’evento di guasto del clock sarà inviato all’input del freno dei timer avanzati (TIM1 e TIM8), e verrà generato un’interruzione di sicurezza del clock CSSI, permettendo al software di completare l’operazione di recupero. Questa interruzione CSSI è collegata all’interruzione NMI (non-maskable interrupt) di Cortex™-M3.

Clock USB

Nell’STM32 è presente un modulo USB a piena velocità, e il suo motore di interfaccia seriale richiede una sorgente clock con una frequenza di 48MHz. La fonte del clock può essere ottenuta solo dall’uscita del PLL (l’unico). Può essere diviso da 2 a 48.

Multiplexer del clock di sistema SYSCLK

La fonte del clock di sistema può essere HSI, PLLCLK e HSE. Impostare il clock di sistema qui: SYSCLK=PLLCLK=96MHz.

Clock del bus AHB HCLK

La frequenza ottenuta dopo la divisione del clock di sistema SYSCLK con il prescalatore AHB viene chiamato clock del bus APB, ovvero HCLK, e questo è consegnato al bus AHB, core, memoria, flash e DMA. Il fattore di divisione di frequenza può essere [1, 2, 4, 8, 16, 64, 128, 256, 512]. I clock della maggior parte dei periferici sul chip sono ottenuti dalla divisione di frequenza HCLK. Per quanto riguarda l’impostazione del clock delle periferiche sul bus AHB, deve essere impostato quando i periferici sono utilizzati. Qui, è sufficiente impostare approssimativamente i clock APB dividendo per 1, cioè HCLK=SYSCLK/1_AHB=96MHz.

Clock del bus APB2 PCLK2

Il clock del bus APB2 (Periferiche ad alta velocità) PCLK2 (Clock periferico) è ottenuto da HCLK attraverso il prescalatore APB2 ad alta velocità, e il fattore di divisione di frequenza può essere [1, 2, 4, 8, 16]. HCLK2 è un clock del bus ad alta velocità, e le periferiche ad alta velocità sul chip sono montate su questo bus, come tutti i GPIO, USART1, SPI1, ecc. Per quanto riguarda l’impostazione del clock della periferica sul bus APB2, deve essere impostata quando la periferica viene utilizzata. Qui, è solo necessario impostare approssimativamente il clock di APB2 e impostarlo per 1 divisione di frequenza, cioè, PCLK2=HCLK=96MHz.

Clock del bus APB1 PCLK1

Il clock del bus APB1 (Periferiche a bassa velocità) PCLK1 (Clock periferico) è ottenuto da HCLK attraverso il prescalatore APB a bassa velocità, e il fattore di divisione di frequenza può essere [1, 2, 4, 8, 16]. HCLK1 è un clock del bus a bassa velocità, fino a 36MHz; le periferiche a bassa velocità sul chip sono montate su questo bus, come USART 2/3/4/5, SPI 2/3, I2C 1/2, ecc. Per quanto riguarda l’impostazione del clock della periferica sul bus APB1, deve attendere fino a quando la periferica viene utilizzata. Qui, è solo necessario impostare approssimativamente il clock di APB1 e impostarlo per dividere per 2, cioè PCLK1=HCLK/2=48MHz.

STM32F4 black pill: gestione dell'energia con la gestione delle frequenze
STM32F4 black pill: gestione dell’energia con la gestione delle frequenze

Altro

Clock del sistema Cortex

Il clock del sistema Cortex si ottiene dividendo HCLK per 8, che equivale a 12MHz. Il clock del sistema Cortex è usato per guidare il timer di sistema SysTick del kernel. SysTick è generalmente usato per il battito del clock del sistema operativo e può anche essere utilizzato per la temporizzazione ordinaria.

Clock RTC, clock watchdog indipendente

Il clock RTC può essere ottenuto dividendo la frequenza di HSE/128, oppure il segnale del clock esterno a bassa velocità LSE può fornirlo con una frequenza di 32.768kHz, oppure può essere fornito dal segnale del clock interno a bassa velocità HSI. Il clock del watchdog indipendente è fornito da LSI e può essere fornito solo da LSI. LSI è un segnale del clock interno a bassa velocità con una frequenza di 30-60kHz, generalmente 32kHz.

STM32 STM32F411 STM32F411CEU6 disposizione dei pin a bassa risoluzione
STM32 STM32F411 STM32F411CEU6 disposizione dei pin a bassa risoluzione

Uscita clock MCO

MCO è l’abbreviazione di Microcontroller Clock Output. È il pin di uscita del clock del microcontrollore. Nella serie STM32 F1 è multiplexato su PA8. La sua funzione principale è fornire un clock al mondo esterno, che è equivalente a un oscillatore a cristallo attivo. Oltre a fornire un clock dal mondo esterno, possiamo anche monitorare l’output del clock del pin MCO con un oscilloscopio per verificare che la configurazione del clock di sistema sia corretta. La sorgente del clock MCO può essere PLLCLK/2, HSI, HSE, e SYSCLK.

Cambiare la configurazione del clock

Ora sappiamo come è composto lo STM32, e possiamo provare a cambiare quei valori secondo lo schema precedente per risparmiare energia.

Per cambiare quel parametro, il core STM32 ci dà la possibilità di sovrascrivere il valore predefinito in pratica; la dichiarazione della funzione nel core è segnata WEAK, e quindi la si sovrascrive con l’uso di extern.

WEAK void SystemClock_Config(void)
{
[...]
}

Per fare un test completo per molte situazioni, utilizzo ST-LINK e FDTI esterno per il debug; mi piacerebbe utilizzare Serial2 perché USART2 funziona su APB2 e usa il buffer a bassa velocità.

STM32F4 black pill e ST-Link: Debug di Serial2 via FTDI con controllo dell'amperaggio
STM32F4 black pill e ST-Link: Debug di Serial2 via FTDI con controllo dell’amperaggio

Ma penso che tu possa usare lo standard senza problemi Serial.

STM32F4 black pill e ST-Link: Debug di Serial via FTDI con controllo dell'amperaggio
STM32F4 black pill e ST-Link: Debug di Serial via FTDI con controllo dell’amperaggio

Ma fai attenzione, non puoi utilizzare il debug della seriale USB perché metteremo fuori uso l’USB con la gestione della frequenza.

Ottenere le frequenze correnti

Ora stiamo per lanciare un semplice sketch, e useremo una serie di stampe per mostrare le frequenze correnti.

/**
 * Test SysClock configuration on STM32
 * Disable USB Serial2
 * and use an external 
 * 
 * by Renzo Mischianti <www.mischianti.org>
 */

// If you use generic STM32F411CE
// you don't need this explicit declaration
// This is needed by blackpill specified version
HardwareSerial Serial2(USART2);   // PA3  (RX)  PA2  (TX)

void setup() {
  Serial2.begin(115200);
  while (!Serial2){ delay(100); }
  Serial2.println("START!");
}

void loop() {
  Serial2.println("------------------------------------");
  Serial2.printf("SYCLK= %dMHz\n", HAL_RCC_GetSysClockFreq()/1000000);

  Serial2.printf("HCLK = %dMHz\n", HAL_RCC_GetHCLKFreq()/1000000);
  Serial2.printf("APB1 = %dMHz\n", HAL_RCC_GetPCLK1Freq()/1000000);
  Serial2.printf("APB2 = %dMHz\n", HAL_RCC_GetPCLK2Freq()/1000000);
  Serial2.println("------------------------------------");
  Serial2.println();
  delay(5000);
}

As expected, the result.

------------------------------------
SYCLK= 96MHz
HCLK = 96MHz
APB1 = 48MHz
APB2 = 96MHz
------------------------------------

We can see in the multimeter a power consumption of 31,20mAh.

Now we try to create a configuration that replicates standard settings, I add here the whole sketch, and now we are going to do the verification.

/**
 * Test SysClock configuration on STM32
 * Disable USB Serial2
 * and use an external 
 * 
 * by Renzo Mischianti <www.mischianti.org>
 */

// If you use generic STM32F411CE
// you don't need this explicit declaration
// This is needed by blackpill specified version
HardwareSerial Serial2(USART2);   // PA3  (RX)  PA2  (TX)

/**
  * Standard configuration
  *  @brief  System Clock Configuration
  *         The system Clock is configured as follow :
  *            System Clock source            = PLL (HSE)
  *            SYSCLK(Hz)                     = 96000000
  *            HCLK(Hz)                       = 96000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 2
  *            APB2 Prescaler                 = 1
  *            PLL_Source                     = HSE
  *            PLL_M_Prescaler                = 25
  *            PLL_N_Mux                      = 192
  *            PLL_P_Prescaler                = 2
  *            PLL_Q_Prescaler                = 4
  *            Flash Latency(WS)              = 3
  * @param  None
  * @retval None
  */
extern "C" void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 192;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  {
    Error_Handler();
  }
}

void setup() {
  Serial2.begin(115200);
  while (!Serial2){ delay(100); }
  Serial2.println("START!");
}

void loop() {
  Serial2.println("------------------------------------");
  Serial2.printf("SYCLK= %dMHz\n", HAL_RCC_GetSysClockFreq()/1000000);

  Serial2.printf("HCLK = %dMHz\n", HAL_RCC_GetHCLKFreq()/1000000);
  Serial2.printf("APB1 = %dMHz\n", HAL_RCC_GetPCLK1Freq()/1000000);
  Serial2.printf("APB2 = %dMHz\n", HAL_RCC_GetPCLK2Freq()/1000000);
  Serial2.println("------------------------------------");
  Serial2.println();
  delay(5000);
}

Ed il risultato ottenuto è lo stesso:

------------------------------------
SYCLK= 96MHz
HCLK = 96MHz
APB1 = 48MHz
APB2 = 96MHz
------------------------------------

Alcuni piccoli cambiamenti nel consumo di energia (probabilmente abbiamo cambiato il divisore rispetto all’originale) ora è 31.50mAh.

Primo test di riduzione delle frequenze

Ora stiamo per fare una piccola riduzione delle frequenze, e stiamo per controllare il risultato.

Configurazione dell'orologio STM32F4 black pill: riduzione base del consumo energetico
Configurazione del clock STM32F4 black pill: riduzione base del consumo energetico

Come puoi vedere nel diagramma a blocchi, abbiamo fatto una buona riduzione dell’ AHB Prescaler con la conseguente riduzione delle frequenze HCLK con la conseguente diminuzione del periferico.

/**
 * Test SysClock configuration on STM32
 * Disable USB Serial2
 * and use an external 
 * 
 * by Renzo Mischianti <www.mischianti.org>
 */

// If you use generic STM32F411CE
// you don't need this explicit declaration
// This is needed by blackpill specified version
HardwareSerial Serial2(USART2);   // PA3  (RX)  PA2  (TX)

/**
  * First try reduction
  *  @brief  System Clock Configuration
  *         The system Clock is configured as follow :
  *            System Clock source            = PLL (HSE)
  *            SYSCLK(Hz)                     = 96000000
  *            HCLK(Hz)                       = 96000000  --> 24000000
  *            AHB Prescaler                  = 1         --> 4
  *            APB1 Prescaler                 = 2
  *            APB2 Prescaler                 = 1
  *            PLL_Source                     = HSE
  *            PLL_M_Prescaler                = 25
  *            PLL_N_Mux                      = 192
  *            PLL_P_Prescaler                = 2
  *            PLL_Q_Prescaler                = 4
  *            Flash Latency(WS)              = 3
  * @param  None
  * @retval None
  */
extern "C" void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 192;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV4;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  {
    Error_Handler();
  }
}

void setup() {
  Serial2.begin(115200);
  while (!Serial2){ delay(100); }
  Serial2.println("START!");
}

void loop() {
  Serial2.println("------------------------------------");
  Serial2.printf("SYCLK= %dMHz\n", HAL_RCC_GetSysClockFreq()/1000000);

  Serial2.printf("HCLK = %dMHz\n", HAL_RCC_GetHCLKFreq()/1000000);
  Serial2.printf("APB1 = %dMHz\n", HAL_RCC_GetPCLK1Freq()/1000000);
  Serial2.printf("APB2 = %dMHz\n", HAL_RCC_GetPCLK2Freq()/1000000);
  Serial2.println("------------------------------------");
  Serial2.println();
  delay(5000);
}

The console output now is

------------------------------------
SYCLK= 96MHz
HCLK = 24MHz
APB1 = 12MHz
APB2 = 24MHz
------------------------------------

E abbiamo una buona riduzione di mAh, e il risultato del multimetro è 14.65mAh.

Una migliore riduzione delle frequenze

Ora ridurremo alcune frequenze senza mettere fuori uso alcun periferico per mantenere il comportamento esatto di uno sketch.

Configurazione dell'orologio STM32F4 black pill: riduzione del consumo energetico
Configurazione del clock STM32F4 black pill: riduzione del consumo energetico

In questo caso, andremo a toccare il Main PLL con la riduzione del multiplexer e alcuni aggiustamenti per non mettere fuori uso l’USB.

/**
 * Test SysClock configuration on STM32
 * Disable USB Serial2
 * and use an external 
 * 
 * by Renzo Mischianti <www.mischianti.org>
 */

// If you use generic STM32F411CE
// you don't need this explicit declaration
// This is needed by blackpill specified version
HardwareSerial Serial2(USART2);   // PA3  (RX)  PA2  (TX)

/**
  * First test reduction
  *  @brief  System Clock Configuration
  *         The system Clock is configured as follow :
  *            System Clock source            = PLL (HSE)
  *            SYSCLK(Hz)                     = 96000000  --> 36000000
  *            HCLK(Hz)                       = 96000000  --> 36000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 2
  *            APB2 Prescaler                 = 1
  *            PLL_Source                     = HSE
  *            PLL_M_Prescaler                = 25
  *            PLL_N_Mux                      = 192       --> 144
  *            PLL_P_Prescaler                = 2         --> 4
  *            PLL_Q_Prescaler                = 4         --> 3
  *            Flash Latency(WS)              = 1
  * @param  None
  * @retval None
  */
extern "C" void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 144;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
  RCC_OscInitStruct.PLL.PLLQ = 3;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}


void setup() {
  Serial2.begin(115200);
  while (!Serial2){ delay(100); }
  Serial2.println("START!");
}

void loop() {
  Serial2.println("------------------------------------");
  Serial2.printf("SYCLK= %dMHz\n", HAL_RCC_GetSysClockFreq()/1000000);

  Serial2.printf("HCLK = %dMHz\n", HAL_RCC_GetHCLKFreq()/1000000);
  Serial2.printf("APB1 = %dMHz\n", HAL_RCC_GetPCLK1Freq()/1000000);
  Serial2.printf("APB2 = %dMHz\n", HAL_RCC_GetPCLK2Freq()/1000000);
  Serial2.println("------------------------------------");
  Serial2.println();
  delay(5000);
}

E qui il risultato in console

------------------------------------
SYCLK= 36MHz
HCLK = 36MHz
APB1 = 18MHz
APB2 = 36MHz
------------------------------------

Come previsto, abbiamo una riduzione notevole del consumo energetico, ma ricorda che tutte le prestazioni del nostro STM32 sono ridotte.

In questa configurazione, abbiamo 10.90mAh.

Conclusione

Abbiamo notato che le possibilità di STM32 sono molte, e dobbiamo conoscere molto bene l’architettura se vogliamo ottenere risultati migliori. Possiamo considerare la perdita di alcune periferiche se non necessarie e aggiungere più potenza a qualche unità funzionale specifica.

Grazie

  1. STM32F1 Blue Pill: piedinatura, specifiche e configurazione IDE Arduino (STM32duino e STMicroelectronics)
  2. STM32: programmazione (STM32F1) via USB con bootloader STM32duino
  3. STM32: programmazione (STM32F1 STM32F4) tramite USB con bootloader HID
  4. STM32F4 Black Pill: pinout, specifiche e configurazione IDE Arduino
  5. STM32: ethernet w5500 standard (HTTP) e SSL (HTTPS)
  6. STM32: ethernet enc28j60 standard (HTTP) e SSL (HTTPS)
  7. STM32: WiFiNINA con un ESP32 come WiFi Co-Processor
    1. STM32F1 Blue-pill: shield WiFi (WiFiNINA)
    2. STM32F4 Black-pill: shield WiFi (WiFiNINA)
  8. Come utilizzare la scheda SD con l’stm32 e la libreria SdFat
  9. STM32: memoria flash SPI FAT FS
  10. STM32: RTC interno, sistema orario e backup batteria (VBAT)
  11. STM32 LoRa
  1. STM32 Risparmio energetico
    1. STM32F1 Blue-Pill gestione clock e frequenza
    2. STM32F4 Black-Pill gestione clock e frequenza
    3. Introduzione e framework Arduino vs STM
    4. Libreria LowPower, cablaggio e Idle (STM Sleep).
    5. Sleep, deep sleep, shutdown e consumo energetico
    6. Sveglia da allarme RTC e Seriale
    7. Sveglia da sorgente esterna
    8. Introduzione al dominio di backup e conservazione delle variabili durante il RESET
    9. Registro di backup RTC e conservazione della SRAM
  2. STM32 invia email con allegati e SSL (come Gmail): w5500, enc28j60, SD e SPI Flash

Spread the love

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *