Je travaille avec le kit de découverte STM32F303VC et je suis légèrement déconcerté par ses performances. Pour vous familiariser avec le système, j'ai écrit un programme très simple simplement pour tester la vitesse de frappe de ce MCU. Le code peut être décomposé comme suit:
- L'horloge HSI (8 MHz) est activée;
- La PLL est initiée avec le prédécaleur de 16 pour atteindre HSI / 2 * 16 = 64 MHz;
- PLL est désigné comme le SYSCLK;
- SYSCLK est surveillé sur la broche MCO (PA8), et l'une des broches (PE10) est constamment basculée dans la boucle infinie.
Le code source de ce programme est présenté ci-dessous:
#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;
}
}
Le code a été compilé avec CoIDE V2 avec GNU ARM Embedded Toolchain en utilisant l'optimisation -O1. Les signaux sur les broches PA8 (MCO) et PE10, examinés avec un oscilloscope, ressemblent à ceci:
Le SYSCLK semble être configuré correctement, car le MCO (courbe orange) présente une oscillation de près de 64 MHz (compte tenu de la marge d'erreur de l'horloge interne). La partie bizarre pour moi est le comportement sur PE10 (courbe bleue). Dans la boucle infinie while (1), il faut 4 + 4 + 5 = 13 cycles d'horloge pour effectuer une opération élémentaire en 3 étapes (c'est-à-dire bit-set / bit-reset / return). Cela empire encore sur d'autres niveaux d'optimisation (par exemple -O2, -O3, ar -Os): plusieurs cycles d'horloge supplémentaires sont ajoutés à la partie LOW du signal, c'est-à-dire entre les fronts descendant et montant de PE10 (l'activation du LSI semble en quelque sorte pour remédier à cette situation).
Ce comportement est-il attendu de ce MCU? J'imagine qu'une tâche aussi simple que définir et réinitialiser un peu devrait être 2 à 4 fois plus rapide. Existe-t-il un moyen d'accélérer les choses?