STM32F1 TIM Input Capture prescaler seems ignored, and OC match doesn’t reset counter — expected behavior?
Goal
-
Measure input signal frequency using Input Capture (IC).
-
Generate a regular waveform using Output Compare (OC) Toggle.
Problem 1 — IC prescaler appears to have no effect
I expected the IC prescaler to capture every Nth edge (e.g., DIV2 → every 2nd event) so that the measured tick delta would scale accordingly. However, regardless of ICPrescaler (DIV1/DIV2/DIV4/DIV8), the capture deltas (and computed frequency) are unchanged.
-
I found a similar discussion here (same symptom):
https://community.st.com/t5/stm32-mcus-products/input-capture-prescaler-does-not-work-as-expected-no-matter-what/td-p/176454
My configuration (summary):
-
Counter: up-counting, ARR = XXXX, PSC = XXXX
-
IC: rising edge, ICSelection = DIRECTTI, ICFilter = 0, ICPolarity = RISING
-
No slave mode (SMS = 000), no triggers, timer just free-running
-
ICPrescaler = TIM_ICPSC_DIV1 (works), then changed to DIV2/DIV4/DIV8 (register shows the change), but captured values don’t reflect prescaling
-
In debug I can see CCRy values updating and CCxIF asserted correctly
-
Frequency measured (from successive captures with overflow handling) matches the input when DIV1; unchanged when using DIV2/4/8
Questions (IC):
-
Under what exact conditions does the IC prescaler (CCxPS bits) take effect on STM32F1?
-
Does it require specific edge filters, input mapping (TIx/Indirect/Trig), or slave mode to be active?
-
-
Is the IC prescaler supposed to drop/interleave latching into CCR while still asserting CCxIF every edge, or should both be prescaled?
-
If the prescaler simply skips CCR latching but I compute deltas between successive captured values, should I explicitly divide by the prescale factor in software? (Right now I see no change in the captured deltas.)
Problem 2 — OC match does not reset the counter
When using OC Toggle mode, after a compare match the counter does not reset; the period of the output waveform is governed by ARR, not by the compare value CCR. I can see why (counter only resets at update/ARR), but then:
-
If I want a waveform whose period equals Δ between compare events, do I have to update CCR incrementally in the ISR (e.g., CCR += interval_ticks) so the next event is scheduled relative to the last compare rather than waiting for CNT to roll to ARR?
-
Is there any hardware mode on STM32F1 where a compare match can reset the counter automatically (without using One-Pulse or a slave-mode reset trigger)?
-
Is this behavior (no reset on compare) the general timer design across MCUs, or specific to STM32 F1?
What I tried (OC):
-
OC Toggle with ARR = LARGE, CCR = K → output toggles once per timer period at position K (as expected), overall frequency set by ARR.
-
Resetting CNT in the OC ISR works functionally but slows the output due to ISR latency/jitter (as expected).
-
PWM mode works as a regular waveform generator (ARR = period, CCR = duty), but I was exploring OC behavior specifically.
