STM32F303VC keşif kiti ile çalışıyorum ve performansından biraz şaşkınım . Sistemle tanışmak için, bu MCU'nun bit hızını test etmek için çok basit bir program yazdım. Kod aşağıdaki gibi parçalanabilir:
- HSI saati (8 MHz) açık;
- PLL, HSI / 2 * 16 = 64 MHz'e ulaşmak için 16 ön ölçekleyici ile başlatılır;
- PLL, SYSCLK olarak belirlenmiştir;
- SYSCLK MCO pimi (PA8) üzerinde izlenir ve pimlerden biri (PE10) sonsuz döngüde sürekli olarak değiştirilir.
Bu programın kaynak kodu aşağıda sunulmuştur:
#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, -O1 optimizasyonu kullanılarak GNU ARM Gömülü Alet Zinciri ile CoIDE V2 ile derlenmiştir. Bir osiloskopla incelenen PA8 (MCO) ve PE10 pimleri üzerindeki sinyaller şöyle görünür:
MCO (turuncu eğri) yaklaşık 64 MHz'lik bir salınım gösterdiğinden SYSCLK doğru yapılandırılmış gibi görünmektedir (dahili saatin hata payı dikkate alınarak). Benim için garip olan kısım PE10 (mavi eğri) üzerindeki davranış. Sonsuz while (1) döngüsünde, temel bir 3 adımlı işlem (yani bit-set / bit-reset / return) gerçekleştirmek için 4 + 4 + 5 = 13 saat çevrimi gerekir. Diğer optimizasyon seviyelerinde daha da kötüleşir (örn. -O2, -O3, ar -Os): sinyalin DÜŞÜK kısmına, yani PE10'un düşen ve yükselen kenarlarına (LSI'nin bir şekilde görünmesini sağlamak için) birkaç ek saat döngüsü eklenir bu durumu düzeltmek için).
Bu davranış, bu MCU'dan bekleniyor mu? Biraz ayar ve sıfırlama kadar basit bir görevi 2-4 kat daha hızlı olmalı. İşleri hızlandırmanın bir yolu var mı?