STM32 Timer Input Capture: Misurare Frequenza e Duty Cycle a Livello di Registro
Misurare la frequenza e il duty cycle di un segnale esterno egrave; uno dei compiti embedded piugrave; comuni — sensori RPM, linee di feedback PWM, impulsi encoder e debug temporale di protocolli richiedono tutti una cattura accurata del periodo. La modalitagrave; input capture dei timer STM32 permette di timestampare i fronti con risoluzione del timer. Questo articolo illustra la configurazione a livello di registro, copre il metodo a doppio canale per la misura simultanea di frequenza e duty cycle, e affronta la gestione dell'overflow indispensabile in ogni firmware di produzione.
Come funziona l'input capture
Ogni timer general-purpose STM32 (TIM2–TIM5, TIM9–TIM17 su F4; TIM2–TIM8, TIM15–TIM17 su G4) dispone di canali capture/compare. In modalitagrave; input capture, il canale rileva un fronte programmato sul suo pin di ingresso (TI1, TI2) e cattura il valore corrente del contatore nel registro di capture (CCR). La sequenza base:
- Il contatore TIMx_CNT scorre liberamente, tipicamente alla frequenza di clock del timer divisa dal prescaler PSC.
- Un fronte sul pin di ingresso attiva una capture: TIMx_CCRx riceve il valore corrente di CNT.
- Il flag CCxIF in TIMx_SR si attiva; puograve; essere generato un interrupt o una richiesta DMA.
- Leggendo capture successive e calcolando la differenza, si ottengono il periodo e la larghezza d'impulso del segnale.
Il percorso di ingresso include filtraggio programmabile, selezione della polaritagrave; del fronte e un prescaler opzionale (ogni 2°, 4° o 8° fronte). Questi sono configurati in TIMx_CCMR1 (canali 1, 2) o TIMx_CCMR2 (canali 3, 4).
Misura a canale singolo: solo frequenza
Con un canale configurato sul fronte di salita, ogni capture fornisce un timestamp di fronti di salita consecutivi. La differenza tra due capture successive egrave; il periodo del segnale in tick del timer.
f_segnale = clock_timer / (PSC + 1) / tick_periodo
Funziona bene per segnali stabili ma non puograve; misurare il duty cycle.
Configurazione registri: TIM2 canale 1, fronte di salita, STM32F401
// Clock TIM2 = 84 MHz, PSC = 83 -> 1 MHz tick
TIM2->PSC = 83;
TIM2->ARR = 0xFFFF;
TIM2->CCMR1 = TIM_CCMR1_CC1S_0; // IC1 su TI1
TIM2->CCER = TIM_CCER_CC1E; // fronte di salita
TIM2->DIER = TIM_DIER_CC1IE;
TIM2->CR1 = TIM_CR1_CEN;
Misura a doppio canale: frequenza e duty cycle
Per misurare sia frequenza che duty cycle servono due capture per periodo: una sul fronte di salita (timestamp A), una sul fronte di discesa (timestamp B). Il tempo alto = B - A, il periodo = prossimo_salita - A. L'architettura dei timer STM32 supporta questa modalitagrave; attraverso due canali sullo stesso ingresso:
- Canale 1 (IC1): mappato su TI1, fronte di salita — cattura l'inizio dell'impulso alto.
- Canale 2 (IC2): mappato su TI1, fronte di discesa — cattura la fine dell'impulso alto.
Si configura tramite TI1FP1 (salita) e TI1FP2 (discesa) nel registro CCMR1. Entrambi i canali condividono lo stesso pin, ma ciascuno ha la propria polaritagrave; in CCER.
// CCMR1: IC1 su TI1, IC2 su TI1
TIM2->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
// CCER: CC1 salita, CC2 discesa
TIM2->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC2P;
TIM2->DIER = TIM_DIER_CC1IE | TIM_DIER_CC2IE;
TIM2->CR1 = TIM_CR1_CEN;
Gestione dell'overflow del timer (rollover 16-bit)
I timer 16-bit eccedono ogni 65536 tick. Se il periodo del segnale supera questo valore, il calcolo del delta si rompe. La soluzione egrave; contare gli overflow nell'interrupt di update ed estendere il valore a 32 bit:
static volatile uint32_t conteggio_overflow = 0;
void TIM3_IRQHandler(void) {
if (TIM3->SR & TIM_SR_UIF) {
TIM3->SR = ~TIM_SR_UIF;
conteggio_overflow++;
}
}
uint32_t now_ext = (conteggio_overflow << 16) | TIM3->CCR1;
Filtraggio d'ingresso e reiezione del rumore
I segnali reali presentano glitch. Il filtro digitale programmabile STM32 sull'ingresso TIx si configura nei bit ICxF di CCMR1/CCMR2. Il filtro campiona a f_DTS e attesta un fronte solo dopo N campioni concordi.
- ICF = 0b0000: nessun filtro.
- ICF = 0b0011: N = 4 campioni — rigetta glitch brevi.
- ICF = 0b1001–1111: N = 8 campioni a f_DTS/8.
Per feedback PWM su controllo motori, uso ICF = 4 o 5 (N = 6–8 a f_DTS).
Esempio pratico: misura di un segnale PWM servo su STM32F401
Un PWM servo RC standard ha 50 Hz (20 ms) con impulso 1–2 ms. Con PSC = 83 e 84 MHz, il tick egrave; 1 MHz: periodo 20000 tick, impulso 1000–2000 tick. TIM3 16-bit egrave; sufficiente.
Problemi comuni
Frequenza di clock del timer errata
Il clock del timer non egrave; sempre SYSCLK. Su F4, se APB1 prescaler non egrave; 1, i timer APB1 girano a 2 x clock APB1.
Rimappatura del canale (TI1 vs TI2)
Il doppio canale (IC2 su TI1) funziona solo se CCMR1 CC2S = 01. Se CC2S = 10 o 11, il canale 2 passa a TI2 o TRC.
Overflow 16-bit su segnali lenti
Un segnale a 1 Hz a 1 MHz necessita 1000000 tick. Su F4, TIM2 e TIM5 sono 32-bit. Su G4, solo TIM2.
Sequenza fronti mancante
Se la scheda viene collegata a metagrave; ciclo, il primo fronte potrebbe essere di discesa. Aggiungere sincronizzazione: ignorare le prime 2–3 capture.
Checklist pratica
- ☐ Frequenza clock timer verificata dai prescaler APB.
- ☐ PSC scelto per il periodo massimo atteso.
- ☐ CCMR1 CCxS corretti: CC1S=01, CC2S=01.
- ☐ CCER polaritagrave; corretta: CC1P=0, CC2P=1.
- ☐ Filtro ICxF impostato.
- ☐ Overflow ISR abilitata per timer 16-bit.
- ☐ Sincronizzazione fronti all'avvio.
- ☐ GPIO in modalitagrave; AF.
- ☐ Test in loopback con PWM noto.
Come lo affronterei su un progetto cliente
Scrivo un modulo di misura con macchina a stati, coda risultati e struttura di configurazione. L'ISR egrave; minimale — scrive capture in un ring buffer — mentre il calcolo di frequenza e duty cycle gira nel contesto applicativo. La configurazione vive in bsp_timers.h; il cliente modifica la tabella, non l'ISR.
Fonti e approfondimenti
- Manuale di Riferimento STM32F401 (RM0368) — Capitolo 14.
- Manuale di Riferimento STM32G4 (RM0440) — Capitolo 24.
- Nota Applicativa ST AN4776 — Ricettario timer general-purpose.
- Nota Applicativa ST AN4013 — Panoramica timer cross-series.
- Nota Applicativa ST AN4300 — Input capture per frequenza e duty cycle.
- STM32CubeF4 — Esempio TIM_InputCapture.

Comments
Have comments? Send me an email.