2020-12-31 01:48 AM
Hi All,
I am using STM32F74xxx.
I need to count micro seconds. currently we are using HAL_GetTick(), function but it gives the time in ms.
After I searched on google I found some ways to get micro seconds count, and I tried it but no luck.
can any one help me here?
This is what I tried to use but my board gets rebooted.
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;
}
uint8_t DWT_Compare(int32_t tp)
{
return (((int32_t)DWT_Get() - tp) < 0);
}
void DWT_Delay(uint32_t us) // microseconds
{
int8_t correction_factor = 8;
int32_t tp = DWT_Get() + us * ((SystemCoreClock/1000000) / correction_factor);
while (DWT_Compare(tp));
}
/**
* @brief Initializes DWT_Clock_Cycle_Count for DWT_Delay_us function
* @return Error DWT counter
* 1: clock cycle counter not started
* 0: clock cycle counter works
*/
uint32_t DWT_Delay_Init(void) {
/* Disable TRC */
CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; // ~0x01000000;
/* Enable TRC */
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // 0x01000000;
/* Disable clock cycle counter */
DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; //~0x00000001;
/* Enable clock cycle counter */
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; //0x00000001;
/* Reset the clock cycle counter value */
DWT->CYCCNT = 0;
/* 3 NO OPERATION instructions */
__ASM volatile ("NOP");
__ASM volatile ("NOP");
__ASM volatile ("NOP");
/* Check if clock cycle counter has started */
if(DWT->CYCCNT)
{
return 0; /*clock cycle counter started*/
}
else
{
return 1; /*clock cycle counter not started*/
}
}
main()
{
DWT_Init();
uint32_t count = 0;
while(1)
{
DWT_Delay(2000000);
printf("count = %lu\r\n",count++);
}
}
Is there any other way to get microseconds count at run time? currently all my timers are in use.
2020-12-31 02:06 AM
You need to speak a magic word first:
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->LAR = 0xC5ACCE55;
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
Next, stick to uint32_t when comparing differences, this will handle overflows correctly because the diff is silently modulus 2^32.
uint32_t tick = DWT->CYCCNT;
...
uint32_t tock = DWT->CYCCNT;
...
if( tock - tick > delay )
2020-12-31 02:35 AM
Thanks KnarfB for the quick response,
I think I am able to access DWT registers now, but I am still not getting how to use it for getting count at real time?
Is it correct what I am planning to do?
this is for just basic understanding.
uint32_t curr_tick = 0;
main()
{
curr_tick = DWT->CYCCNT;
//some task
if((DWT->CYCCNT - curr_tick) >= 1000000)
{
printf("after 1 sec\r\n");
}
}
2020-12-31 03:49 AM
Yes. If you need a delay_us function you wait in a while loop until the condition is met. This is busy waiting though, the while loop eats up the whole processor.
2020-12-31 07:12 AM
Might be simpler just to configure TIM2 or TIM5 as 32-bit timers, of maximal length, prescaled down to 1 MHz