Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Il TIMER 0

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

1
voti

[1] Il TIMER 0

Messaggioda Foto UtentePaolino » 21 set 2006, 13:13

Nel forum di ELECTROPORTAL non è infrequente vedere inserite richieste di realizzazione di temporizzatori/ritardatori con microcontrollori PIC. Con questo breve documento, voglio illustrare cos'è il modulo del TIMER e come impiegarlo per realizzare facilmente delle temporizzazioni.

TIMER 0
La maggior parte dei PIC disponibili oggi sul mercato, dispone di uno o più moduli TIMER; nonostante ci sia della familiarità nella configurazione dei vari timer, in questa sezione verrà illustrato il funzionamento del TIMER 0 in quanto è, come detto, il modulo presente praticamente sempre.
Sulla maggior parte dei PIC. il TIMER 0 (spesso indicato anche come TMR0) è rappresentato da un registro a 8 bit che va ad incrementarsi da un valore precaricato sino a 255 (in notazione esadecimale 0xFF oppure FFh). L'overflow, ossia il superamento del valore 0xFF provoca un azzeramento del contenuto del registro e la generazione di una segnalazione a mezzo del flag T0IF (Timer 0 Interreupt Flag).
L'utilizzo del TIMER 0 può avvenire sia con la gestione degli interrupt sia in polling, ossia con la continua osservazione dell'evento di segnalazione (T0IF=1). Questo è il caso che si vuole analizzare nel seguito lasciando la parte riguardante l'interrupt del timer per un'altra sezione.

Conmideriamo, per semplicità, di utilizzare il PIC 16F84A; lo schema a blocchi del TMR0 è illustrato in figura 1.
Immagine
Il timer può lavorare con sorgente esterna, fornendo un segnale ad onda quadra TTL sul pin RA4 (va specificato il fronte che incrementa il timer, configurando il flag T0SE Timer 0 Source Edge) oppure utilizzando la frequenza di clock di sistema che vale Fosc/4. Il modulo mette a disposizione un prescaler (ossia un divisore) programmabile con 8 valori, da 1:1 a 1:128. Il segnale a questo punto si sincronizza con il clock di sismema (con due cicli di ritardo) e poi finalmente incrementa il registro TMR0.

Il codice che segue, configura il TMR0 per avere un overflow ogni 8.2ms; facendo l'ipotesi di disporre di un quarzo da 4MHz.

Fosc = 4 MHz
Fcy = Fosc/4 = 1 MHz
T0CS= 0
T0SE = 0
Prescaler 1:32 -> PSA = 1, PS0 = 0, PS1 = 0, PS2 =1

Codice: Seleziona tutto
   MOVLW   B'11000100'   ;Config. modulo timer TMR0: prescaler 1:32, clock interno, no prescaler wdt
   MOVWF   OPTION_REG


Per la gestione del TMR0 è sufficiente caricare in W un valore da 0 a 255 e chiamare la rotuine
Codice: Seleziona tutto
   MOVLW   0
   CALL   DELAY


Con W=0 si ha il massimo ritardo (pari a 8.2 ms); con W > 0 si possono avere valori di timer inferiori, con passo 32us

Codice: Seleziona tutto
;----------------------------------------------------
; DELAY
; Routine di ritardo che sfrutta il timer TMR0
; in W c'é il valore da caricare in TMR0: variandolo
; da 0 a 255 il ritardo cala rispettivamente da 8.2ms
; a 32us col quarzo a 4MHz.
; Si presuppone che il TMR0 abbia prescaler 1:32
;----------------------------------------------------
DELAY
   MOVWF   TMR0
   BCF   INTCON,T0IF
DELAY1
   BTFSS   INTCON,T0IF
   GOTO   DELAY1
   RETURN


Ciao.

Paolo
Avatar utente
Foto UtentePaolino
32,6k 8 12 13
G.Master EY
G.Master EY
 
Messaggi: 4226
Iscritto il: 20 gen 2006, 11:42
Località: Vigevano (PV)

0
voti

[2]

Messaggioda Foto Utenteaduri » 25 set 2006, 22:18

Mi congratulo,
ottimo tutorial. :wink:
Io col linguaggio assembler sono una schiappa ma se descrivi come lavora il micro cosi' bene ci capisco anch'io.
Avatar utente
Foto Utenteaduri
435 1 5 11
Expert
Expert
 
Messaggi: 937
Iscritto il: 29 giu 2005, 23:13
Località: Genova

0
voti

[3]

Messaggioda Foto Utentewolf » 28 set 2006, 12:04

