私はSTM32F303VC ディスカバリーキットを使用していますが、そのパフォーマンスに少し困惑しています。システムに慣れるために、このMCUのビットバンギング速度をテストするための非常に単純なプログラムを作成しました。コードは次のように分類できます。
- HSIクロック(8 MHz)がオンになっています。
- PLLは16のプリスケーラーで開始され、HSI / 2 * 16 = 64 MHzを達成します。
- PLLはSYSCLKとして指定されています。
- SYSCLKはMCOピン(PA8)で監視され、ピンの1つ(PE10)は無限ループで常にトグルされます。
このプログラムのソースコードを以下に示します。
#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;
}
}
コードは、-O1最適化を使用して、GNU ARM Embedded Toolchainを使用してCoIDE V2でコンパイルされました。オシロスコープで調べたピンPA8(MCO)およびPE10の信号は、次のようになります。
MCO(オレンジカーブ)がほぼ64 MHzの発振を示すため、SYSCLKは正しく構成されているように見えます(内部クロックのエラーマージンを考慮)。私にとって奇妙な部分は、PE10(青い曲線)の動作です。無限while(1)ループでは、基本的な3ステップ操作(ビットセット/ビットリセット/リターン)を実行するのに4 + 4 + 5 = 13クロックサイクルかかります。他の最適化レベル(例:-O2、-O3、ar -Os)ではさらに悪化します。信号のLOW部分、つまりPE10の立ち下がりエッジと立ち上がりエッジの間にいくつかの追加のクロックサイクルが追加されます(LSIの有効化この状況を改善するため)。
この動作はこのMCUから予想されますか?設定とリセットを2〜4倍速くするだけの簡単なタスクを想像します。物事をスピードアップする方法はありますか?