Ich arbeite mit dem STM32F303VC Discovery Kit und bin etwas verwirrt über dessen Leistung. Um mich mit dem System vertraut zu machen, habe ich ein sehr einfaches Programm geschrieben, um einfach die Bit-Banging-Geschwindigkeit dieser MCU zu testen. Der Code kann wie folgt unterteilt werden:
- HSI-Takt (8 MHz) ist eingeschaltet;
- PLL wird mit dem mit dem Vorteiler von 16 initiiert, um HSI / 2 * 16 = 64 MHz zu erreichen;
- PLL wird als SYSCLK bezeichnet.
- SYSCLK wird am MCO-Pin (PA8) überwacht und einer der Pins (PE10) wird ständig in der Endlosschleife umgeschaltet.
Der Quellcode für dieses Programm ist unten dargestellt:
#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;
}
}
Der Code wurde mit CoIDE V2 mit der GNU ARM Embedded Toolchain unter Verwendung der -O1-Optimierung kompiliert. Die mit einem Oszilloskop untersuchten Signale an den Pins PA8 (MCO) und PE10 sehen folgendermaßen aus:
Der SYSCLK scheint korrekt konfiguriert zu sein, da der MCO (orange Kurve) eine Schwingung von fast 64 MHz aufweist (unter Berücksichtigung der Fehlergrenze des internen Takts). Der seltsame Teil für mich ist das Verhalten auf PE10 (blaue Kurve). In der Endlosschleife while (1) dauert es 4 + 4 + 5 = 13 Taktzyklen, um eine elementare 3-Schritt-Operation durchzuführen (dh Bit-Set / Bit-Reset / Return). Bei anderen Optimierungsstufen (z. B. -O2, -O3, ar -Os) wird es noch schlimmer: Dem LOW-Teil des Signals werden mehrere zusätzliche Taktzyklen hinzugefügt, dh zwischen den fallenden und steigenden Flanken von PE10 (was den LSI irgendwie zu ermöglichen scheint um diese Situation zu beheben).
Wird dieses Verhalten von dieser MCU erwartet? Ich würde mir vorstellen, dass eine so einfache Aufgabe wie das Einstellen und Zurücksetzen ein bisschen 2-4 mal schneller sein sollte. Gibt es eine Möglichkeit, die Dinge zu beschleunigen?