# stm32f407 timer setup stm32duino

I'm trying to understand how timers work in this board. I want to make a simple led blink after X amount of microseconds and then keep the led on for X amount of microseconds

stimer_t _timer;

void setup() {

_timer.timer = TIM3; //84Mhz

TimerHandleInit(&_timer, 60000, ??);
attachIntHandle(&_timer,TimerTestIsr);
}

volatile bool isOn = false;

static void TimerTestIsr(stimer_t *timer) {

UNUSED(timer);

//just to mesure time
previusTime = nowTime;
nowTime = micros();

if (isOn == false) {
digitalWrite(LedPin, HIGH);
isOn = true;
setTimerCounter(&_timer,(65535 - 1234)); //so the counter will start from 64301 till 65535 is 1234
}
else {
//on the next trigger it will shutdown the led
digitalWrite(LedPin, LOW);
isOn == false;
}
}


As I understand the timer can go up to 65535 and then overflows to trigger the interrupt. But I'm strugling to understand how to set the prescaler for 1us or 1ms or 1sec. So what I want to do exactly is set the prescaler so every time the counter increase its 1us or what ever time I want. So if the counter is 50000 I want this to be a delay of 50000us.

• Your example is so wrong, that is diffucult to understand what you are trying to acheive. Do you want to use milis() instead? What's the purpose of using 1us timebase to get 50ms? – Marko Buršič Mar 14 at 16:32
• well inside my loop() i want to generate 2 random numbers one number will be the number to wait before i trigger the interrupt to turn on the led and the second number is to trigger the interrupt again to turn off the led so it will be the duration that the led will stay on.And i want this to run forever – Irf32 Mar 14 at 16:39
• random numbers - do you mean arbitrary numbers instead? Is the interrupt a must? Is the microsecond precision a must? You can implement a timer function using milis() and then you can have many of them without using interrupts, with a cost that their precision are subject to scan time of the entire program. – Marko Buršič Mar 14 at 20:24
• well im trying to control a fuel pump and i need to trigger a relay for it after some time and keep it on for some time then close it and repeat time must be uS and main program will do some calculations by reading some sensors – Irf32 Mar 14 at 23:34

I think I solved that, but I had to mix some functions because for some reason I wasn't able to trigger the interrupt by setting TIM registers only

uint16_t returnPeriod(uint16_t prescaler, unsigned long time, uint8_t mhz) {
return (time) / ((1000000 / mhz) * 0.00001) / prescaler;
}

const byte LedPin = PG7;

stimer_t timerx;

void setup() {

pinMode(LedPin, OUTPUT);
//digitalWrite(LedPin, HIGH);
//NVIC_EnableIRQ(TIM5_IRQn); this is not working for some reason i have to use TimerHandleInit &  attachIntHandle
timerx.timer = TIM5;
TimerHandleInit(&timerx, 0, 0);
TIM5->PSC = 10000;
attachIntHandle(&timerx, tim5TestInterrupt);

}

volatile bool enableFlag = false;
unsigned long time_now = 0, time_before = 0;

void loop() {
time_before = time_now;
time_now = micros();

if (enableFlag == false) { //make sure we enable after timeout
TIM5->ARR = returnPeriod(TIM5->PSC, 5000000, 84); //wait 0.5seconds
TIM5->CNT = 0;
TIM5->CR1 |= TIM_CR1_CEN;
}

while ((TIM5->CR1 & TIM_CR1_CEN)) { // wait till timeout aka timer disabled

}
if(Serial){
Serial.println(time_now-time_before); //it should print delay time + timeout time
}
}

void tim5TestInterrupt(stimer_t* st32timer) {

if (enableFlag == false) {
enableFlag = true;
digitalWrite(LedPin,HIGH);

TIM5->ARR = returnPeriod(TIM5->PSC, 30000000, 84); //timeout after 3 seconds
TIM5->CNT = 0;
}
else {
enableFlag = false;
digitalWrite(LedPin, LOW);

TIM5->CR1 &= ~TIM_CR1_CEN; //disable timer

}
}