Description

HAL_Delay is able to provide minimum 1 ms delay, but when it comes to microseconds, there isn’t any predefined function to create 1 us delay in HAL Library. In this tutorial, I am going to show you how to create 1 microsecond delay in STM32. We will be using one of the Timer to do so. The process will be same for all the STM32 devices, you need to make some minor changes though.

I am using STM32F103C8 controller with CUBEIDE but as I mentioned, it will work same for other microcontrollers with any other IDE also.

Setup

This is the most important part of this process, so read this section very carefully. First of all we need to decide which Timer to use for the process. There is no special requirement, just choose any one. I will be using timer 1.

As you can see in the picture below (from the datasheet), the TIM1 is connected to the APB2 clock. This is a very important piece of information, and you should know it about the timer that you are going to use.

F103C8_BLOCK
F103C8_BLOCK

Now, let’s start the cubeIDE, and open the clock setup tab. Here you can see that, once I set the HCLK at MAX i.e. 72MHz, the APB2 clock is also at 72MHz.

clock setup
clock setup

This means that the TIMER 1 is also running at 72MHz, as the TIM1 is connected to the APB2. Now, let’s reduce this frequency in the timer setup section.

timer setup microseconds
timer setup microseconds

As shown in the picture above, first of all you have to enable the clock source as internal clock.
Prescaler divides the Timer clock further, by the value that you input in the prescaler. As we want the delay of 1 microsecond, the timer frequency must be (1/(1 us)), i.e 1 MHz. And for this reason, the prescaler value is 72.
Note that it’s 72-1, because the prescaler will add 1 to any value that you input there.

The ARR i am setting is the max value it can have. Basically, the counter is going to count from 0 to this value. Every count will take 1 us. So setting this value as high as possible is the best, because this way you can have large delays also. I have set it to 0xffff-1, and it is the maximum value that a 16 bit register (ARR) can have.

I have also enabled the pin PA1 as output, so that we can see the result in an oscilloscope.

Some insight into the CODE

Now, we will write a function to create this 1 us delay. Below is the one.

void delay_us (uint16_t us)
{
	__HAL_TIM_SET_COUNTER(&htim1,0);  // set the counter value a 0
	while (__HAL_TIM_GET_COUNTER(&htim1) < us);  // wait for the counter to reach the us input in the parameter
}

When the function is called with the parameter as the number of microseconds, the following operations takes place

  • The counter in the TIM1 is set to 0
  • The counter keeps counting, until the us value has been reached

As i mentioned before, each count takes 1 us, and therefore the counter will keep counting in microseconds until the input value has reached. Once it happens, the control will come out of the loop, and we have had achieved the delay.

Inside the main loop, we must start the timer, after all the peripherals are initialized.

HAL_TIM_Base_Start(&htim1);

Now, to use the required delay, all we have to do is use the function that we created above.

  while (1)
  {
	  HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_1);
	  delay_us(10);
  }
100%
100%

Result

10 us delay
10 us delay
 100 us delay
100 us delay
  1000 us delay
1000 us delay
Check out the VIDEO Below

DOWNLOAD

You can buy me a coffee sensor ūüôā

download the CODE below

100%
100%
0 0 vote
Article Rating
Subscribe
Notify of
guest
17 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Menu
17
0
Would love your thoughts, please comment.x
()
x