Sto lavorando con il kit di rilevamento STM32F303VC e sono leggermente perplesso dalle sue prestazioni. Per conoscere il sistema, ho scritto un programma molto semplice semplicemente per testare la velocità di bit-bang di questo MCU. Il codice può essere suddiviso come segue:
- Il clock HSI (8 MHz) è attivato;
- PLL viene avviato con il prescaler di 16 per ottenere HSI / 2 * 16 = 64 MHz;
- PLL è designato come SYSCLK;
- SYSCLK viene monitorato sul pin MCO (PA8) e uno dei pin (PE10) viene costantemente attivato / disattivato nel loop infinito.
Il codice sorgente per questo programma è presentato di seguito:
#include "stm32f3xx.h"
int main(void)
{
// Initialize the HSI:
RCC->CR |= RCC_CR_HSION;
while(!(RCC->CR&RCC_CR_HSIRDY));
// Initialize the LSI:
// RCC->CSR |= RCC_CSR_LSION;
// while(!(RCC->CSR & RCC_CSR_LSIRDY));
// PLL configuration:
RCC->CFGR &= ~RCC_CFGR_PLLSRC; // HSI / 2 selected as the PLL input clock.
RCC->CFGR |= RCC_CFGR_PLLMUL16; // HSI / 2 * 16 = 64 MHz
RCC->CR |= RCC_CR_PLLON; // Enable PLL
while(!(RCC->CR&RCC_CR_PLLRDY)); // Wait until PLL is ready
// Flash configuration:
FLASH->ACR |= FLASH_ACR_PRFTBE;
FLASH->ACR |= FLASH_ACR_LATENCY_1;
// Main clock output (MCO):
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
GPIOA->MODER |= GPIO_MODER_MODER8_1;
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_8;
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR8;
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR8;
GPIOA->AFR[0] &= ~GPIO_AFRL_AFRL0;
// Output on the MCO pin:
//RCC->CFGR |= RCC_CFGR_MCO_HSI;
//RCC->CFGR |= RCC_CFGR_MCO_LSI;
//RCC->CFGR |= RCC_CFGR_MCO_PLL;
RCC->CFGR |= RCC_CFGR_MCO_SYSCLK;
// PLL as the system clock
RCC->CFGR &= ~RCC_CFGR_SW; // Clear the SW bits
RCC->CFGR |= RCC_CFGR_SW_PLL; //Select PLL as the system clock
while ((RCC->CFGR & RCC_CFGR_SWS_PLL) != RCC_CFGR_SWS_PLL); //Wait until PLL is used
// Bit-bang monitoring:
RCC->AHBENR |= RCC_AHBENR_GPIOEEN;
GPIOE->MODER |= GPIO_MODER_MODER10_0;
GPIOE->OTYPER &= ~GPIO_OTYPER_OT_10;
GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR10;
GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR10;
while(1)
{
GPIOE->BSRRL |= GPIO_BSRR_BS_10;
GPIOE->BRR |= GPIO_BRR_BR_10;
}
}
Il codice è stato compilato con CoIDE V2 con GNU ARM Embedded Toolchain usando l'ottimizzazione -O1. I segnali sui pin PA8 (MCO) e PE10, esaminati con un oscilloscopio, si presentano così:
Il SYSCLK sembra essere configurato correttamente, poiché l'MCO (curva arancione) presenta un'oscillazione di quasi 64 MHz (considerando il margine di errore del clock interno). La parte strana per me è il comportamento su PE10 (curva blu). Nell'infinito ciclo while (1) sono necessari 4 + 4 + 5 = 13 cicli di clock per eseguire un'operazione elementare in 3 fasi (ovvero bit-set / bit-reset / return). Peggiora ancora su altri livelli di ottimizzazione (es. -O2, -O3, ar -Os): diversi cicli di clock aggiuntivi vengono aggiunti alla parte LOW del segnale, cioè tra i fronti di caduta e di salita di PE10 (abilitando in qualche modo l'LSI per porre rimedio a questa situazione).
Questo comportamento è previsto da questo MCU? Immagino che un'attività semplice come impostare e ripristinare un po 'dovrebbe essere 2-4 volte più veloce. C'è un modo per accelerare le cose?