xtrinch
xtrinch

Reputation: 2291

1s timer on STM32F769I-DISCO

I'm trying to set up a 1s led blink on STM32F69I discovery board with STM32 HAL libraries. I've set up my timer the following way:

__TIM2_CLK_ENABLE();
s_TimerInstance.Init.Prescaler = (216000);
s_TimerInstance.Init.CounterMode = TIM_COUNTERMODE_UP;
s_TimerInstance.Init.Period = (1000);
s_TimerInstance.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
s_TimerInstance.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&s_TimerInstance);
HAL_TIM_Base_Start(&s_TimerInstance);

And then I toggle my LED's with:

int main() {
    for (;;) {
        int timerValue = __HAL_TIM_GET_COUNTER(&s_TimerInstance);
        if (timerValue == 800)
            HAL_GPIO_WritePin(GPIOJ, (LED_GREEN | LED_RED), GPIO_PIN_SET);
        if (timerValue == 1000)
            HAL_GPIO_WritePin(GPIOJ, (LED_GREEN | LED_RED), GPIO_PIN_RESET);
        }
}

The MCU clock is supposed to be 216 mHz. My logic is, that if I set up the prescaler to 216000, it will mean that my timer will make 216000000/216000 = 1000 increments each second. Meaning, if I set my period to 1000, my LED's should blink every one second. However, they blink once like every 1.1-1.2 seconds.

Is my understanding of the prescaler and period completely wrong or what am I missing?

EDIT: 216000-1 && 1000-1 doesn't make any visible difference. In all honesty I am a complete beginner at this, so I am confirming this by seeing it differ from a normal "wall" clock, because I have no idea how to debug this. There is no rest of the code, this is all there is. I am running on 216mHz because it says on the STM website that the STM32F769I's MCU runs on 216, so I assumed my timer is also. Couldn't really decipher anywhere if that is the case, or not. I also didn't find any setting in the timer struct where I could set the clock freq.

Upvotes: 1

Views: 1100

Answers (2)

kkrambo
kkrambo

Reputation: 7057

The STM32F769NI can run at a maximum of 216 MHz but on reset it selects the 16 MHz internal RC oscillator by default. See section 2.15 of the datasheet.

TIM2 has a 16-bit prescaler. See section 2.23.2 of the datasheet.

216000 (0x34BC0) is too large to fit in the 16-bit prescaler. In your program it is getting truncated to 0x4BC0 or 19392.

16 MHz / 19392 = 825.1 Hz or 0.001212 ticks per second.

0.001212 ticks per second multiplied by 1000 ticks = 1.212 seconds.

Change your prescaler to (16000 - 1) since your clock is actually running at 16 MHz, not 216 MHz.

Upvotes: 3

0___________
0___________

Reputation: 68023

Try this very complicated code instead:

TIM2 -> PSC = 21600 - 1;
TIM2 -> EGR = TIM_EGR_UG;
TIM2 -> CR1 |= TIM_CR1_CEN;

while(1) {
    if(TIM2 -> CNT >= 10000) 
    {
        TIM2 -> CNT = 0;
        ToggleLed();
    }
}

Replace ToggleLed with your actual code (which toggles the LED of course)

Upvotes: 0

Related Questions