cancel
Showing results for 
Search instead for 
Did you mean: 

TIMER Interrupt issue STM32

vbesson
Senior

Hello, 

I am facing an issue with my code on my STM32F411

I have a function that is starting a timer TIM5 

I want to be able to handle channel 1, Channel 2, Channel 3 interrupt on output compare no output

  uint32_t ticks = ms * 10U; /* 10 kHz tick -> 10 ticks per ms */
  if (ticks == 0) ticks = 1;


TIM5->CR1 = 0;
TIM5->CR2 = 0;
TIM5->DIER = 0;
TIM5->CCER = 0;
TIM5->CCMR2 = 0;  // Channel 3 and 4 CCMR register

// Set prescaler and auto-reload as needed
TIM5->PSC = 96;         // No prescaler
TIM5->ARR = 0xFFFF;    // Auto-reload max for full range

TIM5->CCMR2 &= ~TIM_CCMR2_CC3S;             // CC3S=00 output
TIM5->CCMR2 &= ~TIM_CCMR2_OC3M;             // Clear OC3M bits
TIM5->CCMR2 |= (0x3 << TIM_CCMR2_OC3M_Pos); // OC3M=011 toggle mode

// Enable Capture/Compare Channel 3 output (optional for toggling output pins)
TIM5->CCER |= TIM_CCER_CC3E;

// Enable interrupt on Capture/Compare 3 event
TIM5->DIER |= TIM_DIER_CC3IE;

// Enable TIM5 counter


  //TIM5->CR1 &= ~TIM_CR1_CEN;                                      // Stop timer while we change ARR/counter          
  TIM5->ARR = (uint32_t)(ticks - 1U)*10;                          // Set Auto-reload register
  TIM5->CCR3 = (uint32_t)(ticks - 1U)*10;                         // Channel 2 for marquee update
  TIM5->CNT = 0;
  //HAL_TIM_Base_Start_IT(&htim5);
  /* Enable update interrupt and start one-shot timer */
 //TIM5->CR1 |=  TIM_CR1_OPM;                                     // One pulse mode
  TIM5->DIER |= TIM_DIER_CC3IE;                                   // Enable interrupt on
  TIM5->CR1 |= TIM_CR1_CEN;                                       // Start the timer
  

 

I configured only Channel 3 

And this is my IRQ handler

 

void TIM5_IRQHandler(void){
  //log_info("A");
  if (TIM5->SR & TIM_SR_UIF){
    
    TIM5->SR &= ~TIM_SR_UIF;                              // Clear the overflow interrupt 
  } 
  else if (TIM5->SR & TIM_SR_CC1IF){                         // Pulse compare interrrupt on Channel 1
    TIM5->SR &= ~TIM_SR_CC1IF;  
    TIM1->CCER &= ~TIM_CCER_CC2NE;
    printf("i\n");
    flgSoundEffectActive=0;
    /* Disable timer and its update interrupt */
    //TIM5->CR1 &= ~TIM_CR1_CEN;
    /* Disable update interrupt using timer register (clear UIE in DIER) */
    //TIM5->DIER &= ~TIM_DIER_UIE;
    TIM5->DIER &= ~TIM_DIER_CC1IE;
                              // Clear the compare interrupt flag
  }
  else if (TIM5->SR & TIM_SR_CC2IF){
    TIM5->SR &= ~TIM_SR_CC2IF;
    flgUpdateMarquee=1;
    
    printf("h\n");
  }
  else if (TIM5->SR & TIM_SR_CC3IF){
    TIM5->SR &= ~TIM_SR_CC3IF;
    flgUpdateMarquee=1;
    printf("j\n");

  }
  else
    TIM5->SR = 0;
}

I received the 3 interrupt instead of only the Channel 3 

What do I need to change to be able start the timer5 only with a predifined channel 

 

thanks for your help

Vincent

 

3 REPLIES 3
TDK
Super User

Flags still get set even if the interrupt is not enabled. The IE bit enable the interrupt but the flag works the same.

If you don't want to handle the other flags in the interrupt handler, then don't check for them. Handle only the flag you care about.

Recommend not using if/else as you will be skipping flags. Handle all relevant flags on each pass.

 

> TIM5->SR &= ~TIM_SR_UIF;

Don't do this, it can clear other flags. Here is the correct way to clear only the UIF flag:

TIM5->SR = ~TIM_SR_UIF;

 

If you feel a post has answered your question, please click "Accept as Solution".

Ok thanks now I understand, but it means that I need to have another variable to define which channel is active on the IRQ Handler

Vincent

 

or check the IE flag to see which interrupt is enabled like HAL does.

If you feel a post has answered your question, please click "Accept as Solution".