Niki77 Inserito: 16 gennaio 2004 Segnala Inserito: 16 gennaio 2004 Salve a tutti,sono nuovo di questo forum,però non nuovo alla programmazione di picmicro ed elettronica in genere ,quindi non vi allarmate!!!Volevo porvi un quesito.Premesso che ho una scheda con un pic16f84 , con un quarzo da 4mhz (ma anche 8mhz,insomma di valore intero),senza clock esterno riesco a ricavare un clock ideale per un eventuale applicazione che corrisponda a 1 centesimo di secondo esatto?Io ho provato in vari modi ma la temporizzazione precisa non la sono mai riuscita a trovare.Ho provato a programmare il prescaler e a sfruttare l'interrupt generato dal tmr0,ho provato con cicli di ritardo etc etc e prima di passare all'estremo rimedio(sostituzione del quarzo o aggiunta di clock esterno) volevo sapere se qualcuno di voi ha un idea.Ringrazio chi eventualmente risponderà.
Mauro Rubinetti Inserita: 16 gennaio 2004 Segnala Inserita: 16 gennaio 2004 Per usare 8Mhz devi avere il PIC da 20Mhz perchè quello normale è <= 4Mhz.Per ottenere la precisione nel conteggio del tempo occorre fare in primo luogo attenzione ai cicli macchina che vengono utilizzati dal micro per compiere le istruzioni (ci sono istruzioni da 1 ciclo da 2 cicli ecc) che andranno sottratte dal ciclo che utilizzi.Se calcoli i millisecondi e hai una routine nell'nterruped che richiede 10 cicli macchina dovrai resettare il contatore all'incirca a 990 mS.Un altro problema è comunque che bisogna attuare una correzzione (quasi sicuramente ogni mezzo secondo) o per lo meno è quello che ho dovuto fare per avere le precisioni che mi servivano in un arco di tempo di circa sette ore di conteggio.Non ho mai provato a far funzionare il mio circuito in continuo e non sò se mi dia errori significativi, ma ad oni modo si potrebbero correggere.Buon lavoro
ifachsoftware Inserita: 16 gennaio 2004 Segnala Inserita: 16 gennaio 2004 fare in primo luogo attenzione ai cicli macchina che vengono utilizzati dal micro per compiere le istruzioni (ci sono istruzioni da 1 ciclo da 2 cicli ecc)
bit Inserita: 16 gennaio 2004 Segnala Inserita: 16 gennaio 2004 Niente correzioni! Il clock preciso si riesce a ottenere tranquillamente.Supponiamo di avere un quarzo da 4 Mhz, il tempo di ciclo sarà 1 us. Dunque noi dobbiamo dividere la frequenza di ciclo (1 Mhz) per 10000.Non si può utilizzare il timer0 per tutta la sua capacità di conteggio (256) poichè il prescaler dovrebbe dividere per un valore decimale (10000 / 256 = 39.06) e ciò è impossibile.E' necessario utilizzare il prescaler per portare il fattore di divisione del timer0 al di sotto di 256, poi il valore del timer verrà settato nuovamente ad ogni ciclo di interrupt. Eventualmente, se il valore del prescaler non risulta essere una potenza di 2 si può creare un postscaler software nel vettore di interruzione.Ad esempio per ottenere la divisione per 10000 si possono utilizzare i seguenti valori:prescaler timer0: 16ciclo timer0: 125postscaler software: 5Per un totale di 16 x 125 x 5 = 10000 cicli macchina esatti!Il prescaler basta settarlo una volta per tutte, il timer0 va reimpostato ad ogni ciclo di interrupt.Poichè il conteggio è avanti e l'interrupt viene generata al passaggio da 255 a 0 (256) il conteggio dovrà partire da 256 - 125 = 131. Poichè non è possibile ricaricare istantaneamente il timer0 appena si verifica l'interrupt useremo un trucchetto: Carichiamo il timer0 con un valore maggiore di 1 unità, compensando il ciclo mancato con dei ritardi nel vettore di interruzione.Ammettiamo che il vettore di interruzione cominci così:ORG 0x04MOVWF ACC_W ;salvataggio accumulatoreMOVF STATUS,WMOVWF ACC_ST ;salvataggio statusBCF INTCON,0x02 ;reset bit interrupt timer0.....MOVLW 0x84 ;valore partenza timer (132d)MOVWF TMR0 ;settaggio timer0Abbiamo tolto un ciclo di conteggio del timer0, che con un prescaler di 16 corrisponderanno a 16 cicli macchina, che dovremo reintrodurre per avere un clock preciso.Ricordando che il timer0 inizia a contare 2 cicli macchina dopo che è stato settato calcoliamo il ritardo introdotto dalle istruzioni che abbiamo già scritto:Chiamata interrupt: 2 usIstruzioni di salvataggio: 3 usReset bit interrupt: 1 usImpostazione valore timer e caricamento timer0: 2 usRitardo inizio conteggio: 2 usPer un totale di 10 us.Inseriamo allora 6 istruzioni di NOP per raggiungere il ritardo di 16 cicli macchina.Il vettore di interruzione diventerà quindi:ORG 0x04MOVWF ACC_W ;salvataggio accumulatoreMOVF STATUS,WMOVWF ACC_ST ;salvataggio statusBCF INTCON,0x02 ;reset bit interrupt timer0NOPNOPNOPNOPNOPNOPMOVLW 0x84 ;valore partenza timer (132d)MOVWF TMR0 ;settaggio timer0Per riprova:Il timer0 conterà da 132 a 256 quindi per 124 impulsi del prescaler. Ogni impulso del prescaler ha una durata di 16 us e quindi il tempo di conteggio del timer0 è di 124 x 16 = 1984 us che sommati ai 16 us che intercorrono tra il momento in cui andiamo in interrupt e il momento in cui ricomincia il conteggio fanno esattamente 2000 us.Se in interrupt realizziamo un postscaler software che divida per 5 otteniamo esattamente 10000 us pari a 1/100 di secondo.Il postscaler può essere così realizzato:DECFSZ POSTSCALER,f ;CONTEGGIO CICLI DI INTERRUPTGOTO FINEINTERRUPTMOVLW 0x05 ;SETTAGGIO NUMERO CICLI DI INTERRUPT (5)MOVWF POSTSCALERPuò andare bene?Ciao a tutti!
k6233 Inserita: 17 gennaio 2004 Segnala Inserita: 17 gennaio 2004 Ciao Nicola,Come ti ho detto per telefono ti ho inviato il programma picdelay.Genera delle routine di ritardo in base al tempo che vuoi ed al quarzo che usi.Se il pic deve fare solo questo puoi evitare di usare interrupt ma fare un programma ciclico.Il codice generato è in asm comunque puoi inserirlo anche sul pic basic (visto che lo usi)CiaoMarco
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