Library 03- STM32F4 system clock and delay functions

In first tutorial about discovery board we were blinking led. But I said nothing about system clock speed. In while loop we just use

for some delay, to actually see how led was blinking. We didn’t know at which clock speed our processors work and for first time, I think you didn’t even ask yourself.

May 26, 2015

A new version, 2.4 was just released. It features custom timers in library.

Custom timers are a way of having some tasks which have to be called periodically in “strange” timer intervals, like one task each 100ms, another each 107ms, third each 123ms and so on.

The way this works is that each time delay timer makes 1ms interrupt, interrupt handler checks for all created software “timers”. If their value, which is decreased in this systick handler reaches zero, callback function is called for user.

Timers allows custom features like custom reload value when callbacks happen and auto reload value is possible too. Auto reload feature means that when timer reaches zero, then timer will begin counting at start value if auto reload is enabled.

If auto reload is not enabled, when timer reaches zero, callback is called and timer become disabled. To start it back, you have to manually enable it.

Look for all functions in library or API documentation for STM32F4xx libraries provided from me.

November 28, 2014

From this moment, there is new delay system. First system used Systick timer to make an interrupts every 1us. This allows us great accuracy in microseconds but not so nice for processor and interrupts. Also, Systick can be used for RTOS and then it become incompatible for my delay.

For that purpose, lib has been changes. now you have 2 options for delay:

  • Systick timer
  • Custom (peripheral) timer

With Systick timer, there is 1ms interrupt (not 1us anymore) for counting time and for 1us delay there is just simple variable based counter (not so accurate). If you need Systick timer for RTOS (or anything else) then you can enable any timer on your MCU for delay. To activate custom timer, open defines.h project file and add lines below:

In case above, TIM2 is used, but if you want your custom timer (TIM6 or TIM7, or anything) you can just replace number “2” with any custom number for your timer available in F4xx MCU.

This timer will also make an interrupts every 1ms but for microseconds delay, there will be better accuracy because delay just count timer’s ticks for proper value. For that purpose, you also need some additional libs:

  • CMSIS
    • STM32F4xx TIM
    • MISC
  • TM
    • TM TIMER PROPERTIES

GCC sucks!

It’s nice that is is free, but code compiled is totally different from ARM compiler (in Keil). So I suggest you, that you enable your timer for delay (Instead of Systick timer), otherwise your delay will not be accurate and you will have problems.

How to enable delay with custom timer is described above!

PS: If you are using ARM Compiler (Keil uVision) then you don’t need to use peripheral timer if you don’t want to.

Libraries where you might (not needed to) have problems if you are using ARM-GCC (Coocox, etc) compiler and variable-based delay for microseconds:

  • OneWire
    • Devices not recognized
  • DS18B20
    • Devices not recognized
  • HC-SR04
    • Invalid measured distance
  • AM2301
    • Invalid data
  • There might be also somewhere..

Up to 180MHz core clock speed

STM32F429 can go up to 180MHz. It has PLL (Phase-Locked Loop) inside to increase frequency from 8MHz external crystal which is on board. I will describe how you do this, step by step.

PS: On Clock speeds is a great tutorial how to do it with ST’s excel clock configuration tool, but this tool does not support frequencies larger than 168MHz, so we will do it manually.

STEP 1: Open your project file stm32f4xx.h and find code below (it should start at line 91):

Change it to:

STEP 2: Open your project file system_stm32f4xx.c and find (you can have other numbers, code should start at line 154):

Formula for system frequency is:

In our case (we want 180MHz) we will set these defines to:

These will give us exactly 180MHz.

STEP 3: In the same file, find (line 174)

and change it to

STEP 4: In file startup_stm32f4xx.c uncomment line below (line 143):

to

STEP 5: On top of main() function add this line:

That’s it, your system now works at 180MHz.

Precise delay

Microcontroller has Systick timer, which can be configured as interrupt generator every X ticks of core clock. In my delay library I set timer to interrupt every 1us. This is every 180 clock ticks.

Library dependencies

  • CMSIS
    • STM32F4xx
    • STM32F4xx RCC
  • TM
    • defines.h

How this works

When you use delay function, you set number of microseconds to delay. Systick timer decrease variable everytime interrupt is called. When timing variable is zero, delay has finished.

First, you have to initialize Systick timer (inside is code for set 180MHz core clock).

There are 2 functions to use with delay:

Functions and enumerations

Example

But sometimes you don’t want to waste some time for doing nothing, but you want toggle led every 500ms and send data to usart terminal together. In this case, you can do something like this:

Logic analyzer result for 500ms delay.

Result

I connected my logic analyzer to green led’s pin and result is on left.

Project is available on Github, download library below.

tilz0R

Owner of this site. Application engineer, currently employed by STMicroelectronics. Exploring latest technologies and owner of different libraries posted on Github.

You may also like...