Ciao, sono agli albori con la programmazione dei PIC, ma la cosa mi sta piacendo parecchio ed ho appena finito il mio primo vero programma.
Una schedina con 16F84A che oscilla precisamente a 250Hz. utilizzando il tmr0.
A questo punto vorrei aggiungere 2 pulsanti:
-Puls. 1 premuto= incremento di 1Hz.
-Puls. 2 premuto= decremento di 1Hz.
Il valore viene salvato in EEPROM in modo che se spengo e riaccendo la scheda rimane salvato il valore modificato.
-Puls. 1 + Puls. 2 premuti contemporaneamente reset con ripartenza a 250Hz.

A questo punto devo mettere un piccolo tempo per antirimbalzo dei pulsanti; il dubbio e' questo: :roll:
Come posso mettere questo tempo senza andare a influire sulla freq. di uscita?
Il tmr0 e' già impegnato, se faccio un ritardo software vado a influire sul tempo totale di esecuzione, quindi abbassando la freq.
Piu' in generale, vorrei sapere se e' possibile con un PIC dotato di un solo timer effettuare piu' di un conteggio temporale.

Saluti
Luca
Avatar utente
Foto Utentewolf
0 2
New entry
New entry
 
Messaggi: 82
Iscritto il: 9 ago 2005, 9:04
Località: Biella

1
voti

[4]

Messaggioda Foto UtentePaolino » 28 set 2006, 13:07

Ciao Luca.
Non specifichi se il TIMER è impiegato in polling o con l'interrupt. Assumo (per ipotesi) che sia il primo caso (polling).
Per operare l'antirimbalzo puoi contare un certo numero di overflow. A 250 Hz il periodo di overflow è pari a 4 ms; se non fosse sufficiente, puoi contare 2 overflow ed ottieni una pausa di 8 ms. Va detto che, modificando la frequenza del timer (aumentandola e/o diminuendola) l'overflow non sarà più con quella frequenza ma leggermente variato.

Se invece usi l'interrupt, ci sono diversi modi. Uno è quello di incrementare una variabile nella routine di interrupt. Nel main, alla pressione del tasto prima azzeri la variabile e poi controlli che tale variabile abbia superato un valore preimpostato (periodo di antirimbalzo) ed allora controlli nuovamente lo stato. Il tuo timer sarà lievemente rallentato dall'incremento della variabile.

Ciao.

Paolo.
Avatar utente
Foto UtentePaolino
32,6k 8 12 13
G.Master EY
G.Master EY
 
Messaggi: 4226
Iscritto il: 20 gen 2006, 11:42
Località: Vigevano (PV)

0
voti

[5]

Messaggioda Foto Utentewolf » 28 set 2006, 14:40

Grazie per le indicazioni, :D
ho usato il polling con un solo overflow che cambia lo stato della uscita.( Allego parte del programma).

Codice: Seleziona tutto
;**********************************************************
; Programma per oscillazione Pic16F84A
; Ingresso abilitazione   0
; Uscita frequenza   0
; Frequenza 250 Hz. 50% programmare 86 Hex o 134 Dec
; all' indirizzo 0 della EEPROM
; altre frequenze:   248 Hz mettere 133
;         252 Hz mettere 135
;
;********Calcolo Frequenza****** 250 Hz
;
; Inizializza TMR0 per ottenere 122 conteggi prima di arrivare a zero.
; 4.000.000/4/16/122=512.3 Hz   / 2 semiperiodi = 256.15 Hz.
; Se lo si inizializza a 134 dovra' essere incrementato 256 - 134 = 122 volte
; prima passare per lo zero.
;**********************************************************

        PROCESSOR       16F84A
        RADIX           dec
        INCLUDE         "P16F84A.INC"
        ERRORLEVEL      -302

        ;Setup

        ;XT oscillator
        ;Disable watch dog timer
        ;Enable power up timer
        ;Disable code protect

        __CONFIG        0x3FF1   ;11111111110001




;-----------------------------------------------------------------------------------------
delay
;-----------------------------------------------------------------------------------------

   movf   freq,w      ; frequenza di oscillazione
   movwf   TMR0

DelayLoop   ;Loop di conteggio

   movf    TMR0,W
   btfss   STATUS,Z   ;TMR0 vale 0 ?
   goto    DelayLoop       ;No, aspetta...

   return



Provero' ad usare l' interrupt, anche perche' variando la frequenza se mi varia di qualche ms l' antirimbalzo non e' cosa grave.

Grazie ancora


Saluti
Luca[/code]
Avatar utente
Foto Utentewolf
0 2
New entry
New entry
 
Messaggi: 82
Iscritto il: 9 ago 2005, 9:04
Località: Biella


Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 18 ospiti