Microsecond delay function for STM32

Using Data Watchpoint and Trace Registers (DWT).
32-bit CYCCNT register counts processor cycles.

#include "stm32f10x.h"

extern uint32_t SystemCoreClock;

void DWT_Init(void) 
{
  if (!(CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk)) 
  {
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
    DWT->CYCCNT = 0;
    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
  }
}

uint32_t DWT_Get(void)
{
  return DWT->CYCCNT;
}

__inline
uint8_t DWT_Compare(int32_t tp)
{
  return (((int32_t)DWT_Get() - tp) < 0);
}

void DWT_Delay(uint32_t us) // microseconds
{
  int32_t tp = DWT_Get() + us * (SystemCoreClock/1000000);
  while (DWT_Compare(tp));
}

Maximum delay is about 29 seconds when microprocessor is clocked at 72Mhz.

((2^32)/72000000)/2=29.8

DWT_Get function is useful to benchmark code at runtime. Maximum  measured time is about 59 seconds

(2^32)/72000000=59.7

For example when running at 72mhz, we measure how much milliseconds took our code:

uint32_t st,en;
DWT_Init();
...
st=DWT_Get();
... // code that is measured
en=DWT_Get();
printf("%d ms\r\n",((en-st)/72000));

For STM32F407 clocked at 168Mhz in the STM32F4 Discovery board maximum delay is about 12 seconds.

((2^32)/168000000)/2=12.8

and maximum  measured time is about 25 seconds

(2^32)/168000000=25.6

 

4 thoughts on “Microsecond delay function for STM32

  1. hey nice post,
    I am getting an error DWT undefined symbol. In which file is the structure located. I am using keil with the std peripheral library for stm32f103

  2. DWT structures are defined in “core_cm3.h” which is included in “stm32f10x.h”. And every STD Peripherals Library include (*.h) file includes “stm32f10x.h”.

  3. The DWT is not defined in older versions of core_cm3.h (for example version 2.1) but is defined in newer version (for example 3.01)

Leave a comment