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.