#include int main(void) { // Disable interrupts asm("cpsid i"); // Running at 80MHz requires configuring flash wait-states: FLASH->ACR = (FLASH->ACR & ~(FLASH_ACR_LATENCY)) | FLASH_ACR_LATENCY_4WS; // Configure the PLL to output 80MHz: // 1. MSI clock is 4MHz at reset, use MSI as source for PLL // 2. Set PLLN multiplier to 40: 4MHz * 40 = 160MHz // 3. PLLM divider is set to zero, no division there // 4. Set PLLR system clock divider to zero = division by two // 160MHz / 2 = 80MHz RCC->PLLCFGR = RCC_PLLCFGR_PLLSRC_MSI | (40 << RCC_PLLCFGR_PLLN_Pos) | (0 << RCC_PLLCFGR_PLLR_Pos) | RCC_PLLCFGR_PLLREN; // Enable the PLL RCC->CR |= RCC_CR_PLLON; while ((RCC->CR & RCC_CR_PLLRDY) != RCC_CR_PLLRDY); // Set the system clock to use PLL // Also clear the HPRE divider to be safe RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_HPRE_Msk | RCC_CFGR_SW_Msk)) | RCC_CFGR_SW_PLL; while ((RCC->CFGR & RCC_CFGR_SWS_PLL) != RCC_CFGR_SWS_PLL); // The processor is now running at 80MHz! // Enable MCO to output the system clock over PA8 RCC->CFGR &= ~(RCC_CFGR_MCOPRE_Msk); RCC->CFGR |= 2 << RCC_CFGR_MCOSEL_Pos; // Configure PA8 for alternate function zero (MCO) RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN; GPIOA->MODER &= ~(GPIO_MODER_MODE8_Msk); GPIOA->MODER |= 2 << GPIO_MODER_MODE8_Pos; GPIOA->AFR[1] &= ~(GPIO_AFRH_AFSEL8_Msk); // Using a volatile assembly instruction ensures that this loop is not // optimized away by the compiler. while (1) asm volatile("nop"); }