- Messaggi: 50
- Ringraziamenti ricevuti 0
Ancora problemi con codice TIMER
13 Anni 7 Mesi fa #16
da Ricky85
Risposta da Ricky85 al topic Re: Ancora problemi con codice TIMER
C'è tutto scritto nella guida di Mauro, ti copio qua sotto la sezione che ti interessa
Impostare il tempo del Timer
Come visto nell'esempio precedente si è potuto far lampeggiare il LED 0 con tempi stabiliti
dal Timer0. Vediamo di capire qual'era il tempo che caratterizzava il lampeggio.
Sappiamo che sulla scheda Freedom II è presente un quarzo da 20MHz. Questo significa
che il periodo del clock utilizzato è pari a 0.05μs ovvero:
TOSC= 1
FOSC
= 1
20⋅106
=0.05 μs
Si ricorda in particolare che il tempo di esecuzione di una istruzione è pari a quattro cicli di
clock dunque il clock che va ad incrementare il nostro Timer è pari a 0.2μs, ovvero:
TTIMER0=TOSC⋅4=0.05⋅4=0.2μs
Nel nostro esempio il periodo di 0.2μs viene in realtà rallentato dal prescaler che è stato
impostato a 32. Questo significa che il periodo del clock uscente dal prescaler sarà 32 volte
maggiore:
T PRESCALER=TOSC⋅4⋅32=0.05⋅128=6.4μs
Il clock in uscita dal prescaler è effettivamente quello utilizzato per far incrementare il
nostro Timer0, il quale è stato impostato per lavorare in modalità a 16 bit. Questo significa
che conterà da 0 a 65535. Quando avverrà l'overflow, ovvero il passaggio da 65535 a 0,
viene generato il nostro interrupt che fa cambiare lo stato al LED 0, quindi il nostro LED
viene cambiato di stato ogni 0.42 secondi106.
Cosa bisogna fare per ottenere 0.5 secondi?
Un modo di procedere è il seguente. Considerando i tempi elevati bisognerà sicuramente
far uso del prescaler, che come detto ritarderà il clock ottenendo un periodo di 6.4μs che come
abbiamo appena visto non è sufficiente per ottenere il tempo desiderato neanche facendo
contare fino al massimo il Timer0 impostato in modalità a 16 bit. Questo significa che
bisognerà utilizzare il prescaler dividendo per 64 piuttosto che per 32, ottenendo in questo
modo :
T PRESCALER=TOSC⋅4⋅64=0.05⋅128=12.8μs
In questo caso moltiplicando il nuovo periodo per 65536 (si è considerato anche lo 0) si ha
che il nostro ritardo totale è 0.839s, ovvero il doppio di prima! Questa volta il nostro Timer0
rallenta troppo. Per ottenere esattamente 0.5s, quello che si fa è non far partire il Timer0 da 0,
ovvero si carica un valore nel timer in modo che raggiunga l'overflow in minor tempo. Questo
significa che potremo in realtà ottenere il nostro tempo...
Per capire il valore da caricare nel Timer0 si divide il tempo che si vuole ottenere per il
periodo del clock ottenuto in uscita dal prescaler, ovvero:
CONTEGGI= 0.5
T PRESCALER
= 0.5
0.0000128=39062.5
Il numero di conteggi non è il valore da caricare nel Timer0, bensì il numero di conteggi
che deve fare il Timer0 prima di andare in overflow. Questo significa che il numero da
caricare nel Timer0 è pari a:
TIMER0=2161−39062.5=65536−39062.5=26473.5
Dal momento che nel Timer0 si possono caricare solo numeri interi sarà necessario
approssimare o troncare il numero, in questo caso dunque il numero da caricare è 26473. Va
bene troncare il numero poiché questo non sarebbe comunque preciso. Come
precedentemente detto per avere tempi precisi sarebbe necessario anche avere un oscillatore
preciso.
Qualche altra nota è importante. Il valore 26473 deve essere caricato all'interno di due
registri ovvero TMR0L e TMR0H. Questo significa che bisogna spezzare il valore 26473 in
due byte, per fare questo si deve convertire il numero in binario (per esempio usando la
calcolatrice di Windows). Il numero binario è: 110011101101001. Tale numero deve esser poi
diviso in due byte:
01100111 - 01101001
Si noti che la divisione in due gruppi è stata fatta partendo da destra. Il primo byte di destra
dovrà essere caricato nel registro TMR0L, mentre l'altro deve essere caricato nel registro
TMR0H, ovvero:
TMR0H = 01100111;
TMR0L = 01101001;
Si osservi che il registro TMR0H è stato scritto per primo. Questo passo è obbligatorio
poiché il registro TMR0H non rappresenta effettivamente gli otto bit più significativi del
Timer0 in modalità 16 bit, bensì un buffer (registro di supporto), il cui valore viene caricato
nel registro TMR0H quando avviene la scrittura del registro TMR0L. Questo significa che per
caricare un valore in modalità a 16 bit è necessario caricare il valore in TMR0H prima di
scrivere in TMR0L. Per maggiori dettagli si faccia riferimento al datasheet del PIC utilizzato.
Le istruzioni sopra citate per caricare il valore nel Timer0 devono essere eseguite subito
dopo aver attivato il Timer0 dunque subito dopo l'inizializzazione del Timer0. Oltre a questo
bisogna ricaricare tale valore ogni volta che si entra nella funzione d'interrupt del Timer0107.
Dal momento che il Timer0 può essere gestito anche in modalità ad 8 bit si può anche
prendere in considerazione il fatto di far lavorare il registro in tale modalità. Il tutto dipende
dai tempi che dobbiamo ottenere. Nel nostro caso per esempio, pur mettendo il prescaler a
256 si sarebbe potuto ottenere un ritardo massimo di circa 13ms.
In ultimo si fa notare che qualora si debbano ottenere ritardi ben superiori al secondo, per
esempio 1 minuto, ovvero in casi in cui la combinazione del Timer e il prescaler non sono
sufficienti per ottenere il ritardo voluto; quello che si fa è inserire un ulteriore conteggio
all'interno della procedura d'interrupt108. Se il tempo dovesse raggiungere valori dell'ora la
soluzione proposta va ancora bene, ma si potrebbe anche prendere in considerazione l'utilizzo
di un Clock Calendar esterno o ottenuto per mezzo del Timer1 ed un quarzo da 32768KHz.
Pagine 177-178 e 179 della guida PIC18 Step By Step
Impostare il tempo del Timer
Come visto nell'esempio precedente si è potuto far lampeggiare il LED 0 con tempi stabiliti
dal Timer0. Vediamo di capire qual'era il tempo che caratterizzava il lampeggio.
Sappiamo che sulla scheda Freedom II è presente un quarzo da 20MHz. Questo significa
che il periodo del clock utilizzato è pari a 0.05μs ovvero:
TOSC= 1
FOSC
= 1
20⋅106
=0.05 μs
Si ricorda in particolare che il tempo di esecuzione di una istruzione è pari a quattro cicli di
clock dunque il clock che va ad incrementare il nostro Timer è pari a 0.2μs, ovvero:
TTIMER0=TOSC⋅4=0.05⋅4=0.2μs
Nel nostro esempio il periodo di 0.2μs viene in realtà rallentato dal prescaler che è stato
impostato a 32. Questo significa che il periodo del clock uscente dal prescaler sarà 32 volte
maggiore:
T PRESCALER=TOSC⋅4⋅32=0.05⋅128=6.4μs
Il clock in uscita dal prescaler è effettivamente quello utilizzato per far incrementare il
nostro Timer0, il quale è stato impostato per lavorare in modalità a 16 bit. Questo significa
che conterà da 0 a 65535. Quando avverrà l'overflow, ovvero il passaggio da 65535 a 0,
viene generato il nostro interrupt che fa cambiare lo stato al LED 0, quindi il nostro LED
viene cambiato di stato ogni 0.42 secondi106.
Cosa bisogna fare per ottenere 0.5 secondi?
Un modo di procedere è il seguente. Considerando i tempi elevati bisognerà sicuramente
far uso del prescaler, che come detto ritarderà il clock ottenendo un periodo di 6.4μs che come
abbiamo appena visto non è sufficiente per ottenere il tempo desiderato neanche facendo
contare fino al massimo il Timer0 impostato in modalità a 16 bit. Questo significa che
bisognerà utilizzare il prescaler dividendo per 64 piuttosto che per 32, ottenendo in questo
modo :
T PRESCALER=TOSC⋅4⋅64=0.05⋅128=12.8μs
In questo caso moltiplicando il nuovo periodo per 65536 (si è considerato anche lo 0) si ha
che il nostro ritardo totale è 0.839s, ovvero il doppio di prima! Questa volta il nostro Timer0
rallenta troppo. Per ottenere esattamente 0.5s, quello che si fa è non far partire il Timer0 da 0,
ovvero si carica un valore nel timer in modo che raggiunga l'overflow in minor tempo. Questo
significa che potremo in realtà ottenere il nostro tempo...
Per capire il valore da caricare nel Timer0 si divide il tempo che si vuole ottenere per il
periodo del clock ottenuto in uscita dal prescaler, ovvero:
CONTEGGI= 0.5
T PRESCALER
= 0.5
0.0000128=39062.5
Il numero di conteggi non è il valore da caricare nel Timer0, bensì il numero di conteggi
che deve fare il Timer0 prima di andare in overflow. Questo significa che il numero da
caricare nel Timer0 è pari a:
TIMER0=2161−39062.5=65536−39062.5=26473.5
Dal momento che nel Timer0 si possono caricare solo numeri interi sarà necessario
approssimare o troncare il numero, in questo caso dunque il numero da caricare è 26473. Va
bene troncare il numero poiché questo non sarebbe comunque preciso. Come
precedentemente detto per avere tempi precisi sarebbe necessario anche avere un oscillatore
preciso.
Qualche altra nota è importante. Il valore 26473 deve essere caricato all'interno di due
registri ovvero TMR0L e TMR0H. Questo significa che bisogna spezzare il valore 26473 in
due byte, per fare questo si deve convertire il numero in binario (per esempio usando la
calcolatrice di Windows). Il numero binario è: 110011101101001. Tale numero deve esser poi
diviso in due byte:
01100111 - 01101001
Si noti che la divisione in due gruppi è stata fatta partendo da destra. Il primo byte di destra
dovrà essere caricato nel registro TMR0L, mentre l'altro deve essere caricato nel registro
TMR0H, ovvero:
TMR0H = 01100111;
TMR0L = 01101001;
Si osservi che il registro TMR0H è stato scritto per primo. Questo passo è obbligatorio
poiché il registro TMR0H non rappresenta effettivamente gli otto bit più significativi del
Timer0 in modalità 16 bit, bensì un buffer (registro di supporto), il cui valore viene caricato
nel registro TMR0H quando avviene la scrittura del registro TMR0L. Questo significa che per
caricare un valore in modalità a 16 bit è necessario caricare il valore in TMR0H prima di
scrivere in TMR0L. Per maggiori dettagli si faccia riferimento al datasheet del PIC utilizzato.
Le istruzioni sopra citate per caricare il valore nel Timer0 devono essere eseguite subito
dopo aver attivato il Timer0 dunque subito dopo l'inizializzazione del Timer0. Oltre a questo
bisogna ricaricare tale valore ogni volta che si entra nella funzione d'interrupt del Timer0107.
Dal momento che il Timer0 può essere gestito anche in modalità ad 8 bit si può anche
prendere in considerazione il fatto di far lavorare il registro in tale modalità. Il tutto dipende
dai tempi che dobbiamo ottenere. Nel nostro caso per esempio, pur mettendo il prescaler a
256 si sarebbe potuto ottenere un ritardo massimo di circa 13ms.
In ultimo si fa notare che qualora si debbano ottenere ritardi ben superiori al secondo, per
esempio 1 minuto, ovvero in casi in cui la combinazione del Timer e il prescaler non sono
sufficienti per ottenere il ritardo voluto; quello che si fa è inserire un ulteriore conteggio
all'interno della procedura d'interrupt108. Se il tempo dovesse raggiungere valori dell'ora la
soluzione proposta va ancora bene, ma si potrebbe anche prendere in considerazione l'utilizzo
di un Clock Calendar esterno o ottenuto per mezzo del Timer1 ed un quarzo da 32768KHz.
Pagine 177-178 e 179 della guida PIC18 Step By Step
Si prega Accedi o Crea un account a partecipare alla conversazione.
- Ricky85
- Senior Member
Riduci
Di più
13 Anni 7 Mesi fa #17
da Spazzoli
anto.spax
youtube robot gallery:
www.youtube.com/user/antospax?feature=mhum
Risposta da Spazzoli al topic Re: Ancora problemi con codice TIMER
Ecco appunto...quello a cui facevo riferimento!!!
..grazie ricky..
..grazie ricky..
anto.spax
youtube robot gallery:
www.youtube.com/user/antospax?feature=mhum
Si prega Accedi o Crea un account a partecipare alla conversazione.
13 Anni 7 Mesi fa #18
da Guido
Risposta da Guido al topic Re: Ancora problemi con codice TIMER
Grazie per avermi rispoto, il mio problema non è come trovare la frequenza, ma di far gestire al Pic frequenze diverse. Come ho scritto non riesco a far riconoscere frequenze diverse al premere di più pulsanti, il codice che ho scritto e che voi mi avete corretto (grazie) mi riconosce solo la frequenza scritta nel main, negli If mi vede solo il settaggio del prescaler (T0PS), è qui che ho bisogno di aiuto. Come far generare le frequenze che voglio Es. 200Hz, 620Hz, 1000Hz, ecc?
Grazie
Grazie
Si prega Accedi o Crea un account a partecipare alla conversazione.
- Guido
- Autore della discussione
- Platinum Member
Riduci
Di più
- Messaggi: 583
- Ringraziamenti ricevuti 1
Moderatori: Mauro Laurenti, Pinna, StefA, Matteo Garia
Registrati al sito
Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.