Reputation: 2291
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
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
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