Easy STM32 Wait Timer

The STM32 series of microcontrollers has a powerful set of timers that are capable of all sorts of waveform generation, timebase, and interrupt-driven tasks. But sometimes you want something simple, like the Arduino guys have:
delayMicroseconds(). This can be helpful in so many places.

Now, in a recent project, I needed an accurate way to delay in a routine by some number of microseconds, so I dug out the (massive) datasheet on the STM32F411RE processor at the heart of the Nucleo board I’m experimenting with. I came up with an accurate, reliable way to delay for some microseconds.

I started with CubeMX to create the basic timebase:

static void MX_TIM3_Init(void)
{
htim3.Instance = TIM3;
htim3.Init.Prescaler = 99; // 99 is really 100 so 1us at 100MHz
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 0; //59999 is 3ms max pulse
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
}

Since I’m running my board at 100MHz, I chose a prescaler of 99 to get a 1/100 ratio of bus clock ticks to timer ticks.

Then, in my main routine, I called the initialization routine:

MX_TIM3_Init();

Now, down in the routine where I wanted the delay, here’s the magic code:


TIM3->ARR = {some 16-bit unsigned value};
TIM3->SR &= ~(TIM_SR_UIF);
TIM3->CR1 |= TIM_CR1_CEN;
while((TIM3->SR & TIM_SR_UIF) != TIM_SR_UIF) ;
TIM3->CR1 &= ~(TIM_CR1_CEN);

This results in a very exact delay as the timer ticks and waits until the the timer’s update interrupt flag is set.
I don’t actually need an interrupt service routine for this, as I’m only waiting for its flag to be set. Voila! An accurate microseconds timer for STM32.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s