Sie sind auf Seite 1von 7

Clocks (and GPIO Speed)

Before discussing how to increase the operating speed of the STM32F4DISCOVERY board, keep
in mind that the faster the MCU operates, the greater its power consumption will be. A tradeoff
between power consumption and operating speed must always be a consideration. As a rule of
thumb: always operate at the slowest speed that will adequately do all that is necessary.

The STM32F4DISCOVERY board literature states that this MCU can operate at clock speeds up to
168MHz. One might then immediately assume that the GPIO toggle speed should be substantially
faster than we experience. In fact, the datasheet for the STM32F4xx states that a maximum toggle
rate of 84MHz is achievable. However, since the output must toggle twice to produce a waveform,
the maximum frequency we should be able to achieve would be 42MHz. We will use the following
program as a benchmark with which to test GPIO output frequency:


#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"

void delay(u32 count){
while(count--);
}

int main(){

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOD,&GPIO_InitStructure);
while(1)
{
GPIOD->ODR = 0x2000;
delay(500000);
GPIOD->ODR = 0x0000;
delay(500000);
}
}

If you do not have access to an oscilloscope with which to observe the waveform on GPIOD pin 13,
the delay() function will slow the toggle sufficiently for you to observe its changing rate as we
modify clock settings; if you have access to an oscilloscope, remove the delay() function and the
two lines in main() that call the delay() function. All stated output frequencies in this tutorial are
measured with an oscilloscope when the code has no delay() function.

When we run the above program (remember that the delay() function and the calls to it are
removed/commented for measurement purposes) and measure the GPIO output, we observe a
frequency of approximately 1.5MHz - nowhere near the 42MHz we would like.

Clock Discussion


All peripherals, the CPU, and all there associated clocks come from one of four (4) sources:

HSE - High Speed External clock is an external crystal or resonator to the MCU. This can have any
frequency between 4MHz and 26MHz. The STM32F4DISCOVERY board comes with an 8MHz
crystal.
HSI - High Speed Internal clock is an internal oscillator with a fixed frequency of 16MHz.
LSE - Low Speed External crystal of exactly 32.768kHz (or resonator) drives the RTC (Real Time
Clock)
LSI - Low Speed Internal clock of 32kHz drives certain other low speed peripherals

The signal from one of these four (4) clock sources drives subsequent individual clocks within the
MCU:

PLL - (Phase Locked Loop) has multiple outputs which can each have a different frequency. The
PLL has the ability to provide an output frequency greater than its input frequency. It is driven by
either the HSE or the HSI.
SysTick - or SYSCLK (System Clock) determines how quickly instructions are executed and has a
maximum speed of 168MHz.
AHB - (AHB1, AHB2, and AHB3) is the Advance High Performance Bus clock is driven by the
SYSCLK and also has a maximum speed of 168MHz. This clock drives many of the peripherals
APB1 - Advanced Peripheral Bus 1 which has a maximum frequency of 42MHz and drives some of
the peripherals
APB2 - Advanced Peripheral Bus 2 which has a maximum frequency of 84MHz and drives other
peripherals
The I2S peripheral has its own clock
If you look at the STM32F4DISCOVERY board, you will observe that it has two (2) mounted
crystals - both are 8MHz. One of these crystals drives the ST-Link; the other drives the HSE clock.

One way to achieve a higher GPIO output frequency is to remove the mounted HSE crystal and
replace it with one of higher frequency (I have seen 25MHz recommended although I don't
remember where.) This is a method I do not recommend unless you are confident in your de-
soldering/soldering skills.

The other method to increase GPIO output frequency is to configure the many clocks by modifying
code already in our project. This code is in files that the compiler references even though they might
not specifically be included in our program. We'll use this method; but, first ...

Changing Clock Settings

Add a call to the SystemInit() function to the beginning of main() as follows:


int main(){
SystemInit();

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOD,&GPIO_InitStructure);
while(1){
GPIOD->ODR = 0x2000;
// delay(500000); // uncomment if your don't have an oscilloscope
GPIOD->ODR = 0x0000;
// delay(500000); // uncomment if your don't have an oscilloscope
}

}

