Gestione interrupt del TMR0 e PIC16F84

Un esempio di uso e gestione del timer0 per la realizzazione di un controllore di impulsi.

Il listato1 mostra l’utilizzo dell’interrupt del TMR0 per il conteggio di impulsi “squadrati”: il programma è costituito da: una fase di acquisizione degli impulsi, una di conversione del numero binario in una forma adatta alla visualizzazione (sui tre display a sette segmenti) e una fase di visualizzazione. Il numero decimale corrispondente al numero degli impulsi si suppone a tre cifre e il codice binario di ognuna di queste viene salvato in tre registri (UNI, DECI, CENTI); tale codice viene sommato al Program Counter per ottenere, da una tabella,  il codice per il display. La fase di acquisizione mostra l’uso dell’interrupt del timer0 a cui viene assegnato  il prescaler  con fattore di divisione di 256; il timer0 viene caricato con un valore iniziale nullo e lasciato ciclare per tutta la fase di acquisizione: quando esso raggiunge il valore 256 si riazzera e il micro entra in una brevissima routine di interrupt, che consiste nel decrementare la variabile corrispondente al numero degli interrupts scelto per stabilire  il periodo di acquisizione degli impulsi. Durante questa fase il microcontrollore  rimane all’interno di un ciclo di conteggio ed esce per i brevi periodi degli interrupts. Si può ottimizzare la routine di conversione nel caso di applicazioni che richiedano tempi di esecuzione più brevi, per esempio nel caso in cui l’ordine di grandezza del numero di impulsi sia maggiore. Il tempo che separa ogni interrupt è 4*(Tosc)*256*256, dove Tosc dipende dalla frequenza del clock e il tempo di acquisizione è 46 volte tale intervallo. Il periodo di accensione di ogni singolo display durante la scansione di visualizzazione è 4* (Tosc)*256*(256-208): tali tempistiche si possono modificare cambiando il valore con cui si carica il tmr0.

List p = 16f84a
TMR0           EQU 0x01    ; Definizione dei registri del PIC e delle costanti
OPTIO          EQU 0x81
INTCON         EQU 0x0B
PCL                     EQU 0x02
STATUS         EQU 0x03
PORTA          EQU 0x05
PORTB          EQU 0x06
RP0                     EQU 0x05
CONTATORE          EQU 0x0D     ; Definizione dei registri di uso generale
CONT                  EQU 0x0E
UNI                 EQU 0x0F
DECI                      EQU 0x10
CENTI                   EQU 0x11
CICLA                   EQU 0x12
      ORG 0
      goto INIZIO
      ORG 4
      goto CICLO1
      ORG 5
INIZIO:      bsf      STATUS,RP0
                   movlw    b’00001000’
             movwf PORTA ; Inizializzazione dei pins di ingresso e uscita
             clrf PORTB ; delle porte A e B: il pin 3 della porta A è
                     movlw b’00000111’ ; l’ingresso degli impulsi da contare, la porta B è
             movwf OPTIO ; usata come uscita per la visualizzazione del
             bcf STATUS,RP0; numero contato su 3 display a 7 segmenti
             clrf PORTB ; prescaler su tmr0 (1:256)
             movlw b’10100000’ ; Abilitazione dell’interrupt del timer0
             movwf INTCON
             clrf CONTATORE ;inizializzazione della variabile
             movlw b’00000000’ ; che contiene il numero degli impulsi
             movwf TMR0 ; avvio del timer0
             movlw d’46’ ; il tempo di acqusizione del numero di impulsi
             movwf CONT ; è 46 volte il periodo tra un interrupt e l’altro
CICLO_A:     btfss PORTA,3 ; Arrivo degli impulsi squadrati
             goto CICLO_A ; Ciclo da cui si esce per interrupt
CICLO_B:     btfsc PORTA,3
             goto CICLO_B
                    incf CONTATORE,1 ; variabile che contiene il numero degli impulsi
                goto CICLO_A
CICLO_C:      decfsz CONT,1 ; decrementa la variabile che conta il numero degli interrupt
                   goto CONTINUA ; continua con gli interrupt e continua a contare gli impulsi
               goto CONV ; smetti di contare gli impulsi e converti il numero binario
                                ; corrispondente nella forma utile alla visualizzazione
                                                                             su display
CONTINUA: movlw b’10100000’ ;
                      movwf INTCON
            retfie
CONV:     bcf INTCON,6 ; conversione del numero degli impulsi in unità,decine e centinaia
            clrf UNI
            clrf DECI
            clrf CENTI

CONV_UNI:   decfsz CONTATORE
               goto VISUALIZZA
               incf UNI,1
               movf UNI,0
               xorlw b’00001001’
               btfsc STATUS, 2
               goto DECINE
               goto CONV_UNI
CONV_DECINE:
               clrf UNI
               incf DECI,1
               movf DECI,0
               xorlw b’00001001’
               btfsc STATUS,2
               goto CENTINAIA
               goto CONV_UNI
CONV_CENTINAIA:
               clrf DECI
               incf CENTI
               goto CONV_UNI
VISUALIZZA:                     ; imposta la variabile che controlla
               movlw d’60’ ; il periodo di visualizzazione sul display
               movwf CICLA
VISUALIZZA_1                     ; uso di una tabella per ottenere i codici
               movf UNI,0 ; delle cifre decimali sulla porta B
               addwf PCL
                   retlw b’00001010’
               retlw b’11101011’
               retlw b’10000110’
               retlw b’11000010’
               retlw b’01100011’
               retlw b’01010010’
               retlw b’00010010’
               retlw b’11001011’
               retlw b’00000010’
               retlw b’01000010’
                   movwf PORTB
               bsf PORTA,0 ; accendi il display delle unità
               call DELAY ; tempo di accensione del display delle unità
               bcf PORTA,0 ; spegni il display e passa a quello delle decine
              movf DECI,0
              addwf PCL
              retlw b’00001010’
              retlw b’11101011’
              retlw b’10000110’
              retlw b’11000010’
              retlw b’01100011’
              retlw b’01010010’
              retlw b’00010010’
              retlw b’11001011’
              retlw b’00000010’
              retlw b’01000010’
                   movwf PORTB
              bsf PORTA,1
              call DELAY
              bcf PORTA,1
              retlw b’00001010’
              retlw b’11101011’
              retlw b’10000110’
              retlw b’11000010’
              retlw b’01100011’
              retlw b’01010010’
              retlw b’00010010’
              retlw b’11001011’
              retlw b’00000010’
              retlw b’01000010’
                      movwf PORTB
              bsf PORTA,2
              call DELAY
              bcf PORTA,2

              decfsz CICLA,1
              goto VISUALIZZA_1
              goto INIZIO ;ritorna ad acquisire gli impulsi: i tre display sono spenti
                                 ; e rimangono tali per tutto il tempo di acquisizione
DELAY:      bcf INTCON,2
                movlw 0xD0
                movwf TMR0
DELAY_1: btfss INTCON,2
              goto DELAY_1
              return
END
Listato 1

Iscriviti e ricevi GRATIS
Speciale Pi

Fai subito il DOWNLOAD (valore 15€) GRATIS

Una risposta

  1. Maurizio Di Paolo Emilio Maurizio Di Paolo Emilio 20 febbraio 2017

Scrivi un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Iscriviti e ricevi GRATIS
Speciale Pi

Fai subito il DOWNLOAD (valore 15€) GRATIS