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 |





Gli interrupt possono essere gestiti sia a livello hardware sia a livello software. Questi ultimi possono essere realizzati in assembler ma anche ad alto livello con il linguaggio C.
Salve, tempo fa avevo visto un articolo su come realizzare un termometro con un pic, senza nessuna sonda, ma contando i tempi di watchdog. Non riesco più a trovare tale articolo, sapete dirmi in quale rivista si trova?
Grazie!
Salve Tony21, puoi utilizzare il motore di ricerca interno al nostro sito:
http://cse.google.com/cse?cx=008025758855854363206:ceuhvxwadvc
Ho provato e ho trovato solo lo schema elettrico, ma non spiega come programmarlo
In che senso senza nessuna sonda? Forse ti riferisci a questo https://it.emcelettronica.com/termometro-digitale-usando-pic16f84a-schema-elettrico
Sì, però, non spiga come programmare il pic, mentre in quell”articolo lo spiegava in dettaglio
La programmazione con Interrupt è molto efficace e, spesso, è l’unica via per evitare la scrittura di codice molto complesso, lavorante in “polling”. Ma occorre progettare il tutto con estrema precisione, per evitare un codice critico e un malfunzionamento generale. Con gli Interrupt si implementa, in pratica, una sorta di multitasking hardware.