add 80MHz clock example
parent
4592359e98
commit
ce7d778208
@ -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…
Reference in New Issue