add 80MHz clock example

main
Clyne 1 year ago
parent 4592359e98
commit ce7d778208
Signed by: clyne
GPG Key ID: 3267C8EBF3F9AFC7

@ -0,0 +1,5 @@
COMMON_DIR := ../common
CFILES += main.c
include $(COMMON_DIR)/rules.mk

@ -0,0 +1,14 @@
# 0. 80MHz system clock
This example shows how to set up the STM32 microcontroller to execute at its faster clock speed of 80MHz.
Achieving this speed requires two things:
1. Setting up the Phase-Locked Loop (PLL) to multiply a source clock up to 80MHz.
2. Configuring flash wait-states to ensure that the processor does not execute faster than instructions can be fetched.
Once the system clock is set to 80MHz, the Microcontroller Clock Output (MCO) is configured to output the system clock
over pin PA8. This output can be viewed with an oscilloscope to confirm the clock's speed.
See `main.c` for comments describing the configuration steps in more detail.

@ -0,0 +1,49 @@
#include <stm32l476xx.h>
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");
}
Loading…
Cancel
Save