Newsgroup: it.hobby.elettronica.digitale
Titolo: Ritardi errati

Un cordiale saluto a tutti coloro che leggono questo messaggio.
Chiedo il vostro aiuto sottoponendovi un problema al quale non riesco a
trovare una soluzione. In pratica ho l'esigenza di generare un segnale ad
onda quadra con periodo pari a 80 microsecondi, ho pensato quindi di
utilizzare un PIC-16F84 predisposto con l'oscillatore quarzato a 4 Mhz ed
opportuno software di mia realizzazione. Purtroppo visualizzando
all'oscilloscopio il segnale in uscita dal pin 1 del PIC, mi ritrovo con un
segnale di 92 microsecondi, inaccettabile per l'uso che devo farne. Di
seguito troverete il file ASM, sarò grato a chi mi aiuterà a capire da dove
saltano fuori questi 12 microsecondi in più ed a correggere l'errore.
Attendo fiducioso e grazie per l'attenzione. Saluti da Franco.
;**************************
;
; TEST-TIMER.ASM
;
; FRANCO
;**************************
PROCESSOR 16F84
RADIX DEC
INCLUDE "P16F84.INC"
          __CONFIG 3FF1H
             ORG 00H
             GOTO      VIA
             ORG 04
INT
              MOVLW     4                   ; inverte lo stato del pin 1
              XORWF     PORTA,F
              MOVLW     251               ; tmr0 divide per 5 (5=256-251)
              MOVWF     TMR0
              BCF           INTCON,2
              BSF            INTCON,7
              RETFIE
VIA
               BSF            STATUS,RP0    ; f.clock = 1Mhz=4Mhz / 4
                                                               ; cioè 1
microsec. all'ingresso del prescaler
               MOVLW     2                          ; il n° 2 dice al
prescaler di dividere per 8
               MOVWF     OPTION_REG   ; il tmr0 divide per 5, quindi in
totale otterremo
               MOVLW     0                          ; 40 microsec. (40=8*5)
per 2 semiperiodi =80 microsec.
               MOVWF     TRISA
               BCF            STATUS,RP0
               BSF             INTCON,5
               BSF             INTCON,7
               MOVLW      251                    ; il tmr0 divide per 5
(5=256-251)
               MOVWF      TMR
TEMPO
                NOP
                GOTO          TEMPO
                END

 segnale di 92 microsecondi, inaccettabile per l'uso che devo farne. Di
Hai considerato il tempo di esecuzione delle istruzioni?
Per me dovresti togliere dal timer la durata delle istruzioni eseguite in
interrupt.
Ciao

Non sono abbastanza sveglio per verificare il tuo programmino,
ma posso dirti che se hai bisogno di temporizzazioni precise
non devi usare gli interrupt, perche' avresti inevitabilmente dei
jitter. Ti conviene fare da programma dei cicli vuoti di ritardo,
visto che il micro resterebbe comunque in attesa.
Con i PIC la cosa e' piuttosto semplice, visto che tutte
le istruzioni impiegano lo stesso tempo.
Luigi

"luigi funes"   ha scritto nel messaggio

Non sono per niente d'accordo, quando servono temporizzazioni molto precise
il timer è un must, basta farsi bene i conti con i tempi d'esecuzione delle
routine di gestione dell'interrupt.
Usando correttamente il timer l'errore massimo che si può ottenere è pari a
+/- 1 ciclo macchina, questo perchè l'interrupt latency time è compreso tra
3 o 4 cicli macchina a seconda del momento in cui si verifica l'evento.
Accidentalemente se si usano i timer+interrupt è possibile nel frattempo
fare tante altre cose, tipo leggere porte o calcoli vari senza sprecare
inutilmente il tempo cpu (che nelle MCU è prezioso) per fare degli inutili
loop software.
P.S.
Non è completamente vero che tutte le istruzioni dei PIC vengono fatte in un
solo ciclo di clock, alcune (pochissime) richiedono 2 cicli tipo la 'goto'
oppure la 'return'
--
Ciao
Marco d'Ambrosio  
m.dam...@libero.it
http://www.razzimodellismo.it
    ACME I-RM-05 / TRA #08224 L1
http://web.tiscalinet.it/mda
http://digilander.iol.it/robotica
 (under construction)

 Attendo fiducioso e grazie per l'attenzione. Saluti da Franco.
Basta che ti conti le istruzioni di gestione interrupt gli aggiungi i cicli
macchina necessari al PIC per eseguire l'int e guarda caso magicamente
vengono fuori i 12us in pił che ti ritrovi.
Quando fai un ciclo di questo tipo devi assolutamente conteggiare il tempo
d'esecuzione per la routine d'interrupt e sottrarlo dal conteggio del timer,
cosa non sempre facile da fare.
Nel tuo caso hai commesso anche l'errore di usare il prescaler che per 80us
non ti serve, carica direttamente il valore 34 (corretto del tempo
d'interrupt) nel timer0 e vedrai che funziona senza problemi.
P.S.
Potrei anche avere toppato nel calcolare il valore da caricare nel timer
visto che sono le 1 di notte e il sonno avanza ma penso che hai capito il
concetto e nel caso sia sbagliato ora sei in grado di trovarti quello
corretto da solo.


Ricordati che quando assegni un valore al tmr0 , non vieneincrementato
per due cicli successivi, 
penso che basterebbe mettere un po di nop e riuscirai ne tuo intento.
Io sono riuscito a creare delle onde quadre da 13 micro secondi senza
troppi problemi  (dovevo implementare un trasmettitore Ir)

 d'interrupt) nel timer0 e vedrai che funziona senza problemi.
Purtroppo del prescaler non posso farne a meno mi serve per altre
temporizzazioni sempre all'interno di questo programmino.
Saluto e ringrazio...FRANCO

Ciao Lad, grazie per il tuo intervento, non ho capito bene se per i tuoi 13
microsec. hai usato l'irq oppure no. In ogni caso, se ti va prova a
modificare il mio file ASM in modo da ottenere la temporizzazione richiesta;
naturalmente usando anche il prescaler.
Saluti da Franco.

Una domanda stupida... hai verificato l'effettiva frequenza dell'oscillatore
(4 MHz) ?

Ciao...Naturalmente posso garantire sull'affidabilità della strumentazione e
del quarzo usati....ciao da Franco

