Timer0

Collegamento ad un motore-passo-passo

Questa pagina descrive l'uso di Timer0, uno dei numerosi contatori hardware presenti all'interno del PIC18. Timer0 semplicemente conta quanti sono i fronti del segnale applicato al suo ingresso, senza l'intervento del processore. per chi ha studiato un poco di elettronica digitale, nulla cambia rispetto ad un contatore up presettabile, cioè nel quale è possibile impostare il valore iniziale.

Qualche esempio di possibile utilizzo:

La struttura di Timer0

Il modo più semplice per comprenderne il funzionamento di Timer0 è leggere il suo schema, presente sui fogli tecnici e qui riportato in una versione semplificata

Struttura del timer 0 in modalità 16 bit

Qualche osservazione sulla struttura di Timer0:

Facciamo lampeggiare un LED

L'esempio che trovate a fondo pagina utilizza Timer0 in modalità 16 bit per generare un'interruzione in compatibility mode ad intervalli regolari. All'interno della ISR viene cambiato ad ogni esecuzione lo stato di un LED, facendolo di conseguenza lampeggiare.

L'hardware è costituito semplicemente da un LED (e relativa resistenza in serie) connesso tra RC0 e massa

Esaminiamo il codice:

Per accendere il LED è necessario configurare PORTC come uscita:

  clrf TRISC ; PORTC come uscita, tutti gli 8 pin

Più complessa la configurazione di Timer0, fatta utilizzando alcuni dei flag del registro T0CON (Timer0 CONtrol register).  Occorre infatti:

Il codice di configurazione di Timer0:

 bcf T0CON, T08BIT ; Configura Timer0 per funzionare a 16 bit
 bcf T0CON, T0CS ; Configura il clock di Timer0 interno (250 kHz)
 bsf T0CON, PSA ; Disattivo il prescaler
 bsf INTCON, TMR0IE ; Abilito Timer0 a generare interruzioni
 bsf T0CON, TMR0ON ; "Accendo" Timer0

Infine occorre abilitare globalmente le interruzioni:

 bsf INTCON, GIE ; Abilito la CPU a ricevere interruzioni

Il loop principale, come spesso succede, non fa nulla:

repeat
 nop ; non fa nulla (No OPeration), per sempre
 nop
 bra repeat

La ISR è semplice: dopo aver verificato attraverso l'apposito flag che l'interruzione è stata effettivamente generata da Timer0, cambia lo stato del LED:

ISR CODE 0x0008
 btfsc INTCON, TMR0IF ; Interruzione da Timer0 ?
 bra GestioneTimer0 ; Esegue il codice corrispondente

 retfie FAST ; Nessuna interrupt riconosciuta... Indizio di un errore?

GestioneTimer0 ; Interrupt da Timer0
 btg LATC, 0 ; Fa lampeggiare il LED, invertendone lo stato
 bcf INTCON, TMR0IF ; Azzera il flag che segnala l'interrupt generato da Timer0
 retfie FAST ; Torna ad eseguire il codice principale

Quanto vale la frequenza di lampeggio del LED?

Quindi viene generato un interrupt ogni 4 µs ·  65 535 ≈ 0,262 s; di conseguenza il LED rimane circa ¼ di secondo accesso ed ¼ di secondo spento, lampeggiando con una frequenza di poco più di 2 Hz

Un altro esempio: un motore passo-passo

Questo codice, come sempre disponibile a fondo pagina, è molto simile al precedente. Esso è stato scritto pensando al pilotaggio di un motore passo-passo, collegato al PIC18 attraverso un driver che in ingresso accetta due segnali:

Non è rilevante il tipo di driver utilizzato. Nella foto di apertura è mostrato un DRV8825 disponibile per pochissimi Euro su molti siti di commercio elettronico; esso è collegato ad un piccolo motore bipolare di recupero.

ATTENZIONE - Un motore richiede tensioni elevate per funzionare (nota 3), distruttive per quasi tutti i componenti elettronici. Quindi:

Lo schema dettagliato è per esempio disponibile su questo sito.

Due le differenze significative nel codice rispetto al precedente:

Il codice

Esercizi

  1. Il prescaler permette di ridurre la frequenza del clock di 2, 4, 8..., 256 volte. Scrivere il codice per ridurre la frequenza di lampeggio del LED attraverso una modifica del prescaler (suggerimento: leggere il significato dei quattro bit meno significativi di REGISTER 12-1: T0CON: TIMER0 CONTROL REGISTER
  2. Il valore di inizio del conteggio può essere impostato dal PIC18 scrivendo un numero a 16 bit nei due registri a 8 bit TMR0L e TMR0H. Di fatto questo riduce il tempo necessario a Timer0 per generare un interrupt. Modificare il codice della ISR per raddoppiare la frequenza di lampeggio del LED, iniziando il conteggio da 0x7FFF anziché, automaticamente, da 0x0000  (nota 2)
  3. Timer0 permette di impostare la priorità delle interruzioni. Scrivere il codice corrispondente dopo aver individuato sui fogli tecnici il flag corrispondente (suggerimento: REGISTER 9-2: INTCON2: INTERRUPT CONTROL 2 REGISTER)

Note

  1. Come tutti i contatori binari, raggiunto il valore massimo, il conteggio ricomincia automaticamente da zero
  2. Per garantire il corretto funzionamento di Timer0 è necessario prima scrivere TMR0H e successivamente TMR0L
  3. Un motore può generare tensioni molto più elevate di quella di alimentazione, anche centinaia di volt (comunque non pericolose per le persone se il motore è di piccole dimensioni)

 

Data di creazione di questa pagina: maggio 2016
Ultima modifica: 25 aprile 2018


Licenza Creative Commons Attribuzione 4.0 Internazionale


Pagina principaleAccessibilitàNote legaliPosta elettronicaXHTML 1.0 StrictCSS 3

Vai in cima