Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Ottenere 1 Hz precisissimo, 16f84a

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[51] Re: Ottenere 1 Hz precisissimo, 16f84a

Messaggioda Foto Utentecarlomusumeci » 7 apr 2015, 17:59

ciao a tutti,e grazie...tra le tante proposte non so piu' quale intraprendere...
una domanda a Foto Utentec1b8 se come proponi tu,inizializziamo il tmr0 a 101,e ogni volta che si dovrà inizializzare si perderanno 2 cicli macchina,non sarebbe meglio inizializzarlo a 99 ? e conviene inizializzarlo dentro la routine dell'interrupt?
Foto UtenteIsidoroKZ,mi potresti spiegare come fare ad alternare le 9 volte di inizializzazione a 61 e le (244 erano?) inizializzazioni a 62?
tramite codice,magari solo la parte che riguardo solo questo procedimento, e se inserirlo dentro o fuori l'interrupt

[user]dadituri[/user],per contare 1000 interrupt dovrei utilizzare 4 registri,tra cui l'ultimo di questi registri inizializzato a 232 giusto? 256+256+256+232=1000 decrementi,

Vorrei provare entrambi i metodi...
Scusate le varie domande,ma solo così capisco il da farsi :-)
Avatar utente
Foto Utentecarlomusumeci
353 5 7
Sostenitore
Sostenitore
 
Messaggi: 526
Iscritto il: 8 apr 2011, 0:35

0
voti

[52] Re: Ottenere 1 Hz precisissimo, 16f84a

Messaggioda Foto Utentec1b8 » 7 apr 2015, 18:13

Rispondo velocemente perché ora non ho molto tempo, se serve approfondiamo più tardi.
Il TMR0 deve essere inizializzato ogni volta dentro la routine di interrupt. L'interrupt scatta quando TMR0 diverta 0, se non lo inizializiamo nuovamente (quindi nella routine), non eseguirà più il numero di conteggi che desideriamo ma genererà un interrupt dopo 256 conteggi.
Il tempo che viene perso per ricaricare il TMR0 (quei 2 us) è una parte dei 40us che dicevo la routine di interrupt deve perdere. Ma non ci sono solo questi 2us da considerare. Ci sono anche il tempo necessario a salvare i registri per evitare di "incasinare" il normale flusso del programma ed il tempo che il micro necessita per servire l'interrupt. Questo ultimo tempo è quello che si discuteva con Foto UtenteIsidoroKZ non essere costante ma poter variare (per qunto ne so io) tra i 3 e i 4 us ad ogni interrupt.
Fabio
Avatar utente
Foto Utentec1b8
3.595 3 8 13
G.Master EY
G.Master EY
 
Messaggi: 1770
Iscritto il: 15 gen 2009, 15:23

0
voti

[53] Re: Ottenere 1 Hz precisissimo, 16f84a

Messaggioda Foto Utentecarlomusumeci » 7 apr 2015, 18:53

Credo di aver capito,ho scritto il codice (solo parte interrupt allegata) per la soluzione che adotteresti tu Foto Utentec1b8,giusta la sequenza all'interno dell'interrupt?
Codice: Seleziona tutto
ORG    0x0
RES   CONT_INT   1; VARIABILE PER CONTARE GLI INTERRUPT
RES   UNITA       1;VARIABILE INCREMENTO UNITA
ORG   0X00
   GOTO   START
;_____________________________________________________________________________________________
ORG   0X04      ;VETTORE INTERRUPT

CONTA
   DECFSZ   CONT_INT       ;DECREMENTA IL CONTA INTERRUP E SE VALE;
   GOTO    CONTA            ;NON E' ZERO CONTINUA A DECREMENTARE
RITORNA   ;SE ZERO INIZIALIZZA NUOVAMENTE TIMER E INCREMENT UNITA
        MOVLW   D'200'             
   MOVWF   CONT_INT         ;CARICA IL CONTA INTERRUPT A 200
   MOVLW   D'101'        
   MOVWF   TMR0                 ;REINIZIALIZZA TMR0 A 101
   INCF   UNITA                ;INCF UNITA
   BCF   INTCON,TOIF   ;AZZERA FLAG INTERRUPT DOVUTO A FINE CONT TIMER0
   RETFIE
