Skip to main content
Graduate
April 27, 2025
Solved

STM32F303RE: only UART & TIM3 work; others (TIM2, TIM4, GPIO) cannot be configured

  • April 27, 2025
  • 2 replies
  • 646 views

Hi,

I'm working on an STM32F303RE project.
So far, only the UART and TIM3 are working properly.
I successfully configured TIM3 in PWM mode on 3 channels, and everything runs as expected. Project is build only on CMSIS libirary. 

void clock_config(void)
{
	RCC->CR |= RCC_CR_HSION;
	 while (!(RCC->CR & RCC_CR_HSIRDY));


	// RCC->CR |= RCC_CFGR_PLLSRC
	 RCC->APB1ENR |= RCC_APB1ENR_PWREN;

	 RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
	 RCC->CFGR|= RCC_CFGR_PPRE1_DIV2;
	 //PPL SOURCE MUX

	// RCC->CFGR |= RCC_CFGR_PLLMUL9;
	 RCC->CFGR |= (0x7 << RCC_CFGR_PLLMUL_Pos);
	 RCC->CR |= RCC_CR_PLLON;
	 while (!(RCC->CR & RCC_CR_PLLRDY));
	 RCC->CFGR |= RCC_CFGR_SW_PLL;
	 while(!(RCC->CFGR & RCC_CFGR_SWS));
	 RCC -> AHBENR |= RCC_AHBENR_GPIOAEN;
	 RCC -> AHBENR |= RCC_AHBENR_GPIOBEN;

}
void TIM3_IRQHandler(void)
{


	 if (TIM3->SR & TIM_SR_CC1IF)
	 {
	 TIM3->SR &= ~TIM_SR_CC1IF; // Wyczyść flagę
	 GPIOA->ODR ^= GPIO_ODR_6; // Przełącz PA6 (D12) z
	 }

}
void TIM2_IRQHandler(void)
{
		//PA0 a0

	 if (TIM2->SR & TIM_SR_CC1IF)
	 {
	 TIM2->SR &= ~TIM_SR_CC1IF; // Wyczyść flagę
	 GPIOA->ODR ^= GPIO_ODR_0; // Przełącz A0 y
	 }

}
void TIM4_IRQHandler(void)
{


	 if (TIM4->SR & TIM_SR_CC1IF)
	 {
	 TIM4->SR &= ~TIM_SR_CC1IF; // Wyczyść flagę
	 GPIOA->ODR ^= GPIO_ODR_11; // Przełącz (PA11) x
	 }

}
void DIRconfig_x(void)
{

		GPIOB -> MODER |= GPIO_MODER_MODER6_0;
		GPIOB -> MODER &= ~(GPIO_MODER_MODER6_1);
		GPIOB -> OTYPER &= ~(GPIO_OTYPER_OT_6);
		GPIOB -> OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR6);
		GPIOB -> PUPDR &= ~(GPIO_PUPDR_PUPDR6);

}

