cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L462 delay in a microsecond(us)

AP_040
Senior

HAL Library provide the HAL_Delay() for millisecond delay. I want to use micro second delay in STM32L4 so how I do it? Is it available in HAL library?

1 ACCEPTED SOLUTION

Accepted Solutions
AP_040
Senior

I am done.

Added this dwt files in my project and working fine.

#ifndef DWT_STM32_DELAY_H
#define DWT_STM32_DELAY_H
 
#ifdef __cplusplus
extern "C" {
#endif
 
 
#include "stm32f1xx_hal.h"
uint32_t DWT_Delay_Init(void);
 
 
 
/**
 * @brief  This function provides a delay (in microseconds)
 * @param  microseconds: delay in microseconds
 */
__STATIC_INLINE void DWT_Delay_us(volatile uint32_t microseconds)
{
  uint32_t clk_cycle_start = DWT->CYCCNT;
 
  /* Go to number of cycles for system */
  microseconds *= (HAL_RCC_GetHCLKFreq() / 1000000);
 
  /* Delay till end */
  while ((DWT->CYCCNT - clk_cycle_start) < microseconds);
}
 
 
#ifdef __cplusplus
}
#endif
 
#endif

View solution in original post

12 REPLIES 12

Use a free running TIM at 1 MHz or faster, and delta the TIM->CNT​ in a loop until you get the elapsed micro-seconds

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
AP_040
Senior

Hello @Community member​  I found below example and implement in my MCU but it is not properly delay the system.

//******************************************************************************

volatile unsigned int *DWT_CYCCNT = (volatile unsigned int *)0xE0001004; //address of the register

volatile unsigned int *DWT_CONTROL = (volatile unsigned int *)0xE0001000; //address of the register

volatile unsigned int *SCB_DEMCR = (volatile unsigned int *)0xE000EDFC; //address of the register

//******************************************************************************

void EnableTiming(void)

{

*SCB_DEMCR = *SCB_DEMCR | 0x01000000;

*DWT_CYCCNT = 0; // reset the counter

*DWT_CONTROL = *DWT_CONTROL | 1 ; // enable the counter

}

//******************************************************************************

void HAL_Delay_us(uint32_t tick)

{

unsigned int start, current;

start = *DWT_CYCCNT;

do

{

current = *DWT_CYCCNT;

} while((current - start) < tick);

}

Is it register address is different for my MCU?

Can I do it this way without free running timer?

Yes, this will work on non CM0(+) parts. CM7 parts need an unlock sequence

It will have the granularity of the CPU clock.

1ms = SystemCoreClock / 1000

1us = SystemCoreClock / 1000000

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
AP_040
Senior

@Community member​ 

So, I need to change "1us = SystemCoreClock / 1000000" this in HAL_InitTick(). Is it?

HAL_SYSTICK_Config(SystemCoreClock / (1000000U/ uwTickFreq))

instead of

HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq))

This way?

AP_040
Senior

I am done.

Added this dwt files in my project and working fine.

#ifndef DWT_STM32_DELAY_H
#define DWT_STM32_DELAY_H
 
#ifdef __cplusplus
extern "C" {
#endif
 
 
#include "stm32f1xx_hal.h"
uint32_t DWT_Delay_Init(void);
 
 
 
/**
 * @brief  This function provides a delay (in microseconds)
 * @param  microseconds: delay in microseconds
 */
__STATIC_INLINE void DWT_Delay_us(volatile uint32_t microseconds)
{
  uint32_t clk_cycle_start = DWT->CYCCNT;
 
  /* Go to number of cycles for system */
  microseconds *= (HAL_RCC_GetHCLKFreq() / 1000000);
 
  /* Delay till end */
  while ((DWT->CYCCNT - clk_cycle_start) < microseconds);
}
 
 
#ifdef __cplusplus
}
#endif
 
#endif

No, this is simply a computation of CPU ticks passed into HAL_Delay_us() to achieve a milli-second, or micro-second of elapsed time. It doesn't use/change SysTick.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
S.Ma
Principal

You can simply do a nop loop if you know the core frequency. Otherwise, the lptimer is a good way to generate delays and callbacks.

AP_040
Senior

@S.Ma​  Yes, we can do it using LPtimer and callbacks but still I have note worked with timer yet. So, can you please help me how I generate microseconds delay using timer itself?

S.Ma
Principal

This forum is inadequate to share source code (did answer and shared this kind of source code already), I'm not going to do the extra mile to compensate for the forum missing services. One there is an STM32 community Git repo for code example, snippets, projets with web links to use on this forum, it may make things much more efficient sharing know-how.