Timer0 è una periferica presente in tutti i PIC a 8 bit, con struttura analoga e compatibile per quanto riguarda il
software, anche se esistono alcune varianti della forma di base.
Le caratteristiche di questo timer sono le seguenti:
- contatore a 8 bit: come solito per Microchip, si tratta di un contatore "a
crescere", cioè che conta in salita da 00 a FFh (255 decimale),
incrementando di 1 ad ogni impulso del clock e che va in overflow al 256esimo
impulso.
- clock interno o esterno: è possibile contare impulsi derivati
dall' oscillatore interno o da una sorgente esterna collegata ad un pin.
- fronte del clock programmabile: è possibile programmare il fronte
di commutazione del livello del segnale di ingresso per cui il contatore
avanza.
- prescaler 2/4/8/16/32/64/128/256: il prescaler divide per il
fattore indicato il segnale di ingresso. E' condiviso con il modulo WDT.
- sorgente di interrupt non periferico: in generale, il TIMER0 è
fonte di interrupt non periferico, abilitabile da programma.
I registri, le funzioni dei bit di controllo e le label relative sono identiche per i
PIC Base e Mid:
questo fa si che una sezione di sorgente
che riguarda il TIMER0 possa essere portata da un processore all' altro
senza alcuna modifica, in quanto opera in modo eguale su tutti.
Nei PIC18F le funzioni di TIMER0 si discostano di poco, con la
variazione
principale dovuta al registro di conteggio programmabile a 8/16 bit. In ogni
caso, i default al POR fanno si che la struttura, anche in questo caso, sia
compatibile.
Questo è un
notevole vantaggio, dato che non è necessario imparare per ogni processore una
diversa gestione del TIMER0.
Vediamo qualche dettaglio.
TIMER0 nella versione base (Baseline e Midrange)
Per comprendere il funzionamento del timer, utilizziamo le caratteristiche
della struttura di base. Nella maggioranza dei PIC 10/12/16 il Timer0 ha questo diagramma a blocchi
tipico:
Sono possibili alcune variazioni delle caratteristiche base:
- clock: In
alcuni PIC dotati di comparatore, l' ingresso di conteggio può essere anche
collegato all' uscita del comparatore (es. PIC10F204/206).
- sorgente di interrupt : Nei Baseline questa opzione non è disponibile, mancando la funzione di interrupt.
In tutti i casi, l' uso di Timer0 dipende da tre registri:
- 1 registro di conteggio TMR0
- 1 registro di controllo OPTION
- 1 registro di gestione dell' interrupt INTCON (solo Mid-range)
Il conteggio viene eseguito in un registro apposito a 8 bit, TMR0
, che è accessibile in lettura e scrittura.
- Il registro di conteggio parte da 0 e incrementa ad ogni
impulso di clock.
- Il contenuto del registro aumenta sino a FFh (255 decimale).
- Al successivo impulso (duecentocinquantaseiesimo), il contatore va in overflow e riprende a
contare a partire da 00
Come per gli altri timer/counter, una volta raggiunto l' overflow si determinano
le seguenti azioni:
- dove disponibile il registro INTCON, viene settato un flag di interrupt
TMR0IF.
Questo flag resta settato fino a che non è cancellato da programma
- se sono stati abilitati i bit TMR0IE e GIE, si genera una
richiesta di interrupt.. Non occorre che sia abilitato anche PEIE perchè
si tratta di un interrupt non-periferico.
Il clock di conteggio può essere derivato da diverse fonti:
- dal clock del processore, Fosc/4. Il bit T0CS
(Timer0 Clock Select) a livello basso, in OPTION_REG
, provvede alla selezione. Il bit PSA (PreScaler Assignment)
a livello 1 esclude il pre divisore del clock
Il segnale di conteggio viene sincronizzato con il clock interno e inviato
al registro contatore.
Se occorre una pre divisione del segnale da conteggiare, il bit PSA a
livello 0 inserisce il prescaler, il cui valore è determinato dai bit PS2:0.
Il conteggio può essere anche riferito ad un segnale esterno:
- il clock esterno arriva attraverso il pin T0CKI (Timer0
ClocK Input). Tipicamente T0CKI corrisponde a
RC0 o GP2 (per i
pic10F). Da notare che, selezionando con il bit T0CS a livello 1
nell' OPTION_REG la scelta del clock
esterno, essa assegna automaticamente la funzione di ingresso al pin sovra
passando una eventuale selezione diversa nel registro di direzione TRIS.
Come in precedenza, PSA determina se il segnale passa o meno attraverso il
predivisore.
Da notare la funzione del bit T0SE (Timer0 Source
Edge), sempre in OPTION_REG,
che permette la scelta del fronte di commutazione di livello del segnale sul
pin T0CKI. Si tratta di un gate XOR
che agisce come inverter.
Si può così selezionare il fronte di salita o di discesa.
Nei Base e Mid il Timer0 è sempre attivo, ovvero non dispone
di bit di accensione/spegnimento.
Questo vuol dire che, fino a quando è presente un clock, il registro
di conteggio sarà incrementato. |
Occorre tenere presente questo aspetto del funzionamento del timer,
importante quando esso viene usato ripetitivamente per generare periodi o
cadenze di tempo.
Il prescaler
Il prescaler ha la funzione di dividere il clock in ingresso, sia che provenga dall' oscillatore
interno, sia che provenga dal pin T0CKI; si
tratta di un ripple counter che divide per numeri pari
(2/4/8/16/32/64/128/256). Così, il rapporto 1:8 indica che il prescaler
invierà al contatore un impulso ogni 8 in ingresso. La scelta del valore è effettuata con i bit PS2:0
dell' OPTION_REG.
Se non si desidera alcuna divisione del clock, il prescaler non va assegnato; in
tal caso il rapporto è 1:1, ovvero il segnale di conteggio non sarà diviso in
alcun modo.
Una particolarità tipica di questo modulo è che il prescaler è in
comune con il WDT e quindi il bit PSA è, in sostanza, uno switch che
commuta il prescaler o al modulo del watchdog o al timer; non è quindi
possibile averlo per entrambi contemporaneamente.
Per comprendere meglio la cosa, prendiamo un diagramma semplificato del
complesso TIMER0/Prescaler/WDT
La chiave è il bit PSA. A livello 0 instrada il segnale di
ingresso del conteggio attraverso il prescaler (percorso verde), mentre il
segnale del WDT viene passato direttamente (percorso blu).
Per contro, se il valore assegnato a PSA
è 1, sarà il
segnale del WDT ad essere trattato dal prescaler (percorso blu), mentre
quello del conteggio perviene direttamente al TMR0.