Estoy trabajando con el STM32F303VC kit de descubrimiento y me sorprende un poco su rendimiento. Para familiarizarme con el sistema, he escrito un programa muy simple simplemente para probar la velocidad de bits de esta MCU. El código se puede desglosar de la siguiente manera:
- El reloj HSI (8 MHz) está activado;
- PLL se inicia con el prescaler de 16 para alcanzar HSI / 2 * 16 = 64 MHz;
- PLL se designa como SYSCLK;
- SYSCLK se monitorea en el pin MCO (PA8), y uno de los pines (PE10) se alterna constantemente en el bucle infinito.
El código fuente de este programa se presenta a continuación:
#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;
}
}
El código se compiló con CoIDE V2 con GNU ARM Embedded Toolchain utilizando la optimización -O1. Las señales en los pines PA8 (MCO) y PE10, examinadas con un osciloscopio, se ven así:
El SYSCLK parece estar configurado correctamente, ya que la MCO (curva naranja) muestra una oscilación de casi 64 MHz (considerando el margen de error del reloj interno). La parte extraña para mí es el comportamiento en PE10 (curva azul). En el bucle infinito while (1), se requieren 4 + 4 + 5 = 13 ciclos de reloj para realizar una operación elemental de 3 pasos (es decir, bit-set / bit-reset / return). Empeora aún más en otros niveles de optimización (p. Ej., -O2, -O3, ar -Os): se agregan varios ciclos de reloj adicionales a la parte BAJA de la señal, es decir, entre los flancos descendentes y ascendentes de PE10 (lo que hace que parezca que el LSI parece para remediar esta situación).
¿Se espera este comportamiento de esta MCU? Me imagino que una tarea tan simple como configurar y restablecer un poco debería ser 2 a 4 veces más rápida. ¿Hay alguna manera de acelerar las cosas?