Il timer interno



Il TIMER0 e' un dispositivo interno al microcontrollore in grado di assolvere alla duplice funzione di contatore e temporizzatore. Le due modalita' sono mutualmente esclusive e possono essere scelte via software. In ogni caso il modulo e' ad 8 bit, cio' significa che e' solo in grado di contare in step di 1 unita'  e ripetere ciclicamente i valori nell'intervallo da 0 a 255. Al TIMER0 e' associato un prescaler in grado di rallentare la velocita' di incremento dei valori in 8 possibili modalita' (1:2, 1:4, 1:8, 1:16, 1:32, 1:64, 1:128, 1:256). Inoltre, se si vuole, e' possibile impostare il modulo in maniera tale da produrre un interrupt ogni volta che si ha un overflow del TIMER0, cioe' ogni volta che il modulo passa dal valore 255 (0xFF) a 0 (0x00). Al TIMER0 e' associato un registro, il TMR0 (mappato nel banco 0 alla locazione di memoria 0x01); in questo registro e' possibile leggere lo stato attuale di avanzamento del contatore oppure impostarne il valore.



Modalita' temporizzatore o contatore


Il TIMER0 funziona in due modalita': temporizzatore o contatore. Nella prima il TIMER0 si incrementa ad ogni istruzione (questo in assenza di prescaler, altrimenti secondo il rapporto imposto). Il valore del registro TMR0 e' impostato a 0 per default, ma puo' essere modificato in qualsiasi momento tramite operazioni di scrittura.
Per selezionare la modalita' temporizzatore occorre impostare a 0 il bit T0CS del registro OPTION_REG.
Veniamo ora alla modalita' contatore. In questa modalita' il TIMER0 si incrementa ad ogni rising-edge o falling-edge del segnale applicato sul pin RA4/T0CKl; la modalita' di incremento (rising o falling-edge) e' selezionata impostando in maniera opportuna il bit T0SE del registro OPTION_REG (T0SE=0 per il rising-edge, T0SE=1 per il falling-edge). T0CS a 1 imposta la modalita' contatore.


Generazione dell'interrupt dal TIMER0


Ogni volta che il TIMER0 passa dal valore 255 (0xFF) a 0 (0x00) viene lanciata una interruzione che automaticamente setta ad 1 il bit T0IF del registro INTCON. L'interrupt puo' essere inibito settando a 0 il bit T0IE. T0IF deve necessariamente essere riportato a 0 dall'eventuale routine di gestione dell'interrupt affinche' possa verificarsi un nuovo interrupt.



Prescaler


Il prescaler e' un modulo per "rallentare" la frequenza di aggiornamento del TIMER0 tramite 8 fattori di divisione prestabiliti. Il prescaler puo' essere assegnato al TIMER0 oppure (in maniera mutualmente esclusiva) al Watch-Dog interno (il Watch-Dog e' un modulo aggiuntivo del microcontrollore spiegato piu' avanti nella guida). Il bit PSA del registro OPTION_REG determina a chi associare il prescaler (al TIMER0 con PSA=0 oppure al Watch-Dog con PSA=1). I tre bit PS0,PS1 e PS2 determinano una tra gli 8 possibili rapporti di divisione di frequenza cioe' 1:2, 1:4, 1:8, 1:16, 1:32, 1:64, 1:128, 1:256. Ovviamente se il prescaler non viene assegnato al TIMER0 (cioe' PSA=1) otteniamo automaticamente un rapporto di divisione di 1:1.
Quando il prescaler e' associato al TIMER0, ogni istruizione che vada a modificare il registro TMR0 (ad esempio, CLRF 0x01, MOVWF 0x01, BSF 0x01,3 etc...) comporta automaticamente il reset a 0 dei tre bit PS0,PS1 e PS2.
Per finire, nella figura seguente sono mostrati i collegamenti interni che collegano il prescaler al TIMER0 e al Watch-Dog: