Newsgroup: it.hobby.elettronica.digitale
Titolo: Scrittura su TMR0 16F84

Sto realizzando un semplice Timer con un
PIC 16F84 Quarzo a 4 MHz e 4 display 7segmenti.
Prescaler associato a TMR0.
Prescaler Rate 1:16.
TMR0 interupt abilitato.
Ogni 16x256=4096us ho un interrupt per overflow di TMR0
e nell'interruipt handler gestico il rinfresco dei display.
Fin qui tutto ok.
Problema: devo gestire una routine ogni mezzo secondo
vale a dire 500000 us.
Con il registro INTCNT (interrupt counter) tengo
il conteggio degli interrupt.
Dopo 122 interrupt sono passati 4096x122=499712us.
Ora setto il bit flag ADJ (adjust) di un registro
di lavoroper ricordarmi che ora devo
regolare il tempo.
Mancano infatti 500000-499712=288 us per
ottenere il mezzo secondo.
Dentro all'interrupt handler voglio scrivere su TMR0
 in modo che vada in overflow dopo 288us
dall'interrupt precedente.
TMR0 deve fare quindi  288/16=18 incrementi
quindi scrivo 256-18=238 su TMR0.
Sembra giusto ma in pratica il timer
va troppo forte, il display
segna 1 sec in piů ogni paio di ore.
Problema di frequenza dell'oscillatore
o programma sbagliato ???
Aiuto !
Non capisco la figura 6.2 e 6.3
pag 28 del documento DS30430C.pdf
(data sheet PIC 16f84).
Se avete bisogno del listato assembler
ve lo posto.
Ciao,
Grazie.
--------------------------
; tmr0 interrupt handler
-------------------------
*salvo W e STARUS*
.
    btfss rnflg,adj ; occorre aggiustare tempo ?
    goto $+3  ; no, continua
    call adjust  ; si, occorre regolare TMR0
    goto restore  ; poi ripristina e ritorna.
    decfsz intcnt,f ; sono trascorsi 122 interrupt ?
    goto refresh  ; no, continua
    call evryhs    ; sě, every half seocnd routine
    bsf rnflg,adj  ; setta bit flag adj
refresh    ; refresh del display
....
restore
* ripristina registri W eSTATUS*
   bcf INTCON,T0IF ; resetta interrupt flag
   retfie   ; ritorna con GIE abilitato
--------------------
; routine adjust
--------------------
adjust movlw 122  ; reinizializza
 movwf intcnt  ; interrupt counter
 bcf rnflg,adj ; e resetta adjust bit.
 nop   ; 16us dall'inizio dell'interrupt handler.
 movlw 239  ; scrive su TMR0 per
 movwf TMR0  ; regolare il tempo.
 nop   ; Scrittura TMR0 eseguita.Reset Prescaler
 nop   ; In questi due cicli macchina
 nop   ; il conteggio di TMR0 č inibito ?
 return

io pure ho avuto dei problemi realizzando un sveglia con lcd usando il pic
e forse si puo' risolvere cosi:
prima cosa fa in modo che il timer
tiscatti piu avanti possibile ma la routine di aggiornamento display non
farla sotto inter. ma sul main tu lascia contare paceficamente il timer
quando il tuo timer ti ha prodotto il tuo secondo setta un flag e lo testi
nel main se va alto aggiorna se no non fare nulla cmq ti dicevo che ho
avuto lao stesso problema e con lcd e piu' incasinato ma si puo attenere un
buon risultato se conti bene quanti instuzioni fai sotto inter. infatti se
tu carichi il timer con un vallore prima di ricaricarlo tu fai dei micro
ritadi da 1us per istruzione alla fine tu carichi il timer es. 25 ma hai
eseguto 4 istruzioni quindi alla fine hai 25+4us lo so sono pochi ma tutto
aiuta a sballare io ero arrivato a 1 secondo ogni 4 ore ma poi mi sono
rotto e sono passato a un ht1380 un orologio con datario e lascio che sia
lui a contare io ogni 500ms verifico se devo incremetare il time su lcd lo
so che ti sempra complicato ma fidati di chi e gia passato...ciaoo
--------------------------------
Inviato via 
http://usenet.iol.it
 

 Sto realizzando un semplice Timer con un PIC 16F84
