我正在使用 STM32F303VC发现套件,我对它的性能感到有些困惑。为了熟悉这个系统,我编写了一个非常简单的程序来测试这个 MCU 的 bit-banging 速度。代码可以分解如下:
- HSI 时钟 (8 MHz) 开启;
- PLL 以 16 的预分频器启动,以实现 HSI / 2 * 16 = 64 MHz;
- PLL 被指定为 SYSCLK;
- SYSCLK 在 MCO 引脚 (PA8) 上进行监控,其中一个引脚 (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;
}
}
该代码是使用 CoIDE V2 和 GNU ARM Embedded Toolchain 使用 -O1 优化编译的。用示波器检查引脚 PA8 (MCO) 和 PE10 上的信号如下所示:
SYSCLK 似乎配置正确,因为 MCO(橙色曲线)显示出接近 64 MHz 的振荡(考虑到内部时钟的误差范围)。对我来说奇怪的部分是 PE10 上的行为(蓝色曲线)。在无限while(1) 循环中,它需要4 + 4 + 5 = 13 个时钟周期来执行一个基本的3 步操作(即位设置/位复位/返回)。它在其他优化级别(例如 -O2、-O3、ar -Os)上变得更糟:在信号的 LOW 部分添加了几个额外的时钟周期,即在 PE10 的下降沿和上升沿之间(以某种方式启用 LSI 似乎来纠正这种情况)。
此 MCU 是否会出现这种行为?我想像设置和重置位这样简单的任务应该快 2-4 倍。有没有办法加快速度?