Questo sito utilizza cookie, anche di terze parti, per migliorare la tua esperienza e offrire servizi in linea con le tue preferenze. Chiudendo questo banner, scorrendo questa pagina o cliccando qualunque suo elemento acconsenti all’uso dei cookie. Se vuoi saperne di più o negare il consenso a tutti o ad alcuni cookie vai alla sezioneCookie Policy

Interrupt con Timer1

Ultimo aggiornamento: 31/07/2015

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.

timer1

 

Bit7 and Bit6: non usati

T1CKPS1
T1CKPS2 

Bits 5-4: setta il prescaler a:
00 = 1/1 fosc/4
01 = 1/2 fosc/4
10 = 1/4 fosc/4
11 = 1/8 fosc/4

T1OSCEN

Bit3: se è usato INTOSC setta l'oscillatore LP 
1 = oscillatore LP ON per il timer1
0 = oscillatore LP OFF 

T1SYNC

Bit2: setta la sincronizzazione del clock esterno
1 = syncro ON con input esterno
0 = syncro OFF 

TMR1CS

Bit1: setta il clock del timer
1 = clock esterno da T1CKI
0 = clock fosc/4 

TMR1ON

Bit0: setta il timer ON o OFF
1 = abilita il timer1
0 = disabilita il timer1

 

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:

intcon picmicro

Due bit del registro INTCON sono coinvolti nella predisposizione del timer1 GIE e PEIE:

  • GIE  = abilita l'interrupt globale
  • PEIE = abilita l'interrupt periferico

Entrambi questi bits devono essere settati ad '1'

TMR1IE picmicro

i bits dei registri PIE 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);
}

 

 

Diritti riservati Cuteminds.com 2008-2015. Tutti i marchi riportati sono detenuti dai legittimi proprietari. Tutto il materiale e` liberamente utilizzabile ma non per scopi commerciali. Non si assume alcuna responsabilita` sul materiale pubblicato per eventuali danni diretti o indiretti che possano derivare dall`utilizzo di schemi, progetti o altro materiale presente nel sito. Inviare una mail a: remove-admin@cuteminds.com (contenuti) remove-webmaster@cuteminds.com (webserver) per domande e/o suggerimenti.