Anche in questo caso e' necessario sottolineare l'importanza della lettura del datasheet prima di affrontare la programmazione di un picmicro anche se questo timer è comune ad una grande fascia di microcontrollori. L'utilizzo dell'interrupt generato dall'overflow del timer1 non è concettualmente molto diverso da quello generato dal timer0, è semplicemente un po' piu' sofisticato:
- è un timer a 16 bit (da 0000h a FFFFh o da 0 a 65535 dec.)
- puo' utilizzare clock interni o esterni
- causa un interrupt o un 'risveglio' su overflow
- puo' operare come timer o contatore sincrono/asincronocounter
essendo un modulo a 16 bit il valore del timer viene memorizzato in due locazioni di memoria (o registri): TMR1H and TMR1L.
Normalmente il comportamento di questo modulo è regolato da un registro: T1CON ma vengono coinvolti anche altri registri.
|
|
E' sempre importante leggere il datasheet perche', ad esempio, utilizzando il picmicro 12F683, il Bit7 ed il Bit6 (T1GINV e TMR1GE sono utilizzati rispettivamente per invertire la logica del gate e per il suo monitoraggio) mentre utilizzando altre mcu di fascia media questi bits non sono utilizzati.
La situazione sembra piuttosto complicata ma in realta' non è cosi (almeno non è sempre cosi). Il Timer1 è semplicemente un timer piu' completo.
Per completare l'abilitazione di questo interrupt si devono settare altre registri:
|
Due bit del registro INTCON sono coinvolti nella predisposizione del timer1 GIE e PEIE:
Entrambi questi bits devono essere settati ad '1' |
|
i bits dei registri PIE e PIR occupano posizioni diverse in base al picmicro utilizzato. Questo non è un problema in quanto utilizzando linguaggi di alto livello (e librerie predisposte) potremo indirizzarli attraverso il loro nome senza curarci molto della loro posizione. Il bit TMR1IE deve essere abilitato (settato ad 1) Il flag TMR1IF deve essere 'pulito' ogni volta che la routine interrupt viene chiamata (e quindi ogni volta che vi è stato un overflow del timer). |
Ricordando quanto esposto in un altro articolo (timer0) riguardo l'utilizzo del prescaler ed il valore di precharge, la situazione dovrebbe essere chiara: il prescaler divide il clock (fosc/4) generando un interrupt ogni 65536 impulsi. Se si desidera modificare questo valore si potrò agire suio valori iniziali (precharge) dei registri TMR1H:TMR1L. Anche in questo caso sara' di aiuto l'utilizzo di un calcolatore (es.: http://eng-serve.com/pic/pic_timer.html)
Utilizzando il Microc (con un 16f877) possiamo ora, quindi, scrivere:
.......
void interrupt() {
if (TMR1IF_bit) {
...... // routine interrupt
......
TMR1IF_bit = 0; // pulisce il bit TMR1IF
TMR1H = 0x00; // setta i valori iniziali del contatore
TMR1L = 0x00;
}
}
void main() {
ADCON = 0x0; // Configura ingressi come digitale
ADCON1 = 0x0;
CMCON = 0x7; // Disabilita i comparatori
TMR1IE_bit = 1; // abilita il Timer1 interrupt
TMR1IF_bit = 0; // resetta il TMR1IF
TMR1H = 0x00; // Inizializza il timer1 con valori di precharge
TMR1L = 0x00;
T1CON = 0x01; // Setta il Timer1 - TMR1ON=1 - PRESCALER=1/1
INTCON = 0xC0;
do {
.........
.........
} while (1);
}