Я работаю с комплектом обнаружения STM32F303VC , и я немного озадачен его производительностью. Чтобы познакомиться с системой, я написал очень простую программу, просто чтобы проверить скорость этого битового микроконтроллера. Код можно разбить следующим образом:
- Часы HSI (8 МГц) включены;
- PLL запускается с прескалером 16 для достижения HSI / 2 * 16 = 64 МГц;
- 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 с использованием оптимизации -O1. Сигналы на выводах PA8 (MCO) и PE10, проверенные осциллографом, выглядят так:
SYSCLK, кажется, настроен правильно, поскольку MCO (оранжевая кривая) демонстрирует колебания почти 64 МГц (с учетом погрешности внутреннего тактового сигнала). Странная часть для меня - это поведение на PE10 (синяя кривая). В бесконечном цикле while (1) требуется 4 + 4 + 5 = 13 тактовых циклов для выполнения элементарной трехэтапной операции (то есть установка битов / сброс битов / возврат). Это становится еще хуже на других уровнях оптимизации (например, -O2, -O3, ar -Os): несколько дополнительных тактовых циклов добавляются к НИЗКОЙ части сигнала, то есть между падающим и нарастающим фронтами PE10 (включение LSI как-то кажется чтобы исправить эту ситуацию).
Это поведение ожидается от этого MCU? Я хотел бы представить, что такая простая задача, как установка и сброс битов, должна быть в 2-4 раза быстрее. Есть ли способ ускорить процесс?