Microsecond/Nanoseconds delay in STM32
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, we will see how to create microsecond delays 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.
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 use 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.
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.
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.
- First of all, set 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.
Now, we will write a function to create this 1 us delay. Below is the one.
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.
Now, to use the required delay, all we have to do is use the function that we created above.