PIC e timer1

Ho un pic16f877a con quarzo a 14,318180 MHz Qualcuno sa darmi una formula che mi permetta di calcolare il numero da scrivere nel "timer 1" in modo che la ISR venga chiamata ogni "x" microsecondi? Nello specifico vorrei che la isr del timer_1 venisse chiamata 1 volta al secondo, solo che con questo quarzo i conti dovranno essere approssimati.... l'errore che si commette è cumulativo? Il valore da scrivere nel timer_1 lo devo scrivere dall'interno della isr? Come devo impostare il postscaler (in C ho a disposizione t1_div_by_1, _2, _4, _8_, _16)

Avrete capito che con i timer sono alle prime :) Grazie per la pazienza Ciao!

Reply to
ice
Loading thread data ...

"ice" ha scritto

Se un errore si ripete continuamente si accumula per forza... ma il problema non e' solo quello, piuttosto una meraviglia dei timer dei pic che recita cosi' "the prescaler counter is cleared on writes the TMR1H or TMR1L registers". In pratica ogni volta si perdono anche tutti gli impulsi conteggiati dal prescaler tra il momento dell'overflow del timer e il momento in cui lo si ricarica :((((((((((((((((((((

Claudio F

Reply to
Claudio F

approssimati....

lo

Sto studiando il timer1 proprio in questi giorni, percio' quello che dico potrebbe essere sbagliato. L'interrupt viene attivato al passaggio da FFFF a 0. Percio' tu basta che nella tua isr carichi il contatore con un valore opportuno, anche se col quarzo che stai usando sara' molto difficile ottenere un valore intero. Pero' c'e' un altro problema. La isr in certe situazioni non viene chiama immediatamente, a volte anche con notevole ritardo se il micro e' in sleep o se se l'interrupt era disabilitato in quel momento. In questi casi la isr andra' a scrivere il contatore che nel frattempo aveva continuato ad andare avanti, e questo causa degli errori nelle temporizzazioni. Sinceramente non so come si possa risolvere questo problema, forse sommando al valore del contatore la costante invece di caricarla direttamente, ma non mi pare che nemmeno cosi' ci sia la certezza di non perdere dei cicli. E il prescaler viene resettato quando si scrive il timer? Devo informarmi meglio!

Reply to
Valeria Dal Monte

approssimati....

lo

Ho guardato la documentazione e purtroppo non ci sono speranze. Se vuoi usare il timer1 per attivare una isr per tenere il tempo con precisione, devi lasciare andare il contatore senza mai riscriverlo altrimenti perdi dei conteggi. Questo significa che per avere una isr chiamata una volta al secondo devi usare un quarzo di una frequenza che abbia un fattore pari a 65536. Oppure devi correggere l'errore via software, ma in questo caso a breve termine avrai sempre delle imprecisioni.

Reply to
Valeria Dal Monte

"Valeria Dal Monte" ha scritto

Che e' quello che si fa di solito... tuttavia potrebbe esserci un'altra possibilita', non ne sono sicuro, ma evitando il prescaler come la peste forse si potrebbe costruire una routine che prima di scrivere nel TMR1 legge il valore gia' raggiunto e ricalcola di conseguenza il valore da scrivere... tenendo conto naturalmente della possibilita' di un overflow della parte bassa (visto che i due registri che compongono il timer devono essere letti separatamente)... a questo punto si conoscerebbe il valore del timer all'istante n e la quantita' di istruzioni (cicli macchina) da noi usate per questa operazione di aggiustamento.

Claudio F

Reply to
Claudio F

Intanto: grazie a tutti per le risposte!

Ma esistono quarzi con fattore 65536? Per me è ok usare anche il timer0 o il timer2. Il mio problema è riuscire a calcolare quanti impulsi arrivano in un determinato tempo (una specie di frequenzimetro). Se la bese tempi è 1 secondo ho già la frequenza in hz ma sono disposto a cambiare se mi dite che è il caso. Per il conteggio impulsi uso l'int0. Anche se il risultato non è molto preciso (diaciamo con un errore del 10%) a me va bene. Avete qualche consiglio?

Ancora grazie Ciao!

Reply to
ice

Probabilmente si', ma non sono molto comuni. Gli unici molto usati sono quelli da 32768 Hz che pero' ti darebbero un interrupt ogni 2 secondi esatti. Il progettino a cui sto lavorando usa proprio uno di questi quarzi per mantenere un orologio in tempo reale con il micro in sleep.

a

In questo caso il problema e' diverso. Potresti usare un timer per contare gli impulsi e l'altro per misurare il tempo, cosi' non sei legato ad una particolare frequenza del quarzo. Per esempio, con il quarzo da 14,318180 MHz hai un clock di 3,579545 MHz. Percio' basta che conti quanti impulsi arrivano ad un contatore nel tempo necessario all'altro contatore per arrivare a 3.579.545. Puoi gestire gli overflow direttamente da software senza usare l'interrupt. In questo modo hai una precisione migliore perche' non hai i problemi di latenza degli interrupt. Ad ogni modo ci sono moltre altre soluzioni.

Reply to
Valeria Dal Monte

Grazie per la dritta! Per il momento ho ottenuto buoni risultati usando il timer2 per conteggiare il tempo mentre impiego il polling per contare gli impulsi. Funziona molto bene e visto che il pic è dedicato solo a questo compito non mi preoccupo di overhead ecc, ecc... Imposto il timer 2 così: setup_timer_2(T2_DIV_BY_16,249,16); In questo modo ottengo 14318180/(4*16*249*16)=56 interrupts al secondo. Conteggio gli interrupts all'interno della ISR del timer2 e qundo ne ho contati 7 so di aver ricevuto, estrapolando, (tot_pulses*8) impulsi (7*8=56) In questo modo ho un refresh sufficientemente veloce! Ti chiedo un'altra cosa: sapresti dirmi come mai la frequenza del quarzo va sempre divisa per 4 quando si fanno i calcoli con i timers? Oltre a dividerla per il postscaler e tutto il resto, si intende...

Grazie ancora Ciao!

Reply to
ice

Il giorno Tue, 13 Apr 2004 13:06:12 GMT, "ice" ha scritto:

Perchè il generatore di clock interno dei pic divide per 4 la frequenza dell'oscillatore, per cui la frequenza del segnale di clock interno del micro è pari a quella del clock esterno diviso 4.

Reply to
Luigi C.

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.