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
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
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”.
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)
Hi! Does this code work properly if cyccnt overflow and begin new cycle from 0?