by deluca » 28 Sep 2012, 11:43
paride22,
al calcolo si toglie 1 perchè anche il valore zero prende un ciclo di clock e quindi per una esatto timing dobbiamo considerare il -1.
Vediamo un esempio pratico usando un Atmega168:
Accendere e spegnere un LED (collegato sul pin1 del PortB) ogni secondo, usando il Timer1 e come clock quello di sistema del micro, che è di 4MHz.
"...Accendere e spegnere un LED (collegato sul pin1 del PortB) ogni secondo...":
Ogni sec il programma deve provvedere a spegnere il LED se è acceso, viceversa ad accenderlo se è spento. ..
"... usando il Timer1 e come clock quello di sistema del micro, che è di 4MHz...":
Il periodo del clock di sistema Tc = 0,25 micros (Tc=1/fc=1/4MHz) e al massimo il Timer1 (16 bit) può contare fino a N = 65535.
Il massimo tempo T che possiamo ottenere da questo timer è dato da:
T = ( N +1) * Tc
avremo 16,384ms
Come possiamo fare per arrivare a 1 sec?
Non possiamo aumentare il numero di bit, ma abbiamo la possibilità di applicare al timer un periodo più grande di quello di sistema Tc cioè possiamo applicare al timer una frequenza di clock fc più bassa di quella di sistema.
L'AVR ha un prescaler(divisore di frequenza) programmabile, con il quale è possibile pilotare il timer con una frequenza di clock inferiore a quella del sistema, di un fattore: 8, 64, 256 o 1024 (questo per il Timer0 e il Timer1)
Dunque, il clock al quale lavora il timer usando i prescaler, non è più Tc, ma Tc *k. (Tc = periodo clock)
Pertanto la formula per il calcolo di T con il prescaler diventa:
T = ( N +1) * Tc * k
k è il fattore di divisione del prescaler.
Quindi abbiamo, con N=65535, il massimo tempo che possiamo ricavare per ogni fattore di prescalamento:
-------------
k | Tmax
-------------
8 | 0,13s
64 | 1,05s
256 | 4,19s
1024 | 16,77s
--------------
Noi scegliamo k=64, perché è il minimo fattore che ci consente di avere un tempo superiore a quello desiderato e quindi ci assicura una risoluzione migliore, (cioè un periodo di clock più piccolo).
Pertanto, il numero N del timer per avere T=1s sarà:
N = [ T / (Tc * k) ] - 1
Per T= 1 sec otteniamo N=62499
Resta ora solo un problema: far azzerare il timer dopo 62499 invece che dopo 65535.
Come fare?
Configurare il timer per farlo lavorare in modo CTC e usare un interrupt che viene generato all'azzeramento dopo il numero desiderato.
Il timer che lavora in modo CTC non conta fino al massimo numero dato dal suo numero di bit, ma fino a un numero massimo definito in un particolare registro: OCR1A (per il Timer1).
Quindi in fase di configurazione del timer1, si andrà a caricare il numero 62499 nel registro OCR1A.
Di seguito le fasi per la configurazione del timer:
Imposta modo CTC;
Carica il numero N in OCR1A;
Impostare l'interrupt su OCR1A;
Imposta il prescaler;
ciao