void configure_z_TIMER3(void)
{
	 //PA6:D12 CH1

	RCC -> APB1ENR |= RCC_APB1ENR_TIM3EN;


	TIM3->PSC = 1999; //72mghz 32??
	TIM3->ARR = 19; //PA6
 TIM3->CR1 |= TIM_CR1_ARPE;
	GPIOA->MODER |= GPIO_MODER_MODER6_0;
	TIM3->CNT=0;

	TIM3->CCMR1 |= (TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1); //outputcomare config
 TIM3->CCER |= TIM_CCER_CC1E;
	//interuptTIM3
	TIM3 -> DIER |= TIM_DIER_UIE;
	TIM3 -> DIER |= TIM_DIER_CC1IE;
	NVIC_SetPriority(TIM3_IRQn, 1);
	NVIC_EnableIRQ(TIM3_IRQn);
	TIM3->CR1|= TIM_CR1_CEN;
}
void configure_y_TIMER2(void)
{
		//PA0:A0 AF1

	RCC -> APB1ENR |= RCC_APB1ENR_TIM2EN;


	TIM2->PSC = 7199; //72mghz 32??
	TIM2->ARR = 19;
 TIM2->CR1 |= TIM_CR1_ARPE;
	GPIOA->MODER |= GPIO_MODER_MODER0_0;
	GPIOA->AFR[0] |= ((0x1 << GPIO_AFRL_AFRL0_Pos));
	TIM2->CNT=0;
	TIM2->CCMR1 |= (TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1); //outputcomare config
 TIM2->CCER |= TIM_CCER_CC1E;
	//interuptTIM3
	TIM2 -> DIER |= TIM_DIER_UIE;
	TIM2 -> DIER |= TIM_DIER_CC1IE;
	NVIC_SetPriority(TIM2_IRQn, 3);
	NVIC_EnableIRQ(TIM2_IRQn);
	TIM2->CR1|= TIM_CR1_CEN;

}
void configure_x_TIMER4(void)
{
	 //PA11:D12

	RCC -> APB1ENR |= RCC_APB1ENR_TIM4EN;


	TIM4->PSC = 7199; //72mghz 32??
	TIM4->ARR = 19; //PA6
 TIM4->CR1 |= TIM_CR1_ARPE;
	GPIOA->MODER |= GPIO_MODER_MODER11_0;
	TIM1->CNT=0;

	TIM4->CCMR1 |= (TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1); //outputcomare config
 TIM4->CCER |= TIM_CCER_CC1E;
	//interuptTIM3
	TIM4 -> DIER |= TIM_DIER_UIE;
	TIM4 -> DIER |= TIM_DIER_CC1IE;
	NVIC_SetPriority(TIM4_IRQn, 2);
	NVIC_EnableIRQ(TIM4_IRQn);
	TIM4->CR1|= TIM_CR1_CEN;
}
int main(void)
{

	clock_config();
	SysTick_Config(72000000/1);
	config_UART();
	configure_z_TIMER3();
	configure_y_TIMER2();
	configure_x_TIMER4();
	DIRconfig_x();





	USART2->TDR = 'D';
	while (!(USART2->ISR & USART_ISR_TXE)) { } // Czekaj na opróżnienie bufora
	while (!(USART2->ISR & USART_ISR_TC)) { } // Czekaj na zakończenie transmisji

	while(1)
	{



	}
}

However, when I try to configure other peripherals (for example TIM2, TIM4, or GPIOs on a different port), they do not seem to initialize properly.

When stepping through the debugger, it looks like the code just skips the configuration functions — no registers are updated, no changes take effect.

All peripherals (TIM2, TIM3, TIM4, UART2) are connected to the same APB1 bus.

Summary of symptoms:

  • TIM3 works correctly in PWM mode and  on 3 channels.

  • UART works correctly.

  • TIM2, TIM4 configuration fails — registers stay default after supposed initialization.

  • GPIOs on ports other than A also cannot be configured — the debugger simply skips the initialization code.

I'm wondering if this could be a clock enable issue (RCC settings?) or something else.

But when I configure 3 channels for TIM3, I have to configure also GPIO output for portB and it configures. So I assume it can be, work because off  brought clock signal.

Any help would be appreciated!

    This topic has been closed for replies.
    Best answer by TDK

    It's probably stuck in the first timer interrupt. You enable UIE but don't check for or clear UIF in the IRQ handler, so it enters it repeatedly. Either don't set UIE or check for and clear UIF in the interrupt.

    Don't read-modify write to clear flags, just write the flag you want to clear to 0.

    TIM3->SR = ~TIM_SR_CC1IF; // clear CC1IF only
    
    TIM3->SR = ~TIM_SR_UIF; // clear UIF only

    2 replies

    TDKAnswer
    Super User
    April 28, 2025

    It's probably stuck in the first timer interrupt. You enable UIE but don't check for or clear UIF in the IRQ handler, so it enters it repeatedly. Either don't set UIE or check for and clear UIF in the interrupt.

    Don't read-modify write to clear flags, just write the flag you want to clear to 0.

    TIM3->SR = ~TIM_SR_CC1IF; // clear CC1IF only
    
    TIM3->SR = ~TIM_SR_UIF; // clear UIF only
    Graduate
    May 1, 2025

    @TDK  You are right thanks for help. Everything works fine.

    Super User
    April 28, 2025

    Besides what @TDK wrote above,  if running at higher frequencies, you need to set FLASH waitstates.

    JW

    Graduate
    May 1, 2025

    @waclawek.jan Thanks for advice. I set it.