The SystemInit() function's definition is in the system_stm32f4xx.c file located in the project
window of the CoIDE The function's prototype is in the startup_stm32f4xx.c file albeit it is
commented in this file so it is not automatically added to our code by the compiler and therefore not
run on boot-up. By adding it to our main() function, we are calling SystemInit() after boot-up
(without any apparent negative consequence.) In fact, adding the call to SystemInit() boosts our
output frequency to approximately 4.9MHz.

For comparison:

default configuration - 1.5MHz
with the SystemInit() function - 4.9MHz
The ST Clock Configuration Tool

ST provides an Excel workbook that not only calculates various clock configuration settings; it can
even produce a file that the compiler will automatically include when compiling your program. As
of the writing of this tutorial, this tool is available from the following URL. Download the
instructions on its use in the Application Note on the same page.


http://www.st.com/web/en/catalog/tools/PF257927

When you open the file, you should make the changes outlined as follows (using the Wizard
Configuration Mode - do not change any other settings until you know what you are doing):

Where it says to "Enter HSE" oscillator frequency, change the 25 to 8. The 8 (MHz is implied) is
the actual frequency of the supplied crystal. While we won't use the HSE in our configuration, there
is no benefit to leave the value uncorrected.
Where it says to "Enter HCLK", change the default value to 168 (MHz is implied). This is the
highest datasheet speed for the system clock.
Click the "Run" button. When is asks you to "Select the system clock source", click of the
PLL(HSI) selection, then click OK. We are selecting the internal oscillator because, while not as
accurate, it is twice as fast as the external crystal.
The APB1 Prescaler should read 4 and the APB2 Prescaler should read 2. The lower the number,
the faster the Systick (which is what we want.) In fact, if you tried to reduce the Prescaler further,
the Clock Tool will inform you that you have exceeded the system clock's capability.

Click the "Generate" button. Excel will create a file called system_stm32f4xx.c. This file should be
in the same folder from which you ran the Clock Configuration Tool. Find the file in Windows
Explorer because you will need to move it to your project.
Use Windows Explorer to locate your project in the Workspace. Within your project, in
thecmsis_boot folder, you have a file called system_stm32f4xx.c. Overwrite this file with your
newly created file using the Clock Configuration Tool. You will know you were successful when
the files older date changes to the current date.
Looking at the Clock Configuration Tool, at the spot where we change the HSE frequency to
8MHz, you will notice just below a message instructing us to also change the HSE value in the
stm32f4xx.h header file. Open the stm32f4xx.h file in the CoIDE and locate the lines shown below:


#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */

Modify the code as follows:


#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */


Now open the startup_stm32f4xx.c file in CoIDE. Find the following code:


/*----------Function prototypes-----------------------------------------------*/
extern int main(void); /*!< The entry point for the application. */
//extern void SystemInit(void); /*!< Setup the microcontroller system(CMSIS) */
void Default_Reset_Handler(void); /*!< Default reset handler */
static void Default_Handler(void); /*!< Default exception handler */
Remove the comment so the section is as follows:

/*----------Function prototypes-----------------------------------------------*/
extern int main(void); /*!< The entry point for the application. */
extern void SystemInit(void); /*!< Setup the microcontroller system(CMSIS) */
void Default_Reset_Handler(void); /*!< Default reset handler */
static void Default_Handler(void); /*!< Default exception handler */
Next, further down in the same file, locate following section of code:


/* Call the application's entry point.*/
main();

And modify it as follows:


/* Call the application's entry point.*/
SystemInit();
main();

Finally, in your main.c file, remove the call to SystemInit().

With these changes, an oscilloscope reveals we have increased the output frequency to
15.3MHz.For comparison:
default configuration - 1.5MHz
with the SystemInit() function - 4.9MHz
using the Clock Configuration Tool and making the other indicated changes - 15.3MHz.
More will probably be added at this point in the next few days.
Is there such a thing as too much speed?

As mentioned at the beginning of this tutorial, the higher the speed, the greater the power
dissipation. If we are making a battery powered device, lower power consumption equates to longer
battery life. My rule of thumb is - use the lowest clock speed that gets the job done.

Another consideration is the highest speed the peripheral attached to our GPIO can handle. In our
case, the blue LED no longer lights up while the others do. Upon analysis for the cause of this
failure, I am sure a work around could be achieved

Das könnte Ihnen auch gefallen