la piu' infausta delle cose e' che la scrittura nel tmr0 ti azzera i cicli
di clock contati dal prescaler nel tempo intercorrente tra l'overflow del
tmr0 e la sua riscrittura:-((( L'unico modo che ho trovato per evitare
questa cosa e' lasciar andare il timer in "free running" (senza mai
ricaricare il tmr0) in modo che generi overflow perfettamente
equidistanti... a questo punto si puo' correggere il tempo a software,
oppure si deve usare un quarzo ben preciso...
ciao
Claudio

 oppure si deve usare un quarzo ben preciso...
basta sommare su tmr0 il preset desiderato, rispetto al suo valore, 
tenuto conto che, tra leggere il valore, sommarlo, e caricarlo, 
occorrono n cicli, da scalarsi al preset voluto; ricordando inoltre che 
  ciascuna itruzione può avere durata di uno o due cicli, per un periodo 
di (1/FOSC)*4.
Saluti.
mubeta.


Già, sono convinto che sia decisamente meglio questa soluzione.
Però, boh, non mi va giù questa facenda.
Noto con rammarico, anche da post precedenti , che il comportamento
del registro TMR0  come Timer provoca molte difficoltà.
Bisogna ancora far luce.
Forza non molliamo !
Ciao Grazie !

 tmr0 e la sua riscrittura:-((( L'unico modo che ho trovato per evitare
Infatti ho cercato di fare in modo che TMR0 inizi ad incrementare
esattamente dopo un tempo multiplo intero del periodo del presclaler rate.
Su TMR0 compenso il ritardo della scrittura con un valore leggeremente
maggiore del preset
Ma non tornano i conti teorici !
Certo, è facile dimenticarsi qualche us per strada...
il conto che ho fatto io è :
Avviene l'overflow di TMR0,
passano 2 us prima che venga eseguita
la prima operazione dell'interrupt handler
poi conto quanti us passano prima
della scittura su tmr0 sia definitiva
introducento eventualmente delle nop
in modo che tmr0 inizi a incrementare
dopo un multiplo
intero del perido del prescale.
Ciao.
Grazie.

 mubeta.
Aaah, tu dici sommare a TMR0.
Il data sheet dice che ogni operazione di scrittura
su TMR0 azzera il prescaler.
Ma anche l'operazione di somma azzera il Prescaler ?
Ciao.
Grazie.

 
Non mi è mai successa una cosa simile, dove lo hai letto? Tutti i vari 
demo che ho trovato in giro, fanno come ho detto io. Fammi sapere, sono 
curioso.
Ciao,
mubeta.

come sta andando? a che punto sei? riuscito a capire che cacchio succede
sul timer informaci mi raccomando



Ho provato sia a scrivere un nuovo valore su TMR0
sia a sommare un preset tutto calcolato
come descritto nei post precedenti.
Stesso risultato Timer troppo veloce.
Per farlo funzionare dignitosamente
devo sottrarre 5  al valore teorico da mettere su
TMR0.Questa differenza l'ho trovata sperimentalmente.
Cronometro alla mano ho lasciato funzionare il timer
per circa 12 ore e i secondi sul display sono
ancora giusti.
Tenuto conto che ho il prescaler  impostato 1:16 vuol dire
che ho rallentato il timer di 16x5 =80 us ogni mezzo secondo.
( ogni mezzo secondo eseguo l'aggiustamento su tmr0
ed eseguo una breve routine sotto interrupt)
In altre parole prima della correzione
il timer sgarrava di 80us ogni 500000us,un errore
percentuale dello 0.00016 %.
Sono andato a vedere il libro
delle superiori e ho visto che i quarzi per microprocessori
hanno una *tolleranza di regolazione*
che va da 0.003% a  0.35%.
Il problema potrebbe quindi essere
nell' assumere per certo che ogni istruzione
duri esattamente 1.000000us (il doppio per i salti).
In effetti il quarzo garantisce un'ottima stabilità
in frequenza sul circuitoa cui è collegato,
ma non è detto che questa frequenza sia precisa
a quella nominale.
Tenuto conto poi della tolleranza dei condensatori
ceramici (22uF)  e della presunta modesta
qualità del quarzo ( meno di 2 euro),
non fatico a credere che il problema sia proprio
nello stadio oscillatore.
Dovrei provare con un oscilloscopio
a vedere a che frequenza oscilla il micro,
ma non c'è l'ho  :-(
e non posso eseguire la prova entro breve tempo.
Se qualcunodi Voi può e ha voglia di provare
ben venga ogni riscontro.
Non sono esperto ma magari il programma
è pure giusto !
Sul software infatti non saprei cosa cambiare.
Correggetemi se l'ho sparata grossa :-)
Ciao a tutti.


Cambiando quarzo con uno dello stesso
valore ( 4 MHz), senza altre specifche riportate,
il timer che prima andava bene con i valore
determinato sperimentalemente torna
a sballare di 2 sec circa ogni 10 ore.
E pensare che avevo scelto la
soluzione digitale per evitare la
taratura di un oscillatore RC + contatore...
Va beh...
Ciao.

Il 04 Giu 2002, 08:09, "pompeo" <
nferrare...@wind.it
    ( Remove
"NOSPAM" to replay )> ha scritto: 

mi sa che va a finire che userai il fido 555 in
configurazione astabile o un sistema con quarzo controllato in temperatura
come ti dicevo il ho risolto il problema con un bellissimo ht1380 costa un
cazzo e ha perfino il datario l'unica pegola e che devi verificare che una
volta inescato l'oscillatore sia partito realmente (in pratica controlli
che i secondi vadano avanti )
