STM32L0 : Changing Clock Frequency
Changing the clock frequency is something I usually never do
because the startup file provided by Keil sets the STM32F1 to 72MHz by default,
which has always been fine with me. However as late I have been testing out TrueStudio
as an IDE. At the same time I managed to break my last St-Link so I have been using
my Nucleo board with its on-board ST-Link to play around with TrueStudio. I will give my thoughts on TrueStudio on a later post.
By default the Nucleo pictured here runs on its internal RC oscillator @ 2MHz, This series of MCU by ST targets low power applications so this explains their default setting. To change the frequency requires setting a few bits
in a few registers and checking a few flags, imagine that. However, to really send this bad boy running requires some soldering and desoldering of solder bridges, I do not have any other Nucleo boards so I do not know if this is a common practice with them, but the way this specific board has been manufactured it is. The soldering required is straight forward so fear not.
The hardware modification is necessary because there is no external
crystal or oscillator connected to the appropriate pin A0 on the microcontroller,
in fact I believe this little guy only accepts an external clock on that single
A0 pin, and not a conventional crystal. (I am not talking about the 32KHz clock for the RTC, I am only talking about main System Clock)So you could use something like a MEMS oscillator. But in this case the board was manufactured in such a way that the ST-Link
that is on-board shares its clock.
This is done by enabling the Master Clock Output (MCO) on the ST-Link
microcontroller which is an STM32F1. That master clock output is then fed to
the A0 clock pin of the STM32L031. To make that connection we have to remove
some solder bridges and create one. Well the bridges are already there we just must
provide the solder.
The hardware part:
Here is a link the manual for the specific board I am using.
On page 33 you will see the following schematic of the MCU and notice the SB17
(Solder bridge) which connects the MSO (MASTER CLOCK OUT) to the mcu A0.
Another important part of this manual is page 19 that shows what solder bridges need to be on or off to get the desired clock. Where "ON" means that we must close the gap in the solder bridge and thus make a connection, and "OFF" means we remove any solder/jumper/0-Ohm resistor making the connection and thus break the connection. I have provided the table on page 19 here for your viewing pleasure.
Below are images taken from pages 11 and 12 of the manual showing the location of the specified
solder bridges. Click to enlarge.
In a nutshell you are going to desolder bridges 4 5 6 7 and
8. Meaning that if there is a 0 ohm resistor bridging the gap you must remove
it. If there is solder alone bridging the gap you must remove it. Then on the
other side of the board you will find solder bridge number 17 but for this one you must bridge the gap, adding enough solder to complete the connection.
The software part:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | void setClockTo32Mhz(void) { //adjust flash latency REG_VAL = FLASH->ACR ; FLASH->ACR |= FLASH_ACR_LATENCY ; while( (FLASH->ACR & FLASH_ACR_LATENCY) == 0 ) ; //wait for latency set flag //set voltage scaling to range 1 PWR->CR |= PWR_CR_VOS_0 ; PWR->CR &= ~(PWR_CR_VOS_1); while( ((PWR->CSR) & (PWR_CSR_VOSF)) == 1) ; //wait for voltage to settle //turn on HSE external, HSE bypass and security RCC->CR |= RCC_CR_CSSHSEON | RCC_CR_HSEBYP | RCC_CR_HSEON ; while( ((RCC->CR) & RCC_CR_HSERDY) == 0) ; //wait for the HSE to be ready //reset and configure pll mull and div settings, and PLL source RCC->CFGR = ( (RCC->CFGR & ~(RCC_CFGR_PLLDIV | RCC_CFGR_PLLMUL)) | RCC_CFGR_PLLDIV2 | RCC_CFGR_PLLMUL8 | RCC_CFGR_PLLSRC_HSE ) ; while((RCC->CR & RCC_CR_PLLRDY )== 1) ; //turn on PLL , wait for ready RCC->CR |= RCC_CR_PLLON; while( ((RCC->CR) & RCC_CR_PLLRDY) == 0 ) ; // wait for pll to ready //set PLL as system clock RCC->CFGR |= RCC_CFGR_SW_PLL; while( ((RCC->CFGR)&(RCC_CFGR_SWS_PLL)) != RCC_CFGR_SWS_PLL ); } |
It is very important that after any modification to the
system clock or system bus clocks the function SystemCoreClockUpdate is called.
According to the CMSIS header file where this function is located:
“Each time the core clock (HCLK) changes, this function must
be called to update the SystemCoreClock variable value. Otherwise any
configuration based on this value will be incorrect .“
One of those configurations being my favorite SystickConfig
function. As you can see below only after updating my clock and calling the
SystemCoreClockUpdate function do I call my SysTickConfig function. Otherwise
the systick will be configured using the default 2MHz value.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | int main(void) { setClockTo32Mhz(); SystemCoreClockUpdate(); SysTick_Config(SystemCoreClock/1000); while (1) { } return 0; } |
This comment has been removed by a blog administrator.
ReplyDelete