Giorgio Demurtas Inserito: 28 settembre 2009 Segnala Share Inserito: 28 settembre 2009 Ho un display sul quale mostro la variabile velox, che vorrei vedere incrementata ogni secondo. Il problema è che il tempo non viene giusto, ma almeno 5 volte più veloce. Trattasi di un pic16f84. Ho un quarzo da 4 MHz, quindi con prescaler a 8 dovrei ottenere 1000000/8=125000 Hz.Se faccio partire il registro del timer da 131, ci vogliono 125 incrementi per mandarlo in overflow (131+125=256), e quindi eseguire l'interrupt ogni millisecondo.Conto 1000 millisecondi e incremento velox. #int_RTCC RTCC_isr() //Interrupt Service Routine { set_timer0(131); //131 così ci vogliono 125 incrementi per l'overflow millisecondi++; if (millisecondi>999) { millisecondi=0; velox++; } } funziona...ma va più veloce del previsto! Link al commento Condividi su altri siti More sharing options...
valeria.dea Inserita: 28 settembre 2009 Segnala Share Inserita: 28 settembre 2009 Forse ti sto dicendo una cosa ovvia...ma sei sicuro di averlo impostato in Timer Mode e non in Counter Mode?Magari hai qualcosa sul pin del timer che ti crea degli eventi per far scattare il contatore.Boh è un'idea.Ciao Link al commento Condividi su altri siti More sharing options...
Giorgio Demurtas Inserita: 28 settembre 2009 Autore Segnala Share Inserita: 28 settembre 2009 Non lo so, come si imposta?Comunque la sorgente dei tempi è interna. void main() { //inizio programma principale set_tris_a(0x11); //ra4 ed ra0 ingressi, tutto il resto uscite set_tris_b(0x00); setup_timer_0 (RTCC_DIV_8|RTCC_INTERNAL); //imposto il prescaler enable_interrupts(int_rtcc); //abilito l'interrupt da tmr0 enable_interrupts(global); //abilito tutti gli interrupts setup_wdt(WDT_2304MS); //impostazioni iniziali velox=0; millisecondi=0; cifra_on=1; while(1) //ciclo continuo------------------------------------------------- { .... .... Un amico mi suggeriva X= (4*Prescaler*256)/(FOSCinHz)X= (4*8*256)/(4000000) = 0.002048 secondsNel mio caso faccio (4*8*125)/4000000 = 0.001 secondie il registro lo faccio partire da 131 Link al commento Condividi su altri siti More sharing options...
accacca Inserita: 28 settembre 2009 Segnala Share Inserita: 28 settembre 2009 Non uso ne conosco molto i PIC faccio alcune osservazioni (chiedo perdono in anticipo se sono banali)1.- pag.20 datasheet T0IF dev'essere cancellato dalla proc di interruptnon si cancella automaticamente. Se non lo fai hai interrupt continuima te ne accorgeresti perchè il micro andrebbe "a rilento"2.- Sempre pagina 20 guardando il ddiagramma a blocchi ci sono poche possibilità o non hai settato il prescaler e allora dovresti vedere interrupt a F/4 oppure sospetto che la chiamata a setup_wdt ti riconfiguri il prescaler. La doc dice che è condiviso tra timer e wdt leggi a inzio paragrafo 5.2 dove chiarisce la cosa. Link al commento Condividi su altri siti More sharing options...
Jtag Inserita: 28 settembre 2009 Segnala Share Inserita: 28 settembre 2009 In effetti adesso è più chiaro , mancava una parte iniziale.....Come dice accacca credo sia colpa del wdt, se decidi di usare il prescaler per il timer non puoi usarlo per il WDT. Link al commento Condividi su altri siti More sharing options...
Giorgio Demurtas Inserita: 28 settembre 2009 Autore Segnala Share Inserita: 28 settembre 2009 eh si è proprio il WDT!Ci ero appena arrivato da solo, perchè ho fatto un programma per cambiare un uscita ad ogni interrupt, e ci ho collegato il frequenzimetro, che mi segnava sempre la stessa cosa cambiando prescaler.Allora ho cominciato a spogliare il programma lasciando solo le funzioni principali, e la prima cosa che ho tolto era proprio il WDT.Ho anche corretto il valore di partenza a 132, perchè così diventano 125 intervalli compreso quello 256>0.Comunque potrebbe andare meglio: In un minuto resta indietro di 1-2s rispetto al pc... mah, ci penserò domani!grazie per ora a tutti Link al commento Condividi su altri siti More sharing options...
Giorgio Demurtas Inserita: 29 settembre 2009 Autore Segnala Share Inserita: 29 settembre 2009 Per accelerare un pò, in modo da leggere 0.50 kHz nel frequenzimetro, faccio partire da set_timer0(135); invece che 132 teorico.Ora resta indietro 3 s in 15 minuti. Ma dovendo fare un orologio c'è modo di risolvere o questi sono i limiti di accuratezza di un pic???Mah, mi aspettavo una cosa molto più precisa, eppure il quarzo è da 4.000 MHz. Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 29 settembre 2009 Segnala Share Inserita: 29 settembre 2009 Tanto per incominciare i tuo 4MHz possono essere 3.9 o anche meno. Dipende dal quarzo e dalle capacità; potresti provare a variare il valore delle due capacità verso massa.Poi c'è un problema legato, credo, al micro. Se non hai un timer a 16 bits gli errori dovuti ai tempi di altenza dell'interrupt aquella frequenza sono più pesanti. Con un timer a 16 bit puoi aumentare il periodo a qualche decina di ms, così i tempi di servizio pesano meno.Metti la ricarica del timer subito nella prima istruzione di servizio all'interrupt.Poi se nonostante tutto questo il ritardo o l'anticipo hanno valori pressochè costanti, puoi sempre cambiare la temporizzazione per compensare l'errore Link al commento Condividi su altri siti More sharing options...
accacca Inserita: 29 settembre 2009 Segnala Share Inserita: 29 settembre 2009 (modificato) il pic è innocente dovrebbe dipende dal quarzo ma anche avesse 100ppm dovresti vedere +/-1sec ogni 2,7ore (se non ho sbagliato i conti...)come avviene il meccanismo di ricarica del counter va in overflow e riparte dal preset o devi ricaricare tu il valore?se per caricare il timer ci metti 10us e lo fai ogni millisecondoti ritrovi un ritardo di 10ms ogni secondo ciè 600ms ogni minutoche significa 3sec ogni 5minTu hai 1sec ogni 5min quindi il delay di ricarica ogni millisecondo potrebbe essere 3us bisognerbbe vedere delay per servire isr e che istruzioni asm fa realmente per calcolare il ritardo essatto fino alla ricarica del preset. Modificato: 29 settembre 2009 da accacca Link al commento Condividi su altri siti More sharing options...
Jtag Inserita: 29 settembre 2009 Segnala Share Inserita: 29 settembre 2009 In alternativa, ma un po' più dispendioso, puoi utilizzare una base dei tempi esterna, che ovviamente sia più precisa Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 29 settembre 2009 Segnala Share Inserita: 29 settembre 2009 (modificato) Non è questione di precisione del quarzo, è questione dell'equivalente capacitivo dell'intero oscillatore.100 parti per milione totali, per un quarzo comune, con un oscillatore a saturazione come quelli dei dispositivi numerici, senza nessuna compensazione per temperatura, è già una bella precisione. Nello specifico sarebbero solo 400Hz di errore massimo.In gioventù progettavo apparati per telcomunicazioni e avionica, una certa esperienza, con questi dispositivi, me la sono fatta. Bastano pochi pF in più o meno per avere spostamenti di frequenza anche maggiori.Con qurzo a 4MHz dovrebbe essere necessario 1us, perchè necessita uan sola istruzione. Dipende se è la prima istruzione della routine o meno. Se il timer fosse un 16bit come, ad esempio, quello che si usa per i 16f877, il ritardo va ad influenzare uan base tempi di almeno un ordine di grandezza maggiore, quindi l'imprecisione totale diminuisce. Modificato: 29 settembre 2009 da Livio Orsini Link al commento Condividi su altri siti More sharing options...
Giorgio Demurtas Inserita: 29 settembre 2009 Autore Segnala Share Inserita: 29 settembre 2009 Ah, ok, è normale, mi consolo. Nella routine di interrupt la prima cosa che faccio è ricaricare il timer.Il TMR0 del 16F84 è a 8 bit. Di fatto ho fatto così. Lascio un uscita sulla quale leggere la frequenza di interrupt, e risistemo il valore da caricare nel registro del timer. Girovagando per la rete ho trovato che un Real time clock, che visto il prezzo (~2€) è fenomenale!The DS1307 serial real-time clock (RTC) is a low-power, full binary-coded decimal (BCD) clock/calendar plus 56 bytes of NV SRAM. Address and data are transferred serially through an I²C, bidirectional bus. The clock/calendar provides seconds, minutes, hours, day, date, month, and year information. The end of the month date is automatically adjusted for months with fewer than 31 days, including corrections for leap year. The clock operates in either the 24-hour or 12-hour format with AM/PM indicator. The DS1307 has a built-in power-sense circuit that detects power failures and automatically switches to the backup supply. Timekeeping operation continues while the part operates from the backup supply. Link al commento Condividi su altri siti More sharing options...
Messaggi consigliati
Crea un account o accedi per commentare
Devi essere un utente per poter lasciare un commento
Crea un account
Registrati per un nuovo account nella nostra comunità. è facile!
Registra un nuovo accountAccedi
Hai già un account? Accedi qui.
Accedi ora