;_____________________________________________________________________________________________

START
...
...
   MOVLW   B'00000100'       ;ASSEGNA PRESCALER :32 E LAVORA CON FOSC4MHZ
   MOVWF   OPTION_REG
   MOVLW    B'10100000'                  ;ABILITA 'GENERALE INTER' E INTER DOVUTO A FINE CONT TMR0
   MOVWF   INTCON
...
...
...
;MULTIPLEXAGGIO E INCREMENTO MINUTI ORE ECC
Avatar utente
Foto Utentecarlomusumeci
353 5 7
Sostenitore
Sostenitore
 
Messaggi: 526
Iscritto il: 8 apr 2011, 0:35

0
voti

[54] Re: Ottenere 1 Hz precisissimo, 16f84a

Messaggioda Foto UtenteDarioDT » 7 apr 2015, 20:56

Purtroppo quel poco che faccio lo faccio in c! :(
Non credo di poterti aiutare.....
Ciao,
Dario
ƎlectroYou e non smetti mai di imparare!
Avatar utente
Foto UtenteDarioDT
5.080 4 8 13
Master
Master
 
Messaggi: 1220
Iscritto il: 16 apr 2012, 20:13
Località: Bari

0
voti

[55] Re: Ottenere 1 Hz precisissimo, 16f84a

Messaggioda Foto Utentecarlomusumeci » 7 apr 2015, 21:00

vabene grazie ugualmente :D attendo l'intervento di Foto UtenteIsidoroKZ e Foto Utentec1b8
Avatar utente
Foto Utentecarlomusumeci
353 5 7
Sostenitore
Sostenitore
 
Messaggi: 526
Iscritto il: 8 apr 2011, 0:35

1
voti

[56] Re: Ottenere 1 Hz precisissimo, 16f84a

Messaggioda Foto UtenteIsidoroKZ » 7 apr 2015, 21:32

carlomusumeci ha scritto:Foto UtenteIsidoroKZ,mi potresti spiegare come fare ad alternare le 9 volte di inizializzazione a 61 e le (244 erano?) inizializzazioni a 62?


Devi usare un po' di variabili locali nella routine di interrupt, variabili che alla partenza vengono inizializzate dal main, poi vengono reinizializzate dentro la routine di interrupt. Il modo piu` generale e` quello di fare una tabella in cui nella prima voce indichi quante volte deve essere ripetuta la divisione e nella seconda voce metti il divisore: ad esempio

55 61
02 62
55 61
02 62
27 61
01 62
55 61
02 62
55 61
02 62

Poi usi un contatore che conta a che riga sei arrivato. Parti dalla prima e fai 55 divisioni per 61 (avevo scritto 62 al posto di 61!), poi quando hai finito incrementi il contatore arrivi alla riga dopo che dice 2 divisioni da 62... quando sei alla fine della tabella ricominci da capo.

Foto Utentec1b8 stavo considerando che se hai un microsecondo di errore random a ogni chiamata di interrupt, in un giorno in media vai in ritardo di piu` di 8s e non sono recuperabili perche' la quantizzazione del contatore non lo permette. Se l'OP lo usa per tempi brevi va bene, ma su tempi lunghi l'errore introdotto dall'incertezza e` maggiore di quello tipico del quarzo.
Per usare proficuamente un simulatore, bisogna sapere molta più elettronica di lui
Plug it in - it works better!
Il 555 sta all'elettronica come Arduino all'informatica! (entrambi loro malgrado)
Se volete risposte rispondete a tutte le mie domande
Avatar utente
Foto UtenteIsidoroKZ
113,9k 1 3 8
G.Master EY
G.Master EY
 
Messaggi: 19951
Iscritto il: 17 ott 2009, 0:00

0
voti

[57] Re: Ottenere 1 Hz precisissimo, 16f84a

Messaggioda Foto Utentecarlomusumeci » 7 apr 2015, 22:36

in linea generale,ho capito come fare,solo che non ho mai fatto una tabella che indichi quante volte incrementare di un certo valore il registro x...domani vedo in qualche libro se trovo esempi di tabelle(o altro per fare questo lavoro),potrei utilizzare il registro PCL per contare...vedo come fare,grazie mille comunque
Avatar utente
Foto Utentecarlomusumeci
353 5 7
Sostenitore
Sostenitore
 
Messaggi: 526
Iscritto il: 8 apr 2011, 0:35

0
voti

[58] Re: Ottenere 1 Hz precisissimo, 16f84a

Messaggioda Foto Utentec1b8 » 7 apr 2015, 22:39

Certo, 8s di errore in un giorno sono troppi. Non avevo fatto questo calcolo. Va detto che l'interruput viene servito in 3us se il micro viene interrotto durante una "normale" istruzione, e in 4us se viene interrotto durante una istruzione di salto. Considerando che in un programmi i salti dovrebbero essere numericanente inferiori alle altre istruzioni e che un interrupt si verifichi proprio durante un salto non dovrebbe essere così sistematico, probabilmente l'errore sarà inferiore a 8s in un giorno. È sicuramente vero che non è quantificabile e quindi, come giustamente sottolinei, potrebbe non essere accettabile.
Fabio
Avatar utente
Foto Utentec1b8
3.595 3 8 13
G.Master EY
G.Master EY
 
Messaggi: 1770
Iscritto il: 15 gen 2009, 15:23

0
voti

[59] Re: Ottenere 1 Hz precisissimo, 16f84a

Messaggioda Foto UtenteGuidoB » 8 apr 2015, 1:02

Ciao Foto Utentecarlomusumeci, prova a guardare anche la discussione "Un orologio con un PIC 16F628a sarà preciso?" di sette mesi fa.

La migliore soluzione che avevo trovato per casi di questo genere era quella di usare un "trimmer software" (almeno, io l'avevo chiamato così), ed è descritta in questo intervento. Si possono compensare errori sistematici e ottenere facilmente accuratezze di calcolo di poche parti per miliardo, cioè dell'ordine di decimi di secondo all'anno. È bene usare un timer che si autoricarica alla scadenza.

A questo punto l'errore maggiore verrebbe dalle derive termiche del quarzo. Potresti però stabilizzare la temperatura del quarzo con un elemento riscaldante (e/o raffreddante) e un termostato.

Per ottenere una precisione ancora maggiore in modo economico, credo che dovresti sintonizzarti su qualche portante di radiotrasmettitore agganciata a frequenze generate con orologi atomici.

O_/
Big fan of ƎlectroYou!
Avatar utente
Foto UtenteGuidoB
16,2k 7 12 13
G.Master EY
G.Master EY
 
Messaggi: 2461
Iscritto il: 3 mar 2011, 16:48
Località: Madrid

0
voti

[60] Re: Ottenere 1 Hz precisissimo, 16f84a

Messaggioda Foto Utentecarlomusumeci » 8 apr 2015, 14:38

Grazie a tutti :) a una mattinata che ci ragiono su,ho usato tutti i vostri consigli per mettere in pratica quello di Foto UtenteIsidoroKZ

allora,,,ho creato 4 Variabili

61O62 ;se il bit 0 di questo registro vale 1 incrementa a 62,se 0 increm a 61.
CONT_INT ;registro che conta se sono avvenute 61 o 62 interrupt
CONT_147 ;registro che conta le volte che ha inizializzato il contatore di interrupt a 61
CONT_8 ;registro che conta le volte che ha inizializzato il contatore di interrupt a 62


e poi nel main si tiene conto di quante volte si deve inizializzare a 61 o 62, il registro che conta gli interrupt (CONT_INT)

tramite questo marchingegno...
Codice: Seleziona tutto
MAIN
147VOLTE   
   BCF   61O62,0   ;poni a 0 il bit 0 di 61O62
   MOVLW   8
   MOVWF   CONT_8    ;mantieni inizializzato a 8 ,CONT_8
   DECFSZ CONT_147;decrementa
   GOTO 147VOLTE    ;ripeti per 147 volte
8VOLTE            ;ho ripetuto per 147 volte inizializzazione a 61
   BSF   61O62,0    ;inizializza a 62
   DECFSZ   CONT_8    ;conta 8 inizializzazioni a 62
   GOTO      8VOLTE   ;conta fino a 8 inizializzazioni
   MOVLW   147
   MOVWF   CONT_147 ;reinizializza le 147 volte a 61
   
;vedere che valore dare a CONT_INT
   BTFSS   61O62,0    ;se  61O62 (nome variabile);
   MOVLW   61   ;vale 0 decrementa da 61
   MOVLW   62    ;vale 1 decrementa da 62
   MOVWF   CONT_INT

continuo col programma...


e dentro la routine degli interrupt una cosa semplice semplice


;inizio interrupt
ORG 0X04;INTERRUPT
CONTA6X
DECFSZ CONT_INT ;decrementa conta interrupt
GOTO CONTA6X
INCF UNITA ;incrementa unità
BCF INTCON,TOIF;azzera flag overflow tmr0
RETFIE
;fine interrupt


spero che in questo modo va...ho il dubbio che se inizializzando CONT_147 a 147... e CONT_8 a 8... in realta decrementino uno da 148 e uno da 9.. o sbaglio

ho cercato di commentare al meglio tutto...
spero di aver capito...che ne pensate Foto UtenteIsidoroKZe Foto UtenteGuidoB?

allego codice messo in sequenza
Codice: Seleziona tutto
147 volte 61
8 volte 62
_______________________METODO ISIDOROKZ_________________________
61O62          ;se il bit 0 di questo registro vale 1 incrementa a 62,se 0 increm a 61.
CONT_INT   ;registro che conta se sono avvenute 61 o 62 interrupt
CONT_147   ;registro che conta le volte che ha inizializzato il contatore di interrupt a 61
CONT_8      ;registro che conta le volte che ha inizializzato il contatore di interrupt a 62
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ORG 0X00
     GOTO   INIZIO
;___________________________________________

;inizio interrupt
ORG 0X04;INTERRUPT
CONTA6X
     DECFSZ   CONT_INT     ;decrementa conta interrupt
     GOTO     CONTA6X     
     INCF      UNITA         ;incrementa unità
     BCF      INTCON,TOIF;azzera flag overflow tmr0   
     RETFIE       
;fine interrupt   
;____________________________________________

INIZIO
   MOVLW   B'00000100'       ;imposta il prescaler a 64
   MOVWF   OPTION_REG
   MOVLW    B'10100000'      ;imposta interrupt su overflow tmr0
   MOVWF   INTCON

MAIN
147VOLTE   
   BCF   61O62,0   ;poni a 0 il bit 0 di 61O62
   MOVLW   8
   MOVWF   CONT_8    ;mantieni inizializzato a 8 ,CONT_8
   DECFSZ CONT_147;decrementa
   GOTO 147VOLTE    ;ripeti per 147 volte
8VOLTE            ;ho ripetuto per 147 volte inizializzazione a 61
   BSF   61O62,0    ;inizializza a 62
   DECFSZ   CONT_8    ;conta 8 inizializzazioni a 62
   GOTO      8VOLTE   ;conta fino a 8 inizializzazioni
   MOVLW   147
   MOVWF   CONT_147 ;reinizializza le 147 volte a 61
   
;vedere che valore dare a CONT_INT
   BTFSS   61O62,0    ;se  61O62 (nome variabile);
   MOVLW   61   ;vale 0 decrementa da 61
   MOVLW   62    ;vale 1 decrementa da 62
   MOVWF   CONT_INT

continuo col programma...




   
Avatar utente
Foto Utentecarlomusumeci
353 5 7
Sostenitore
Sostenitore
 
Messaggi: 526
Iscritto il: 8 apr 2011, 0:35

PrecedenteProssimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 5 ospiti