+ Rispondi
Risultati da 1 a 2 su 2

Discussione: PIC ed il timer0

  1. #1

    Iscritto dal
    12/02/2012
    Località
    Genova
    Messaggi
    174

    PIC ed il timer0

    Quello che segue è un'articolino che avevo scritto qualche anno fa per un forum, mi era stato pubblicato ma poi cancellato.
    Lo metto qui sperando che a qualcuno possa venir bene, mi dispiace che una fatica venga sprecata.
    Avevo anche scritto un tutorial per l'assembly del PIC che dopo alcuni spostamenti di sito è sparita dalla rete.
    Camillo

    Il timer 0 nel calcolo "preciso" del tempo.

    Il timer 0 è il più antico tra quelli presenti nei PIC attuali, è già presente nei primi PIC (16C5x) dove, essendo l'unico, si chiama RTCC (Real Time Clock/Counter). La sua struttura è rimansta invariata da allora, la troviamo anche nei PIC della serie 18 ma non più nei PIC a 16bit (serie 24 e 30).

    Il suo funzionamento è legato al registro TMR0 e a 6 bit di controllo che si trovano nel registro OPTION, che diventa T0CON nella serie 18 dove TMR0 è a 16 bit.
    I controlli del timer sono:
    PSA assegna il prescaler al timer oppure al WDT.
    T0CS definisce la sorgente del clock, esterna sul piedino RA4/T0CKI o interna con la frequenza del quarzo divisa per 4.
    T0SE serve solo se si usa il clock esterno per decidere il fronte di intervento.
    Ed infine i 3 bit PS0, PS1 e PS2 che agiscono sul fattore di divisione del prescaler.

    Il prescaler è usato per dividere il clock prima che questo arrivi al registro timer TMR0 che si incrementa ad ogni colpo del clock che gli arriva. Quando il suo valore passa da 255 a 0 (overflow) attiva il flag T0IF che si trova nel registro INTCON. Questo causa un interrupt se è attivo oppure va letto se si lavora in polling. E' importante che T0IF venga azzerato dopo l'uso.
    Il fattore di divisione del prescaler va da 2 a 256 passando per le potenze di 2, non esiste la divisione per 1 che si ottiene mettendo PSA a 1 e quindi assegnando il prescaler al WDT.

    Il timer è quindi adatto per calcolare il trascorrere del tempo.
    Però per avere una misura precisa occorre prendere alcuni accorgimenti perché lo scorrere del tempo all'interno del timer 0 non è sempre privo di sobbalzi.
    La base di partenza è naturalmente l'oscillatore utilizzato, la sorgente del quale interna od esterna che sia deve essere precisa ed affidabile e quindi quarzata.

    Abbiamo quindi il registro TMR0 che ad ogni colpo di clock che gli arriva si incrementa (con o senza prescaler) ed al suo overflow fa scattare un meccanismo (in interrupt o in polling) che indica che è passato un certo tempo dal suo carico precedente e quindi va ricaricato per poi scadere di nuovo e così via all'infinito.
    TMR0 va caricato con un valore tale che allo scadere sia passato il tempo voluto, qui viene il bello poiché il suo carico avviene in un tempo successivo al suo overflow nel carico va tenuto conto del tempo trascorso tra i due momenti. Il tempo che è trascorso è stato conteggiato da TMR0 che, ricordo, non si ferma mai tranne nei casi spiegati appresso, il timer non va quindi caricato in maniera assoluta ma con una sottrazione (o una somma in complemento) che compensi il tempo trascorso nel frattempo.
    Purtroppo non è così semplice, avviene un'altro fatto, la scrittura su TMR0 causa un suo stop di 3 cicli (Tcy) se non si usa il prescaler o di 4 cicli se lo si usa. Essendo noto questo fatto si deve tenerne conto nella scrittura del valore, la qual cosa è facile senza prescaler ma si complica un poco se il prescaler è oltre la divisione per 4.
    E non è finita; se si usa il prescaler esso viene azzerato dall'operazione di scrittura su TMR0 per cui occorre conteggiare il tempo che passa dall'overflow alla scrittura del registro e riempire il tempo con delle istruzioni inefficaci per giungere alla scrittura su frontiera di prescaler. Vi è però un ciclo che non è compensabile ed è quando quando l'overflow giunge in mezzo ad un'istruzione che impiega 2 Tcy ad eseguirsi (call, goto, ret).
    La compensazione di frontiera è impossibile se si lavora in polling anche se minimizzabile con l'accorgimento di ripollare TMR0 e solo quando cambia ricaricarlo.
    Se invece si lavora in interrupt i tempi sono più facilmente computabili anche se occorre prendere degli accorgimenti che descrivo immediatamente.
    La routine di gestione del timer 0 deve essere la prioritaria su tutte le altre, questo facilita il conto delle istruzioni.
    Se si usa il prescaler gli interrupt non vanno mai fermati (GIE=0 mai) se si deve disattivare l'interrupt ad esempio per scrivere su EEPROM il tempo in cui si sta con l'interrupt disabilitato deve essere un multiplo esatto della divisione impostata sul prescaler.
    Il tempo massimo in cui l'interrupt è disabilitato e quindi anche all'interno delle routine di interrupt deve essere inferiore al ciclo del timer 0 sottraendovi tutte le compensazioni apportabili, altrimenti si perde un giro.

    Da quanto visto per avere tempi il più precisi possibile è meglio lavorare in interrupt e senza prescaler.
    A mio parere l'unica maniera per non impazzire con tempi e tempuscoli è quella di non scrivere mai su TMR0 ma lasciarlo correre, sia con che senza prescaler con interrupt o in polling. L'unico accorgimento da prendere è di non stare con l'interrupt fermo più del tempo di un giro completo del timer, idem per il test del polling.

    Attenzione se si addormenta il processore (istruzione 'sleep') il timer viene fermato con conseguenze deleterie per i tempi, naturalmente il suo interrupt non può dare la sveglia.
    Camillo

    Se hai un'amico immaginario, dicono che sei pazzo; invece, se in tanti hanno lo stesso amico immaginario, è religione.
    Anonimo

  2. #2

    Iscritto dal
    24/10/2011
    Località
    Marche
    Messaggi
    9,260
    Grazie Camillo, è sempre bello leggere i tuoi articoli.

    Ti ho mandato un pvt.


 

Autorizzazioni

  • Non puoi iniziare nuove discussioni
  • Non puoi rispondere alle discussioni
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
Powered by vBulletin™ Version 4.1.5
Copyright © 2019 vBulletin Solutions, Inc. All rights reserved
SEO by vBSEO ©2011, Crawlability, Inc.
Fuso orario: UTC +1, sono le 15:01.