cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 microsecond delay function with polling method

hazall
Associate III

Hi,

I am using stm32f0. I try to microsecond delay function. But, I observe that TIMx->CNT not increasing.

I probably mistake on configutration function. But I could not solved. In 29 line, UF flag not to be set

Here is my code;

 

 

void ledconfig(){

  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC,ENABLE) ;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP ;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;  
  GPIO_Init(GPIOC, &GPIO_InitStructure); 

}
void configure_us_timer(uint32_t clock_freq, uint32_t us_delay) {
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);  
  uint32_t prescaler;
  uint32_t reload;
  prescaler = clock_freq / 1000000 - 1;
  reload = (us_delay * clock_freq) / (1000000 * (prescaler + 1)) - 1;
  TIM1->CR1 &= ~TIM_CR1_CEN;
  TIM1->PSC = prescaler;
  TIM1->ARR = reload;
  TIM1->CR1 |= TIM_CR1_URS;
  TIM1->CR1 |= TIM_CR1_CEN;
}
void delay_us(uint32_t us_delay) {
  // Configure timer for desired delay
  configure_us_timer(SystemCoreClock, us_delay);
// Wait for update flag to be set and then cleared (indicates one timer period elapsed)
  while ((TIM1->SR & TIM_SR_UIF) == 0);
  while ((TIM1->SR & TIM_SR_UIF) != 0);
  // Disable timer (optional)
  TIM1->CR1 &= ~TIM_CR1_CEN;
}

int main(void)
{ 
  ledconfig();
  GPIO_SetBits(GPIOC,GPIO_Pin_9) ; 
  delay_us(1000000); // to abserve that I configure it 1 second
  GPIO_ResetBits(GPIOC,GPIO_Pin_9) ; 
  while (1)
  {
  }
}

 

 

Thanks for helping

3 REPLIES 3
Danish1
Lead II
  • In your debugger, can you see that TIM1 is counting?
  • Have you read the appropriate chapter in the Reference Manual for your stm32? This is very detailed and complicated, for the simple reason that these timers are extremely powerful, and can be made to do many different things.

Looking at you code, I do not like the idea of waiting for the UIF bit TIM->SR to be set, and then waiting for it to be cleared. For example the section on upcounting modes has the text:

In addition, if the URS bit (update request selection) in TIMx_CR1 register is set, setting the UG bit generates an update event UEV but without setting the UIF flag (thus no interrupt or DMA request is sent).

The section on TIM1->SR says

Bit 0 UIF: Update interrupt flag
This bit is set by hardware on an update event. It is cleared by software.

0: No update occurred.
1: Update interrupt pending. This bit is set by hardware when the registers are updated:

–At overflow or underflow regarding the repetition counter value (update if repetition counter = 0) and if the UDIS=0 in the TIMx_CR1 register.

–When CNT is reinitialized by software using the UG bit in TIMx_EGR register, if URS=0 and UDIS=0 in the TIMx_CR1 register.

–When CNT is reinitialized by a trigger event (refer to Section 13.4.3: TIM1 slave mode control register (TIM1_SMCR)), if URS=0 and UDIS=0 in the TIMx_CR1 register.

So my reading is that while you have URS set, UIF might never happen.

TIM here only 16-bit so will have limited span.

Personally I'd keep the TIM in maximal mode and delta CNT measurement as this would be both thread safe and not have delays from repeated initialization. 

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

> RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

Is this SPL?

What's the value of SystemCoreClock?

Read out and check/post content of TIM registers.

JW