cancel
Showing results for 
Search instead for 
Did you mean: 

Blinking LED with TIM1(STM32F3DISCOVERY) through registers

Mhass.12
Associate II

I'm working on a project with an STM32F3 MCU and I've been running some test-code on register level, but I have had trouble with the timer and making pin PE8 blink. The result from this code is that it will turn the LED on but it won't toggle the pin so the LED isn't blinking. The following is the code that I'm running on keil uvision:

#include "stm32f303xc.h"
#include "system_stm32f3xx.h"
 
void CLOCK_config(void);
void GPIO_config(void);
void TIM1_init(void);
 
void CLOCK_config(void){
	//ENABLE HSI CLOCK
	RCC->CR |= RCC_CR_HSION;
	while(!(RCC->CR & RCC_CR_HSIRDY));
	//ENABLE TIM1
	RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
	//CONFIGURE CLOCK FOR PORTE
	RCC->AHBENR |= RCC_AHBENR_GPIOEEN;
}
 
void GPIO_config(void){	
	//SET GPIOE8 AS OUTPUT MODE
	GPIOE->MODER |= (1<<0x10U);
	//SET GPIOE8 AS MEDIUM SPEED
	GPIOE->OSPEEDR |= (1<<0x10U);
}
 
void TIM1_init(void){
	//SET PRESCALER
	TIM1->PSC |= 65000;
	//SET RELOAD COUNTER VALUE
	TIM1->ARR |= 100;
	//ENABLE TIMER
	TIM1->CR1 |= TIM_CR1_CEN;
}
 
int main(){
	CLOCK_config();
	GPIO_config();
	TIM1_init();
	
	while(1){
		if(TIM1->SR & TIM_SR_UIF){
			TIM1->SR &= ~TIM_SR_UIF;
			GPIOE->BSRR ^= (1<<0x8U);
		}
	}
}

Is there something that I'm missing, because I thought that I had configured the peripherals correctly, although I'm a bit unsure about how the system clock should be configured? I wanted to keep it simple so I'm hoping for a solution that doesn't involve interrupts or changing the timer to the generic or basic timers.

4 REPLIES 4
TDK
Guru

> TIM1->SR &= ~TIM_SR_UIF;

If you want to only clear UIF, only write that bit as zero.

> GPIOE->BSRR ^= (1<<0x8U);

BSRR is write only. If you want to toggle a bit, use ODR, or use BSRR correctly (lower 16 bits to set, upper 16 bits to reset) to do so atomicly.

TIM1->SR = ~TIM_SR_UIF;
GPIOE->ODR ^= (1<<0x8U);

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

You should generally avoid using RMW operations (read-modify-write, i.e. |= &= ^= in C) except where strictly necessary.

The issue with clearing TIMx_SR.UIF by RMW is in this case just bad practice, not the one that causes the problems - but XORing BSRR is what causes malfunction, as TDK said above.

There's one more such "fatal" issue there - TIM1->ARR |= 100; as TIMx_ARR is initialized to 0xFFFF leaves ARR to be 0xFFFF, which is not what you want.

Also note, that while TIMx_PSC is by default zero so |= while not needed (and a bad practice too) will change it to the expected value, it will get "active" only after the next Update event (counter "rollover"), as prescaler is unconditionally preloaded. The net result is, that the first timer will be significantly shorter. Not something you'll particularly notice with a blinking LED, but you should know about it too.

JW

Thank you for the reply, the LED is still not blinking but I think I'm getting closer to an answer with this

Thank you for the reply, I appreciate it. I will try to initialize more accurately.