Pracuję z zestawem do wykrywania STM32F303VC i jestem nieco zaskoczony jego wydajnością. Aby zapoznać się z systemem, napisałem bardzo prosty program, aby po prostu przetestować szybkość bitowania tego MCU. Kod można podzielić w następujący sposób:
- Zegar HSI (8 MHz) jest włączony;
- PLL jest inicjowany za pomocą prekalera 16, aby osiągnąć HSI / 2 * 16 = 64 MHz;
- PLL jest oznaczony jako SYSCLK;
- SYSCLK jest monitorowany na pinie MCO (PA8), a jeden z pinów (PE10) jest stale przełączany w nieskończonej pętli.
Kod źródłowy tego programu przedstawiono poniżej:
#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;
}
}
Kod został skompilowany z CoIDE V2 z wbudowanym narzędziem GNU ARM przy użyciu optymalizacji -O1. Sygnały na pinach PA8 (MCO) i PE10, badane za pomocą oscyloskopu, wyglądają następująco:
SYSCLK wydaje się być poprawnie skonfigurowany, ponieważ MCO (krzywa pomarańczowa) wykazuje oscylację prawie 64 MHz (uwzględniając margines błędu zegara wewnętrznego). Dziwne dla mnie jest zachowanie na PE10 (niebieska krzywa). W nieskończonej pętli while (1) potrzeba 4 + 4 + 5 = 13 cykli zegara, aby wykonać podstawową 3-etapową operację (tj. Zestaw bitów / reset bitów / powrót). Jest jeszcze gorzej na innych poziomach optymalizacji (np. -O2, -O3, ar -Os): kilka dodatkowych cykli zegara jest dodawanych do NISKIEJ części sygnału, tj. Między opadającymi i rosnącymi krawędziami PE10 (włączenie LSI w jakiś sposób wydaje się zaradzić tej sytuacji).
Czy tego zachowania oczekuje się od tego MCU? Wyobrażam sobie, że zadanie tak proste jak ustawienie i resetowanie powinno być 2-4 razy szybsze. Czy istnieje sposób na przyspieszenie?