2016-09-29 04:02 PM
I am trying to set up TIM2 as a free-running microsecond counter; no interrupts or anything fancy. Basically, I want to be able to read the 32-bit CNT register and get microseconds; this is very handy for fine-grained delays and timing for hardware related issues. The SystemCoreClock value is set to 72,000,000, which is correct; my FreeRTOS kernel is running at 1,000 Hz based off that, and if I toggle an LED every 500 (FreeRTOS) ticks, it blinks correctly at 1 Hz (on 0.5 seconds, off 0.5 seconds). All is fine.
However, when I program TIM2 with a prescaler of (72 - 1), which should cause it to count at 1 MHz, it counts at half that rate; I verified this by noting the difference in TIM2.CNT from one second to the next, and the difference is 500,000! Here is my code:TIM_TimeBaseInitTypeDef tinit;
TIM_TimeBaseStructInit(&tinit);
uint16_t prescaler = (uint16_t) ((SystemCoreClock ) / 1000000) - 1;
tinit.TIM_Prescaler = prescaler;
TIM_TimeBaseInit(TIM2, &tinit);
TIM_Cmd(TIM2, ENABLE);
I have verified that the system clock is being set correctly, multiplying my 12 MHz HSE by 6 to get to 72 MHz; besides, FreeRTOS is using it to correctly set up a 1000 Hz tick for its use. What am I missing that results in half the frequency I desire?
Thanks!
2016-09-29 05:52 PM
You should look at the APB1 clock divisor. DIV4 would get you DIV2 to the TIMCLK, see Clock Tree
You can check internal clocks via the MCO pin (PA8) There is a 32-bit cycle counter at the CPU rate, see DWT_CYCCNT