Estou trabalhando com o kit de descoberta STM32F303VC e estou um pouco intrigado com seu desempenho. Para me familiarizar com o sistema, escrevi um programa muito simples, simplesmente para testar a velocidade desse MCU. O código pode ser dividido da seguinte maneira:
- O relógio HSI (8 MHz) está ativado;
- O PLL é iniciado com o com o pré-calibrador de 16 para atingir HSI / 2 * 16 = 64 MHz;
- PLL é designado como SYSCLK;
- O SYSCLK é monitorado no pino MCO (PA8), e um dos pinos (PE10) é constantemente alternado no loop infinito.
O código fonte deste programa é apresentado abaixo:
#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;
}
}
O código foi compilado com o CoIDE V2 com o GNU ARM Embedded Toolchain usando a otimização -O1. Os sinais nos pinos PA8 (MCO) e PE10, examinados com um osciloscópio, têm a seguinte aparência:
O SYSCLK parece estar configurado corretamente, pois o MCO (curva laranja) exibe uma oscilação de quase 64 MHz (considerando a margem de erro do relógio interno). A parte estranha para mim é o comportamento no PE10 (curva azul). No loop while (1) infinito, são necessários 4 + 4 + 5 = 13 ciclos de relógio para executar uma operação elementar de 3 etapas (isto é, set-bit / bit-reset / return). Fica ainda pior em outros níveis de otimização (por exemplo, -O2, -O3, ar -Os): vários ciclos de clock adicionais são adicionados à parte LOW do sinal, ou seja, entre as bordas crescente e decrescente do PE10 (permitindo que o LSI de alguma forma pareça para remediar esta situação).
Esse comportamento é esperado deste MCU? Eu imagino que uma tarefa tão simples quanto definir e redefinir um pouco deve ser 2-4 vezes mais rápida. Existe uma maneira de acelerar as coisas?