Saya bekerja dengan kit penemuan STM32F303VC dan saya sedikit bingung dengan kinerjanya. Untuk berkenalan dengan sistem, saya telah menulis sebuah program yang sangat sederhana hanya untuk menguji kecepatan bit-banging dari MCU ini. Kode dapat diuraikan sebagai berikut:
- Jam HSI (8 MHz) dihidupkan;
- PLL dimulai dengan prescaler 16 untuk mencapai HSI / 2 * 16 = 64 MHz;
- PLL ditunjuk sebagai SYSCLK;
- SYSCLK dimonitor pada pin MCO (PA8), dan salah satu pin (PE10) terus-menerus diaktifkan di loop tak terbatas.
Kode sumber untuk program ini disajikan di bawah ini:
#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;
}
}
Kode ini dikompilasi dengan CoIDE V2 dengan GNU ARM Embedded Toolchain menggunakan optimasi -O1. Sinyal pada pin PA8 (MCO) dan PE10, diperiksa dengan osiloskop, terlihat seperti ini:
SYSCLK tampaknya dikonfigurasikan dengan benar, karena MCO (kurva oranye) menunjukkan osilasi hampir 64 MHz (mempertimbangkan margin kesalahan jam internal). Bagian yang aneh bagi saya adalah perilaku pada PE10 (kurva biru). Dalam infinite while (1) loop dibutuhkan 4 + 4 + 5 = 13 siklus siklus untuk melakukan operasi 3-langkah dasar (yaitu bit-set / bit-reset / kembali). Ini menjadi lebih buruk pada level optimisasi lainnya (mis. -O2, -O3, ar -Os): beberapa siklus clock tambahan ditambahkan ke bagian RENDAH dari sinyal, yaitu antara tepi jatuh dan naik dari PE10 (memungkinkan entah bagaimana sepertinya LSI untuk memperbaiki situasi ini).
Apakah perilaku ini diharapkan dari MCU ini? Saya akan membayangkan tugas sesederhana mengatur dan mengatur ulang sedikit harus 2-4 kali lebih cepat. Apakah ada cara untuk mempercepat?