ELEMANIA
PIC16F690 - Timer1
Timer1 e temporizzazione hardware

In molti casi il programmatore desidera temporizzare il funzionamento del PIC con intervalli di tempo piuttosto lunghi (per esempio per far lampeggiare un LED). Abbiamo già visto come ciò possa essere ottenuto per mezzo di cicli di ritardo, cioè mediante una temporizzazione software. Questa soluzione, sebbene abbastanza semplice da realizzare, non è in generale la migliore, in quanto impegna continuamente il microcontrollore nell'esecuzione di cicli di ritardo.

Un'altra soluzione (temporizzazione hardware) consiste nell'utilizzare uno dei timer interni al PIC, programmato in modo tale da generare un interrupt allo scadere di ogni intervallo prefissato di tempo (per esempio ogni volta che si vuole accendere o spegnere un LED). Se si usano a questo scopo i timer a 8 bit (Timer0 o Timer2) si ha il problema che i tempi prodotti sono sempre piuttosto brevi. Per esempio usando Timer0 (ma lo stesso ragionamento vale per Timer2) con una frequenza di clock standard di 4 MHZ, si ha un periodo di incremento pari a 1 µs. Ciò significa che il timer si azzera (e genera un interrupt) ogni 256 µs. Anche programmando il prescaler al massimo valore (256) il massimo tempo che si ottiene è pari a 256*256 µs = 65 ms circa. Se si vogliono temporizzare tempi più lunghi, escludendo la possibilità di cambiare la frequenza del clock di sistema, l'unica soluzione consiste nell'effettuare un conteggio software del numero di interrupt generati e nell'eseguire una determinata azione (es. spegnere o accendere un LED) solo quando tale conteggio ha raggiunto il valore desiderato (dopodiché si azzera il contatore e si ricomincia il conteggio daccapo), come spiegato nella precedente lezione.

Una soluzione forse più semplice è quella di usare Timer1. Nel PIC16F690 questo timer ha 16 bit e dunque è in grado di contare fino a 65536. Se a ciò si aggiunge il prescaler (che permette di moltiplicare i tempi fino a un massimo di 8 volte), con questo timer (sempre facendo riferimento a un clock a 4 MHz) si possono ottenere tempi fino a 8*65536 µs = 0,52 s.

Inoltre, se anche questo tempo non fosse sufficientemente lungo, c'è un'altra caratteristica che rende Timer1 particolarmente adatto allo scopo ed è il fatto di poter usare come sorgente di clock non il clock di sistema, ma l'oscillatore RC secondario LFINTOSC da 31 kHz
interno al PIC (indipendentemente da quale sia l'oscillatore selezionato come clock del PIC). In questo modo i tempi raggiungibili arrivano fino a un massimo di circa 67 secondi.

 

Un esempio di temporizzazione hardware con Timer1 (flash di LED)

La figura seguente riassume i principali registri di controllo di Timer1:

Il registro più importante per la programmazione di Timer1 è T1CON:

Senza entrare nei dettagli (per i quali si rimanda il lettore al manuale del PIC) i bit più importanti per i nostri scopi sono:

Vediamo ora un semplice esempio di programma che utilizza Timer1 per far lampeggiare una serie di LED ogni 0,5 secondi circa (usando il clock standard a 4 MHz). Il programma suppone che i LED siano collegati con i pin di PORTC:

#include <P16F690.inc>

__CONFIG _CP_OFF & _CPD_OFF & _BOR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _FCMEN_OFF & _IESO_OFF

;***** DEFINIZIONE DI REGISTRI GPR PER IL SALVATAGGIO DEL CONTESTO
W_TEMP EQU 0X7D
STATUS_TEMP EQU 0X7E
PCLATH_TEMP EQU 0X7F

;**********************************************************************
    ORG 0X000 ; INIZIO MEMORIA DI PROGRAMMA
    GOTO MAIN ; SALTA ALL'INIZIO DEL PROGRAMMA PRINCIPALE

 

;******************* INTERRUPT SERVICE ROUTINE *****************
    ORG 0X004 ; INIZIO ROUTINE DI INTERRUPT

MOVWF W_TEMP ; SALVA W                    ; SALVATAGGIO REGISTRI DEL PIC
MOVF STATUS,W ; COPIA STATUS IN W
MOVWF STATUS_TEMP ; SALVA STATUS
MOVF PCLATH,W ; COPIA PCLATH IN W
MOVWF PCLATH_TEMP ; SALVA PCLATH

BANKSEL PIR1
BTFSC PIR1, TMR1IF    ; CONTROLLA SE CI SONO INTERRUPT DA TIMER1
CALL TIMER1INT

MOVF PCLATH_TEMP,W     ; RIPRISTINO REGISTRI DEL PIC
MOVWF PCLATH
MOVF STATUS_TEMP,W
MOVWF STATUS
SWAPF W_TEMP,F
SWAPF W_TEMP,W
   
RETFIE                         ; RETURN FROM INTERRUPT
;*******************************************************

 

; *************** SUBROUTINE PER FAR LAMPEGGIARE IL LED ************
TIMER1INT

BCF PIR1, TMR1IF ; CLEAR DEL FLAG DI INTERRUPT

MOVLW 0xFF             ; INVERTE LO STATO DEI LED
XORWF PORTC,F

RETURN

; ***********************************************************

 

MAIN

; ABILITAZIONE DEGLI INTERRUPT
        BANKSEL INTCON
        BSF INTCON, GIE
        BSF INTCON, PEIE
        BANKSEL PIE1
        BSF PIE1, TMR1IE

; PROGRAMMAZIONE DEL REGISTRO T1CON
        BANKSEL T1CON
        MOVLW b'00110001'        ; PRESCALER  1:8
        MOVWF T1CON

; PROGRAMMAZIONE DI PORTC
        BANKSEL ANSEL
        CLRF ANSEL
        CLRF ANSELH

BANKSEL PORTC
CLRF PORTC         ; LED SPENTI INIZIALMENTE

BANKSEL TRISC
CLRF TRISC         ; PORTC IN OUTPUT

GOTO $             ; CICLO INFINITO (ATTESA DI INTERRUPT)

END

 

 

precedente - successiva

Sito realizzato in base al template offerto da

http://www.graphixmania.it