2025-11-18 10:37 AM
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
2025-11-18 10:56 AM - edited 2025-11-18 10:57 AM
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;
2025-11-18 11:00 AM
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
2025-11-18 11:39 AM
or check the IE flag to see which interrupt is enabled like HAL does.