Tôi đang làm việc với bộ khám phá STM32F303VC và tôi hơi bối rối bởi hiệu suất của nó. Để làm quen với hệ thống, tôi đã viết một chương trình rất đơn giản chỉ để kiểm tra tốc độ đập của MCU này. Mã có thể được chia nhỏ như sau:
- Đồng hồ HSI (8 MHz) được bật;
- PLL được bắt đầu với bộ tổng hợp trước là 16 để đạt được HSI / 2 * 16 = 64 MHz;
- PLL được chỉ định là SYSCLK;
- SYSCLK được theo dõi trên chân MCO (PA8) và một trong các chân (PE10) liên tục được bật trong vòng lặp vô hạn.
Mã nguồn cho chương trình này được trình bày dưới đây:
#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;
}
}
Mã được biên dịch với CoIDE V2 với GNU ARM Embedded Toolchain bằng cách sử dụng tối ưu hóa -O1. Các tín hiệu trên chân PA8 (MCO) và PE10, được kiểm tra bằng máy hiện sóng, trông như thế này:
SYSCLK dường như được cấu hình đúng, vì MCO (đường cong màu cam) thể hiện dao động gần 64 MHz (xem xét biên độ lỗi của đồng hồ bên trong). Phần kỳ lạ đối với tôi là hành vi trên PE10 (đường cong màu xanh). Trong vòng lặp while (1) vô hạn, phải mất 4 + 4 + 5 = 13 chu kỳ xung nhịp để thực hiện thao tác 3 bước cơ bản (nghĩa là bit-set / bit-reset / return). Nó thậm chí còn tệ hơn ở các mức tối ưu hóa khác (ví dụ -O2, -O3, ar -Os): một số chu kỳ xung nhịp bổ sung được thêm vào phần THẤP của tín hiệu, tức là giữa các cạnh rơi và tăng của PE10 (cho phép LSI dường như bằng cách nào đó để khắc phục tình trạng này).
Là hành vi này được mong đợi từ MCU này? Tôi sẽ tưởng tượng một nhiệm vụ đơn giản như thiết lập và đặt lại một chút phải nhanh hơn 2-4 lần. Có cách nào để tăng tốc mọi thứ?