;
; ESEMPIO 1.1
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione
;
;Sommare due valori immediati (p.e. 5+7) il risultato va depositato nella
;posizione 0x10
;
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Risultato equ 0x10 ;Determina la posizione del risultato
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva il vettore di interrupt
Inizio movlw 0x05 ;Carica il 1° addendo in W
addlw 0x07 ;Somma il 2º addendo
movwf Risultato ;Memorizza il risultato
Stop nop ;Metti breakpoint di arresto
nop
end ;Fine del programma principale
;
; ESEMPIO 1.2
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione
;
;Tre valori A,B e C supponiamo siano stati precedentemente memorizzati.
;Si desidera risolvere la seguente equazione: (A+B)-C
;
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Dato_A equ 0x10 ;Determina la posizione del dato A
Dato_B equ 0x11 ;Determina la posizione del dato B
Dato_C equ 0x12 ;Determina la posizione del dato C
Risultato equ 0x13 ;Determina la posizione del risultato
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva il vettore di interrupt
Inizio movf Dato_A,W ;Carica il 1° addendo
addwf Dato_B,W ;Somma il 2º addendo
movwf Risultato ;Memorizza risultato parziale
movf Dato_C,W ;Carica il sottraendo
subwf Risultato,F ;Sottrai dal minuendo e memorizza
Stop nop ;Metti breakpoint di arresto
nop
end ;Fine del programa principale
;
; ESEMPIO 1.3
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione
;
;Sommare due numeri, A e B, di 16 bits ciascuno.
;
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Dato_A_L equ 0x10 ;Determina la posizione del dato A (basso)
Dato_A_H equ 0x11 ;Determina la posizione del dato A (alto)
Dato_B_L equ 0x12 ;Determina la posizione del dato B (basso)
Dato_B_H equ 0x13 ;Determina la posizione del dato B (alto)
Risultato_L equ 0x14 ;Determina la posizione del risultato (basso)
Risultato_H equ 0x15 ;Determina la posizione del risultato (alto)
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva il vettore di interrupt
Inizio movf Dato_A_L,W ;Carica meno peso del dato A
addwf Dato_B_L,W ;Somma meno peso del dato B
movwf Risultato_L ;Memorizza il risultato
movf Dato_A_H,W ;Carica più peso del dato A
btfsc STATUS,C ;C'è stato trasporto anteriore ??
addlw 1 ;Si, aggiungi 1 all'accumulatore
addwf Dato_B_H,W ;Somma più peso del dato B
movwf Risultato_H ;Conserva il risultato
Stop nop ;Metti breakpoint di arresto
nop
end ;Fine del programma principale
;
; ESEMPIO 1.4
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione
;
;Sottrarre due numeri, A - B, di 16 bits ciascuno.
;
;Anche se questo esercizio è simile al precedente, è da notare che, il contenuto dell'
;accumulatore agisce come sottraendo e, l'operando, come minuendo.
;
;Ugualmente è da notare che il flag CARRY va interpretato
;in modo opposto a come va fatto con la somma (a "0" c'è trasporto).
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Dato_A_L equ 0x10 ;Determina la posizione del dato A (basso)
Dato_A_H equ 0x11 ;Determina la posizione del dato A (alto)
Dato_B_L equ 0x12 ;Determina la posizione del dato B (basso)
Dato_B_H equ 0x13 ;Determina la posizione del dato B (alto)
Risultato_L equ 0x14 ;Determina la posizione del risultato (basso)
Risultato_H equ 0x15 ;Determina la posizione del risultato (alto)
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva il vettore di interrupt
Inizio movf Dato_B_L,W ;Carica meno peso del dato B (sottraendo)
subwf Dato_A_L,W ;Sottrai meno peso del dato A (minuendo)
movwf Risultato_L ;Memorizza il risultato
movf Dato_B_H,W ;Carica più peso del dato B (sottraendo)
btfss STATUS,C ;C'è stato trasporto(CARRY = 0) anteriore ??
addlw 1 ;Sì, aggiungi 1 all'accumulatore (sottraendo)
subwf Dato_A_H,W ;Sottrai più peso del dato A (minuendo)
movwf Risultato_H ;Conserva il risultato
Stop nop ;Metti breakpoint d'arresto
nop
end ;Fine del programma principale
;
; ESEMPIO 1.5
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione
;
;Memorizzare il modello 33 in 15 posizioni contigue della memoria di dati, iniziando
;dall'indirizzo 0x10
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Contatore equ 0x0c ;Contatore interno
Prima equ 0x10 ;Posizione iniziale
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva il vettore di interrupt
Inizio movlw .15
movwf Contatore ;Carica il contatore con 15 (in decimale)
movlw Prima
movwf FSR ;Orienta il puntatore con indirizzo iniziale
movlw 0x33 ;Carica modello da memorizzare
Loop movwf INDF ;Memorizza modello in pos. indicata da FSR
incf FSR,F ;Aumenta il puntatore FSR
decfsz Contatore,F ;Diminuisci contatore fino ad arrivare a 0
goto Loop ;Contatore non è 0
Stop nop ;Metti breakpoint d'arresto
nop
end ;Fine del programma principale
;
; ESEMPIO 1.6
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione
;
;Il programma paragona due numeri A e B. Se A=B, il risultato è 0. Se A > B, il risultato
;è A-B. Se A < B il resultato è A+B
;
;Si noti che, non avendo istruzioni di paragone, questo è realizzato mediante
;sottrazioni.
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Dato_A equ 0x10 ;Variabile del dato A
Dato_B equ 0x11 ;Variabile del dato B
Risultato equ 0x12 ;Variabile per il risultato
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva il vettore di interrupt
Inizio movf Dato_B,W ;Carica il dato B
subwf Dato_A,W ;Sottrai/paragona a dato A
btfsc STATUS,Z ;Sono uguali (Z=1)??
goto A_uguale_B ;Sì
btfsc STATUS,C ;No. A maggiore di B (C=0)??
goto A_mayor_B ;Sì
A_minor_B movf Dato_A,W ;No, A è minore di B
addwf Dato_B,W ;Somma A più B
movwf Risultato ;Conserva il risultato
goto Stop
A_mayor_B movwf Risultato ;
goto Stop
A_uguale_B clrf Risultato ;Azzera il risultato
Stop nop ;Metti breakpoint d'arresto
nop
end ;Fine del programma principale
;
; ESEMPIO 1.7
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione
;
;Il programma realizza una temporizzazione di 0.5 secondi. Si presume una frequenza di
lavoro
;del PIC di 4 MHz, per cui il TMR0 cambia ogni 1 uS (4Tosc=1uS ).
;
;Il TMR0 viene caricato con 250 - 2 (il suo complemento, 7) e si seleziona un prescaler
di 8. La
;temporizzazione così ottenuta è di 1990 uS. Se questa si ripete 250 volte, si ottiene
;una temporizzazione totale intorno ai 500000uS
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Contatore equ 0x10 ;Variabile per il contatore
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva il vettore di interrupt
Inizio bsf STATUS,RP0 ;Seleziona banco dati 1
movlw b'11000010'
movwf OPTION_REG ;Configura prescaler di 8 assegnato al TMR0
bcf STATUS,RP0 ;Seleziona banco dati 0
movlw .250
movwf Contatore ;Attiva la variabile contatore
Loop1 clrf INTCON ;Disconnetti flag del TMR0 e interrupt
movlw .7
movwf TMR0 ;Carica il TMR0 con complemento di 250
Loop2 btfss INTCON,T0IF ;Fine del TMR0 (flag T0IF=1) ??
goto Loop2 ;No, aspettare
decfsz Contatore,F ;Sì. Ripetere tante volte quante ne indica il
contatore
goto Loop1
Stop nop ;Metti breakpoint di arresto
nop
end ;Fine del programma principale
;
; ESEMPIO 1.8
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione
;
;Questo esempio realizza il prodotto di due numeri di 8 bits generando un risultato di
;16 bits.
;Il programma impiega lo stesso meccanismo di realizzazione di un prodotto su carta.
;Si noti che il programma viene eseguito sempre nello stesso intervallo di tempo,
;qualunque siano gli operandi.
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
cblock 0x10 ;Inizio di definizione di variabili
Moltiplicando ;Variabile per il moltiplicando
Moltiplicatore ;Variabile per il moltiplicatore
Risultato_H ;Parte alta del risultato
Risultato_L ;Parte bassa del risultato
Estatus_Temp ;Reg. di stato temporale
Contatore ;Variabile con numero di volte per eseguire operazioni
endc ;Fine delle definizioni
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva il vettore di interrupt
Inizio clrf Risultato_H
clrf Risultato_L ;Metti a 0000 il risultato iniziale
movlw 0x08
movwf Contatore ;Avvia il contatore con 8
bcf STATUS,C ;Cancella il carry
Loop movf Moltiplicando,W ;Carica il moltiplicando
btfsc Moltiplicatore,0 ;E' 1 il bit di minor peso del moltiplicatore ??
addwf Risultato_H,F ;Sì, si somma il moltiplicando
rrf Risultato_H,F
rrf Risultato_L,F ;Spostamento a destra del risultato
;Ruota a destra il moltiplicatore senza che si modifichi il flag Carry
Ruota_sen_Carry movf STATUS,W
movwf Estatus_Temp ;Salva provvisoriamente il carry
rrf Moltiplicatore,F ;Sposta a destra il moltiplicatore
movf Estatus_Temp,W
movwf STATUS ;Recupera il carry originale
decfsz Contatore,F ;Ripeti il loop 8 volte
goto Loop
Stop nop ;Metti breakpoint d'arresto
nop
end ;Fine del programma principale
;
; ESEMPIO 1.9
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione
;
;Converti il valore binario presente in posizione 0x10 in BCD. Il risultato va depositato
;nelle variabili Buffer_H e Buffer_L.
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Binario equ 0x10 ;Valore binario iniziale
Buffer_H equ 0x11 ;Parte alta del risultato
Buffer_L equ 0x12 ;Parte bassa del risultato
Temp_1 equ 0x13 ;Registro temporale
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva il vettore di interrupt
Inizio movf Binario,W ;Carica il valore binario iniziale
clrf Buffer_L
clrf Buffer_H ;Attiva registri di lavoro
BIN_BCD_1 addlw 0xf6 ;Sottrai 10 mediante somma di complemento a 2.
btfss STATUS,C ;C'è Carry?
goto BIN_BCD_3 ;NO.
movwf Temp_1 ;SI.Conservare nel registro temporale.
incf Buffer_L,F ;Aumentare byte basso, conservarlo e inviare...
movf Buffer_L,W ;..copia al ==> W...
xorlw b'00001010' ;..0Ah xor W.
btfss STATUS,Z ;Buffer_L è uguale a 10 ??
goto BIN_BCD_2 ;NO.
clrf Buffer_L ;SI. Metti Buffer_L a 0
incf Buffer_H,F ;Incrementare Buffer_H
BIN_BCD_2 movf Temp_1,W ;Recuperare il dato.
goto BIN_BCD_1 ;Continuare l'operazione.
BIN_BCD_3 addlw H'0A' ;TEMPO + 0Ah
swapf Buffer_L,F ;<3:0> <==> <7:4> y ==> Buffer_L
iorwf Buffer_L,F ;W OR Buffer_L ==> Buffer_L
Stop nop ;Metti breakpoint d'arresto
nop
end ;Fine del programma principale
;
; ESEMPIO 1.10
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione
;
;Converti il valore binario presente in posizione 0x10, compreso tra 0 e 9, nel suo
;equivalente in codice GRAY
;
;Questo esempio cerca di abituare l'utente all'utilizzo di tabelle
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Bcd equ 0x10 ;Valore BCD iniziale
Gray equ 0x11 ;Valore ottenuto in codice GRAY
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva il vettore di interrupt
Tabel addwf PCL,F ;Calcola spostamento sulla tabella
retlw b'00000000' ;Codice GRAY della cifra 0
retlw b'00000001' ;Codice GRAY della cifra 1
retlw b'00000011' ;Codice GRAY della cifra 2
retlw b'00000010' ;Codice GRAY della cifra 3
retlw b'00000110' ;Codice GRAY della cifra 4
retlw b'00000111' ;Codice GRAY della cifra 5
retlw b'00000101' ;Codice GRAY della cifra 6
retlw b'00000100' ;Codice GRAY della cifra 7
retlw b'00001100' ;Codice GRAY della cifra 8
retlw b'00001101' ;Codice GRAY della cifra 9
Inizio movf Bcd,W ;Carica il valore BCD originale
call Tabel ;Converti in GRAY
movwf Gray ;Conserva il risultato
Stop nop ;Metti breakpoint di arresto
nop
end ;Fine del programma principale
;
; ESEMPIO 2.11
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;Il Display a 7 segmenti del MicroPIC Trainer
;
;Sul display a catodo comune connesso alla porta B, si vuole visualizzare lo stato
;logico "0" o "1" dell'interruttore RA0. Mediante l'interruttore RA1 si attiva o no il
;punto decimale.
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva il vettore di interrupt
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP0 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come uscita
movlw b'00011111'
movwf TRISA ;Porta A si configura come entrata
bcf STATUS,RP0 ;Seleziona banco 0
Loop clrwdt ;Aggiorna il WDT
btfsc PORTA,0 ;Controlla RA0
goto RA0_es_1 ;E'livello "1"
movlw b'00111111'
movwf PORTB ;Visualizza la cifra 0
goto Test_RA1
RA0_es_1 movlw b'00000110'
movwf PORTB ;Visualizza la cifra 1
Test_RA1 btfsc PORTA,1 ;Controlla RA1
goto RA1_es_1 ;E' a "1"
bcf PORTB,7 ;Disconnetti punto decimale
goto Loop
RA1_es_1: bsf PORTB,7 ;Attiva punto decimale
goto Loop
end ;Fine del programma principale
;
; ESEMPIO 2.12
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;Il Display a 7 segmenti del MicroPIC Trainer. Decodificatore hex. a 7 segmenti.
;
;Mediante i quattro interruttori RA0-RA3 si introduce un valore esadecimale di 4 bits
;che deve essere visualizzato sul display del MicroPIC Trainer
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva il vettore di interrupt
;**********************************************************************************
;Tabella: Questa procedura converte il codice binario presente nei 4 bits di minor peso
;del reg. W nel suo equivalente a 7 segmenti. Il codice a 7 segmenti ritorna anche
;nel reg. W
Tabella: addwf PCL,F ;Spostamento sulla tabella
retlw b'00111111' ;Cifra 0
retlw b'00000110' ;Cifra 1
retlw b'01011011' ;Cifra 2
retlw b'01001111' ;Cifra 3
retlw b'01100110' ;Cifra 4
retlw b'01101101' ;Cifra 5
retlw b'01111101' ;Cifra 6
retlw b'00000111' ;Cifra 7
retlw b'01111111' ;Cifra 8
retlw b'01100111' ;Cifra 9
retlw b'01110111' ;Cifra A
retlw b'01111100' ;Cifra b
retlw b'00111001' ;Cifra C
retlw b'01011110' ;Cifra d
retlw b'01111001' ;Cifra E
retlw b'01110001' ;Cifra F
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP0 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come uscita
movlw b'00011111'
movwf TRISA ;Porta A si configura come entrata
bcf STATUS,RP0 ;Seleziona banco 0
Loop clrwdt ;Aggiornare il WDT
movf PORTA,W
andlw b'00001111' ;Leggi il codice di RA0-RA3
call Tabella ;Converti in 7 segmenti
movwf PORTB ;Visualizza sul display
goto Loop
end ;Fine del programma principale
;
; ESEMPIO 2.13
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;Contatore UP/DOWN binario
;
;Sugli 8 leds di uscita connessi alla porta B verrà visualizzato, in binario, il numero
;di impulsi applicati dall'entrata RA0. RA1 determina se il conto è ascendente (a "1")
;o discendente
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva il vettore di interrupt
;********************************************************************************
;Delay_20_ms: Questa procedura di temporizzazione ha per oggetto di eliminare l'"effetto
;rimbalzo" delle periferiche elettromeccaniche. Realizza un delay di 20 mS. Se il PIC
;lavora a una frequenza di 4MHz, il TMR0 cambia ogni uS. Se vogliamo tempori-
;zzare 20000 uS (20 mS) con un prescaler di 128, il TMR0 dovrà contare 156 eventi
;(156 * 128). Il valore 156 equivale a 9c hex. e poiché il TMR0 è ascedente bisognerà
;caricare il suo complemento a 1 (63 hex.).
Delay_20_ms: bcf INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0x63 ;Complemento hex. di 156
movwf TMR0 ;carica il TMR0
Delay_20_ms_1 clrwdt ;Aggiornare il WDT
btfss INTCON,T0IF ;Overflow del TMR0 ??
goto Delay_20_ms_1 ;Ancora no
bcf INTCON,T0IF ;Adesso sì, rimettere il flag
return
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP0 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come uscita
movlw b'00011111'
movwf TRISA ;Porta A si configura come entrata
movlw b'00000110'
movwf OPTION_REG ;Prescaler di 128 per il TMR0
bcf STATUS,RP0 ;Seleziona banco 0
Loop clrwdt ;Aggiornare il WDT
btfss PORTA,0 ;Aumento del segnale RA0 ?
goto Loop ;No
call Delay_20_ms ;Elimina rimbalzi
Loop_2 clrwdt ;Aggiornare il WDT
btfsc PORTA,0 ;Diminuzione di RA0 (impulsi) ??
goto Loop_2 ;No
call Delay_20_ms ;C'è stato impulso, eliminare rimbalzi
btfss PORTA,1 ;RA1 = 1
goto Down ;No, conto discendente
Up incf PORTB,F ;Conto ascendente
goto Loop
Down decf PORTB,F ;Conto discendente
goto Loop
end ;Fine del programma principale
;
; ESEMPIO 2.14
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;Contatore UP/DOWN decimale di una cifra
;
;Sul display a 7 segmenti connessi alla porta B verrà visualizzato il numero di impulsi
;applicati dall'entrata RA0. RA1 determina se il conto è ascendente (a "1")
;o discendente
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Contatore equ 0x0c ;Variabile del contatore
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva il vettore di interrupt
;**********************************************************************************
;Tabella: Questa procedura converte il codice BCD presente nei 4 bits di minore peso
;del reg. W nel suo equivalente a 7 segmenti. Il codice a 7 segmenti ritorna anche
;nel reg. W
Tabella: addwf PCL,F ;Spostamento sulla tabella
retlw b'00111111' ;Cifra 0
retlw b'00000110' ;Cifra 1
retlw b'01011011' ;Cifra 2
retlw b'01001111' ;Cifra 3
retlw b'01100110' ;Cifra 4
retlw b'01101101' ;Cifra 5
retlw b'01111101' ;Cifra 6
retlw b'00000111' ;Cifra 7
retlw b'01111111' ;Cifra 8
retlw b'01100111' ;Cifra 9
;*********************************************************************************
;Delay_20_ms: Questa procedura di temporizzazione ha per scopo di eliminare l'"effetto
;rimbalzo" delle periferiche elettromeccaniche. Realizza un delay di 20 mS. Se il PIC
;lavora a una frequenza di 4MHz, il TMR0 cambia ogni uS. Se desideriamo tempori-
;zzare 20000 uS (20 mS) con un prescaler di 128, il TMR0 dovrà contare 156 eventi
;(156 * 128). >Il valore 156 equivale a 9c hex. e poiché il TMR0 è ascendente bisognerà
;caricare il suo complemento a 1 (63 hex.).
Delay_20_ms: bcf INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0x63 ;Complemento hex. di 156
movwf TMR0 ;carica il TMR0
Delay_20_ms_1 clrwdt ;Aggiornare il WDT
btfss INTCON,T0IF ;Overflow del TMR0 ??
goto Delay_20_ms_1 ;Ancora no
bcf INTCON,T0IF ;Adesso sì, rimettere il flag
return
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP0 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come uscita
movlw b'00011111'
movwf TRISA ;Porta A si configura come entrata
movlw b'00000110'
movwf OPTION_REG ;Prescaler di 128 per il TMR0
bcf STATUS,RP0 ;Seleziona banco 0
clrf Contatore ;Mettere a 0 del contatore
Loop movf Contatore,W
call Tabella ;Converti BCD in 7 segmenti
movwf PORTB ;Visualizza il valore del contatore
Wait_0 clrwdt ;Aggiornare il WDT
btfss PORTA,0 ;Aumento del segnale RA0 ?
goto Wait_0 ;No
call Delay_20_ms ;Elimina rimbalzi
Wait_1 clrwdt ;Aggiornare il WDT
btfsc PORTA,0 ;Diminuzione di RA0 (impulso) ??
goto Wait_1 ;No
call Delay_20_ms ;C'è stato impulso, eliminare rimbalzi
btfss PORTA,1 ;RA1 = 1
goto Down ;No, conto discendente
Up incf Contatore,F ;Aumenta contatore
movlw .10
subwf Contatore,W
btfss STATUS,Z ;E' maggiore di 9 ??
goto Loop ;No
clrf Contatore ;Sì, mettere a 0 il contatore
goto Loop
Down decf Contatore,F ;Diminuisci il contatore
movlw 0xff
subwf Contatore,W
btfss STATUS,Z ;E' minore di 0 ??
goto Loop ;No
movlw 0x09
movwf Contatore ;Sì, mettere a 9 il contatore
goto Loop
end ;Fine del programma principale
;
; ESEMPIO 2.15
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;Generazione di onde quadrate di differenti frequenze variando il valore del TMR0
;
;La linea di uscita RB0 cambierà stato a una frequenza determinata dal valore
;introdotto mediante i 3 interruttori RA0-RA2:
;
;RA2 RA1 RA0 Frequenza Periodo Semiperiodo
;--- --- --- ---------- ------- -----------
;0 0 0 0 KHz --- ---
;0 0 1 1 KHz 1000 uS 500 uS
;0 1 0 2 KHz 500 uS 250 uS
;0 1 1 3 KHz 333 uS 166 uS
;1 0 0 4 KHz 250 uS 125 uS
;1 0 1 5 KHz 200 uS 100 uS
;1 1 0 6 KHz 166 uS 83 uS
;1 1 1 7 KHz 143 uS 71 uS
;
;Nel trattamento di interrupt che provocherà l'overflow del TMR0, si può
;notare come vengono salvati il W e il registro di stato, per recuperarli posteriormente.
;E' ciò che si chiama "salvare il contesto"
;
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Valore equ 0x0c ;Variabile di frequenza
W_Temp equ 0x0d ;W temporale
Status_Temp equ 0x0e ;Registro di stato temporale
org 0x00 ;Vettore di Reset
goto Inizio
org 0x04 ;Vettore di interrupt
goto Interrupt
;*********************************************************************************
;Tabella: questa procedura restituisce il valore da caricare nel TMR0 secondo la
frequenza selez-
;ionata. Partendo da una frequenza generale di 4 MHz, il TMR0 cambia ogni 1 uS.
;Si seleziona un preescaler di 4. Il valore da caricare in TMR0 si ottiene dividendo il
;semiperiodo della frequenza desiderata con il prescaler. Al valore ottenuto si
;sottrae 2 per motivi di sincronismo interno del PIC, si converte in hex. e si comple-
;menta.
Tabel.: addwf PCL,F ;Calcola spostamento della tabella
retlw 0x00 ;0 KHz
retlw 0x86 ;1 KHz
retlw 0xc5 ;2 KHz
retlw 0xda ;3 KHz
retlw 0xe4 ;4 KHz
retlw 0xea ;5 KHz
retlw 0xee ;6 KHz
retlw 0xf1 ;7 KHz
Interrupt movwf W_Temp ;Salva il W
swapf STATUS,W
movwf Status_Temp ;Salva il registro di stato
movf Valore,W
movwf TMR0 ;Ricarica il TMR0
bcf INTCON,T0IF ;Disattiva il flag TMR0
movlw b'00000001'
xorwf PORTB,F ;Fai oscillare RB0
swapf Status_Temp,W
movwf STATUS ;Recupera il registro di stato
swapf W_Temp,F
swapf W_Temp,W ;Recupera il registro W
retfie
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP0 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come uscita
movlw b'00011111'
movwf TRISA ;Porta A si configura come entrata
movlw b'00000001'
movwf OPTION_REG ;Prescaler di 4 per il TMR0
bcf STATUS,RP0 ;Seleziona banco 0
movlw b'00100000'
movwf INTCON ;Interrupt TMR0 abilitato
Loop clrwdt ;Aggiornare il WDT
movf PORTA,W
andlw b'00000111'
btfss STATUS,Z ;RA0-RA2 = 0 ??
goto Uscita_On ;No, uscita di frequenza
bcf INTCON,GIE ;Sì, interrupt OFF, frequenza OFF
goto Loop
Uscita_On call Tabella ;Determina valore da caricare in TMR0
movwf Valor ;Carica la variabile
bsf INTCON,GIE ;Interrupt ON
goto Loop
end ;Fine del programma principale
;
; ESEMPIO 2.16
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;Generazione di numeri aleatori
;
;Ogni volta che si applica un impulso attraverso RA0, si genera un numero binario
aleatorio di 8 bits
;che verrà visualizzato sugli 8 leds connessi nella porta B, per 3 secondi.
;
;Tra le differenti tecniche, quella utilizzata per ottenere il numero, consiste nel
catturare
;il valore del TMR0 in un determinato momento.
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Numero equ 0x0c ;Numero aleatorio
Delay_Cont equ 0x0d ;Contatore di intervalli
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva vettore di interrupt
;*********************************************************************************
;Delay_20_ms: Questa procedura di temporizzazione ha per scopo di eliminare l'"effetto
;rimbalzo" delle periferiche elettromeccaniche. Realizza un delay di 20 mS. Se il PIC
;lavora a una frequenza di 4MHz, il TMR0 cambia ogni uS. Se vogliamo tempori-
;zzare 20000 uS (20 mS) con un prescaler di 256, il TMR0 dovrà contare 78 eventi
;(78 * 256). Il valore 78 equivale a 0x4e hex. e poiché il TMR0 è ascendente bisognerà
;caricare il suo complemento a 1 (0xb1 hex.).
Delay_20_ms: bcf INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0xb1 ;Complemento hex. de 78
movwf TMR0 ;carica il TMR0
Delay_20_ms_1 clrwdt ;Aggiornare il WDT
btfss INTCON,T0IF ;Overflow del TMR0 ??
goto Delay_20_ms_1 ;Ancora no
return
;*********************************************************************************
;Delay_var: Questa procedura a scopo generico realizza una temporizzazione variabile
;tra 50 mS e 12.8". Si impiega un prescaler di 256 e il TMR0 viene caricato con 195.
;La velocità di lavoro è di 4Mhz e quindi il TMR0 incrementa ogni uS. In
;questo modo, il TMR0 deve contare 195 eventi che, con un preescaler di 128 fa un
;intervallo totale di 50000 uS/50 mS (195 * 256). Il valore 195 va espresso
;in Hex. (c3) e poiché il TMR0 è ascendente bisognerà caricare il suo complemento (3C
hex.)
;Tale intervallo di 50 mS si ripete tante volte quante ne indica la variabile
"Delay_cont",
;è per questo che il delay minimo è di 50 mS ("Delay_cont=1) e il massimo di 12.8"
;(Delay_cont=255).
Delay_var: bcf INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0x3c ;Complemento hex. de 195
movwf TMR0 ;carica il TMR0
Intervallo clrwdt ;Aggiornare il WDT
btfss INTCON,T0IF ;Overflow del TMR0 ??
goto Intervallo ;Ancora no
decfsz Delay_Cont,F ;Diminusci contatore di intervalli
goto Delay_var ;Ripeti l'intervallo di 50 mS
return
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP0 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come uscita
movlw b'00011111'
movwf TRISA ;Porta A si configura come entrata
movlw b'00000111'
movwf OPTION_REG ;Prescaler di 256 per il TMR0
bcf STATUS,RP0 ;Seleziona banco 0
Loop clrwdt ;Aggiornare il WDT
btfss PORTA,0 ;Attivato RA0 ??
goto Loop ;Ancora No
movf TMR0,W ;Adesso sì.
movwf Numero ;Cattura il valore del TMR0 (Nº aleatorio)
call Delay_20_ms ;Elimina rimbalzi
RA0_1 clrwdt ;Aggiorna il WDT
btfsc PORTA,0 ;Disattivato RA0 ??
goto RA0_1 ;Ancora no
movf Numero,W ;E' stato prodotto un impulso in RA0, si legge
movwf PORTB ;il valore catturato del TMR0 (Nº aleatorio)
;e si toglie con i leds della PORTA B
movlw d'60'
movwf Delay_Cont ;Introduci variabile di temporizzazione
call Delay_var ;Temporizza 3 secondi
clrf PORTB ;Disconetti le uscite
goto Loop
end ;Fine del programma principale
;
; ESEMPIO 2.17
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;Generazione di numeri aleatori. Il dado elettronico
;
;Si tratta di generare un numero aleatorio tra 1 e 6. Quando RA0 è a "1", sul
;display a 7 segmenti connesso alla porta B, si visualizzano in forma sequeziale
;i numeri dall'1 al 6, con intervalli di 0.05". Quando RA0 passa a livello "0", si
visualizza
;il numero aleatorio ottenuto in un tempo di 3". Poi il display si spegne e la
;sequenza si ripete.
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Numero equ 0x0c ;Numero aleatorio
Delay_Cont equ 0x0d ;Contatore di intervalli
Temporale equ 0x0e ;Variabile temporale
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva vettore di interrupt
;**********************************************************************************
;Tabella: Questa procedura converte il codice binario presente nei 4 bits di minor peso
;del reg. W nel suo equivalente a 7 segmenti. Il codice a 7 segmenti ritorna anche
;nel reg. W
Tabella: addwf PCL,F ;Spostamento sulla tabella
retlw b'00111111' ;Cifra 0
retlw b'00000110' ;Cifra 1
retlw b'01011011' ;Cifra 2
retlw b'01001111' ;Cifra 3
retlw b'01100110' ;Cifra 4
retlw b'01101101' ;Cifra 5
retlw b'01111101' ;Cifra 6
;*********************************************************************************
;Delay_20_ms: Questa procedura di temporizzazione ha per scopo di eliminare l'"effetto
;rimbalzo" delle periferiche elettromeccaniche. Realizza un delay di 20 mS. Se il PIC
;lavora a una frequenza di 4MHz, il TMR0 cambia ogni uS. Se vogliamo tempori-
;zzare 20000 uS (20 mS) con un prescaler di 256, i TMR0 dovrà contare 78 eventi
;(78 * 256). Il valore 78 equivale a 0x4e hex. e poiché il TMR0 è ascendente bisognerà
;caricare il suo complemento a 1 (0xb1 hex.).
Delay_20_ms: bcf INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0xb1 ;Complemento hex. de 78
movwf TMR0 ;carica il TMR0
Delay_20_ms_1 clrwdt ;Aggiornare il WDT
btfss INTCON,T0IF ;Overflow del TMR0 ??
goto Delay_20_ms_1 ;Ancora no
return
;*********************************************************************************
;Delay_var: Questa pocedura a scopo generale realizza una temporizzazione variabile
;tra 50 mS e 12.8". Si impiega un prescaler di 256 e il TMR0 viene caricato con 195.
;La velocità di lavoro è di 4Mhz e quindi il TMR0 aumenta ogni uS. In
;questo modo, il TMR0 deve contare 195 eventi che, con un preescaler di 128 fa un
;intervallo totale di 50000 uS/50 mS (195 * 256). Il valore 195 deve essere espresso
;in Hex. (c3) e poichè il TMR0 è ascendente bisognerà caricare il suo complemento (3C
hex.)
;Tale intervallo di 50 mS si ripete tante volte quante ne indica la variabile
"Delay_cont",
;è per questo che il delay minimo è di 50 mS ("Delay_cont=1) e il massimo di 12.8"
;(Delay_cont=255).
Delay_var: bcf INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0x3c ;Complemento hex. de 195
movwf TMR0 ;carica il TMR0
Intervallo clrwdt ;Aggiornare il WDT
btfss INTCON,T0IF ;Overflow del TMR0 ??
goto Intervallo ;Ancora no
decfsz Delay_Cont,F ;Diminuisci contatore di intervalli
goto Delay_var ;Ripeti l'intervallo di 50 mS
return
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP0 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come uscita
movlw b'00011111'
movwf TRISA ;Porta A si configura come entrata
movlw b'00000111'
movwf OPTION_REG ;Prescaler di 256 per il TMR0
bcf STATUS,RP0 ;Seleziona banco 0
Loop clrwdt ;Aggiornare il WDT
btfss PORTA,0 ;Attivato RA0 ??
goto Loop ;Ancora No
movf TMR0,W ;Adesso sì.
movwf Numero ;Cattura il valore del TMR0 (Nº aleatorio)
call Delay_20_ms ;Elimina rimbalzi
;Il numero aleatorio viene, mediante sottrazioni consecutive, diviso in 6. In questo modo
;l'ultimo resto sarà tra 0 e 5 che verrà incrementato di una unità affinché si abbia
defini-
;tivamente un numero tra 1 e 6
Dividi: movlw d'6'
subwf Numero,W ;Sottrai 6 al numero aleatorio
movwf Numero ;conservalo
sublw d'5'
btfss STATUS,C ;Guarda se è minore de 5
goto Dividi ;No
incf Numero,F ;Il numero è tra 1 e 6
;Questa procedura di istruzioni ha per scopo di mostrare sul display i numeri
;dall'1 al 6 a intervalli di 0.05" per dare una sensazione di movimento del dado.
;Tale movimento viene mantenuto mentre RA0 é a "1". Andando a "0" si presenta il
;numero aleatorio precedentemente catturato dal TMR0
Dado: movlw d'6'
movwf Temporale ;Avvia il contatore del dado
RA0_1 clrwdt ;Aggiornamento del WDT
btfss PORTA,0 ;Guarda se RA0 è a 1
goto Uscita ;No, visualizza l'aleatorio
movf Temporale,W ;Numero da visualizzare
call Tabella ;Conversione in BCD
movwf PORTB ;Visualizza sul display
movlw d'1'
movwf Delay_Cont ;Variabile di temporizzazione
call Delay_var ;temporizza 0.05"
decfsz Temporale,F ;Numero seguente
goto RA0_1
goto Dado
call Delay_20_ms ;Elimina rimbalzi
Uscita: movf Numero,W ;Riprendi l'aleatorio
call Tabella ;Lo converte in 7 segmenti
movwf PORTB ;Uscita sul Display
movlw d'60'
movwf Delay_Cont ;avvia variabile di temporizzazione
call Delay_var ;Temporizza 3"
clrf PORTB ;Disconnetti l'uscita
goto Loop
end ;Fine del programma principale
;
; ESEMPIO 2.18
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;Il TMR0 come contatore di eventi esterni
;
;Un sensore optoelettronico connesso a RA4 genera un impulso ogni volta che un oggetto si
;iterpone tra l'emissore e il recettore di luce. Il TMR0 si incarica di contarli
;a seconda del valore del prescaler. Tale valore si aggiusta mediante 3 interruttori
;(RA0-RA2) connessi alla Porta A, essendoci così 8 pre-divisioni:
;
; I2 I1 I0 Divisione
; -- -- -- --------
; 0 0 0 1:2
; 0 0 1 1:4
; 0 1 0 1:8
; 0 1 1 1:16
; 1 0 0 1:32
; 1 0 1 1:64
; 1 1 0 1:128
; 1 1 1 1:256
;
; Il conteggio è visualizzato in binario sui leds collegato alla Porta B e
;deve essere moltiplicato per il valore del prescaler selezionato, per determinare il
numero
;totale di impulsi. Il contatore si riassetta mettendo RA3 a "1". Va tenuto conto del
;"effetto rimbalzo" che si produce nell'interruttore RA4 del MicroPIC Trainer.
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni de registri interni
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva vettore di interrupt
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP0 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come uscita
movlw b'00011111'
movwf TRISA ;Porta A si configura come entrata
movlw b'00110000'
movwf OPTION_REG ;TMR0 contatore sensibile al discendente di RA4
bcf STATUS,RP0 ;Seleziona banco 0
Loop clrf TMR0 ;Mettere a 0 il contatore
Loop1: clrwdt ;Aggiorna il WDT
btfsc PORTA,3 ;Controlla se I3 è attivo (RESET)
goto Loop ;Sì Conto arrestato e settaggio a 0
movf PORTA,W ;No, leggere I2-I0 per formare il nuovo valore
andlw b'00000111' ;del prescaler
bsf STATUS,RP0 ;Seleziona pagina 1
iorwf OPTION_REG,F ;Aggiorna il nuovo valore del prescaler
bcf STATUS,RP0 ;Seleziona pagina 0
movf TMR0,W ;Leggi il valore del contatore
movwf PORTB ;Uscita ai leds
goto Loop1
end ;Fine del programma principale
;
; ESEMPIO 2.19
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;La memoria EEPROM di dati.La macchina "SUO TURNO"
;
;Si tratta di simulare il funzionamento delle macchine tipo "SUO TURNO" comuni in
molteplici
;attività. Sul display verrà visualizzato il numero del turno attuale. Questo aumenta a
;ogni impulso applicato da RA0. Nella memoria EEPROM del PIC16F84 si immagazzina l'ultimo
numero
;visualizzato, in modo che, davanti a una mancanza di alimentazione (p.e.), si riprenda
il conto dall'
;ultimo numero.
;
;Se si inizia utilizzando il sistema per la prima volta , si visualizza lo 0
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Contatore equ 0x0c ;Variabile per il contatore
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva vettore di interrupt
;****************************************************************************************
;EE_Write: Registra un byte nella EEPROM di dati. L'indirizzo sarà quello contenuto in
EEADR e
;il dato si suppone sia stato precedentemente messo in EEDATA
EE_Write bsf STATUS,RP0 ;Seleziona banco 1
bsf EECON1,WREN ;Permesso di scrittura
movlw b'01010101'
movwf EECON2
movlw b'10101010'
movwf EECON2 ;Sequenza stabilita da Microchip
bsf EECON1,WR ;Ordine di scrittura
bcf EECON1,WREN ;Disconnetti permesso di scrittura
Wait btfss EECON1,EEIF ;Controllare flag di fine di scrittura
goto Wait
bcf EECON1,EEIF ;Rimettere flag di fine di scrittura
bcf STATUS,RP0 ;Selezione banco 0
return
;**************************************************************************************
;EE_Read: Leggere un byte dalla EEPROM. Il registro EEADR deve essere caricato con
l'indiriz-
;zo da leggere. In EEDATA apparirà il dato letto.
EE_Read bsf STATUS,RP0 ;Selezione di banco 1
bsf EECON1,RD ;Ordine di lettura
bcf STATUS,RP0 ;Selezione di banco 0
return
;**********************************************************************************
;Tabella: Questa procedura converte il codice BCD presente nei 4 bits di minor peso
;del reg. W nel suo equivalente a 7 segmenti. Il codice a 7 segmenti ritorna anche
;nel reg. W
Tabella: addwf PCL,F ;Spostamento sulla tabella
retlw b'00111111' ;Cifra 0
retlw b'00000110' ;Cifra 1
retlw b'01011011' ;Cifra 2
retlw b'01001111' ;Cifra 3
retlw b'01100110' ;Cifra 4
retlw b'01101101' ;Cifra 5
retlw b'01111101' ;Cifra 6
retlw b'00000111' ;Cifra 7
retlw b'01111111' ;Cifra 8
retlw b'01100111' ;Cifra 9
;*********************************************************************************
;Delay_20_ms: Questa procedura di temporizzazione ha per scopo di eliminare l'"effetto
;rimbalzo" delle periferiche elettromeccaniche. Realizza un delay di 20 mS. Se il PIC
;lavora a una frequenza di 4MHz, il TMR0 cambia ogni uS. Se vogliamo tempori-
;zzare 20000 uS (20 mS) con un prescaler di 128, il TMR0 dovrà contare 156 eventi
;(156 * 128). Il valore 156 equivale a 9c hex. e poiché il TMR0 è ascendente bisognerà
;caricare il suo complemento a 1 (63 hex.).
Delay_20_ms: bcf INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0x63 ;Complemento hex. de 156
movwf TMR0 ;carica il TMR0
Delay_20_ms_1 clrwdt ;Aggiornare il WDT
btfss INTCON,T0IF ;Overflow del TMR0 ??
goto Delay_20_ms_1 ;Ancora no
bcf INTCON,T0IF ;Adesso sì, rimettere il flag
return
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP0 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come uscita
movlw b'00011111'
movwf TRISA ;Porta A si configura come entrata
movlw b'00000110'
movwf OPTION_REG ;Prescaler di 128 per il TMR0
bcf STATUS,RP0 ;Seleziona banco 0
clrf EEADR ;Seleziona indirizzo 00 di EEPROM
call EE_Read ;Leggi byte dalla EEPROM
movlw 0x09
subwf EEDATA,W
btfsc STATUS,C ;Maggiore di 9 ??
goto Ini_0 ;Sì, mettere a 0 il contatore
goto Ini_1 ;No
Ini_0 clrf Contatore ;Mettere a 0 il contatore
goto Loop
Ini_1 movf EEDATA,W
movwf Contatore ;Avviare contatore
Loop movf Contatore,W
call Tabella ;Converti contatore a 7 segmenti
movwf PORTB ;Visualizza sul display
Wait_0 clrwdt ;Aggiorna il WDT
btfss PORTA,0 ;RA0 è a "1" ??
goto Wait_0 ;No, aspettare
call Delay_20_ms ;Eliminare rimbalzi
Wait_1 clrwdt ;Aggiornare il WDT
btfsc PORTA,0 ;RA0 è a "0" ??
goto Wait_1 ;No, aspettare
call Delay_20_ms ;Eliminare rimbalzi. C'è stata un impulso
incf Contatore,F ;Aumenta contatore
movlw .10
subwf Contatore,W
btfsc STATUS,Z ;Contatore maggiore di 9 ??
clrf Contatore ;Sì, ritorno a 00
movf Contatore,W
movwf EEDATA
call EE_Write ;Registra il nuovo valore del contatore nella EEPROM
goto Loop
end ;Fine del programma principale
;
; ESEMPIO 2.20
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;L'uso dello schermo LCD
;
;Questo esempio vuole introdurci all'utilizzo dello schermo LCD, per visualizzare
;differenti messaggi (p.e. Ciao).
;
;Va ricordato che le linee RA0-RA2 agiscono ora come uscita di segnali di controllo verso
;l'LCD. Essendo connesse ai propri interruttori nel MicroPIC Trainer, questi devono
;essere permanentemente a livello logico "1" .
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Lcd_var equ 0x0c ;Variabili (2) delle procedure di utilizzo dell'LCD
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva vettore di interrupt
include "LCD_Cxx.inc" ;Include le procedure di utilizzo dell'LCD
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP0 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come uscita
movlw b'00011000'
movwf TRISA ;RA0-RA2 uscite, RA3-RA4 entrate
bcf STATUS,RP0 ;Seleziona banco 0
call LCD_INI ;Sequenza di inizio dell'LCD
movlw b'00001111'
call LCD_REG ;Invia istruzione: LCD ON, Cursore ON e blink ON
movlw 'C'
call LCD_DATO ;Visualizza C
movlw 'i'
call LCD_DATO ;Visualizza i
movlw 'a'
call LCD_DATO ;Visualizza a
movlw 'o'
call LCD_DATO ;Visualizza o
movlw ' '
call LCD_DATO ;Visualizza bianco
Loop sleep ;Messa in Standby
goto Loop ;Ritorno in standby
end ;Fine del programma principale
;
; ESEMPIO 2.21
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;L'uso dello schermo LCD
;
;Questo esempio vuole introdurci all'utilizzo dello schermo LCD, per visualizzare
;differenti messaggi.
;
;Va ricordato che le linee RA0-RA2 agiscono ora come uscita di segnali di controllo verso
;l'LCD. Essendo connesse ai propri interruttori nel MicroPIC Trainer, questi devono
;essere permanentemente a livello logico "1" .
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Lcd_var equ 0x0c ;Variabili (2) delle procedure d'uso dell'LCD
Delay_Cont equ 0x0e ;Variabile per la temporizzazione
Temporal_1 equ 0x0f ;Variabile temporale
Temporal_2 equ 0x10 ;Variabile temporale
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva vettore di interrupt
include "LCD_Cxx.inc" ;Include le procedure d'uso dell'LCD
;****************************************************************************************
**
;A seconda del valore contenuto nel registro W, si restituisce il carattere da
visualizzare
Tabella_Messaggi movwf PCL ;Calcola lo spostamento sulla tabella
Mess_0 equ $ ;Mess_0 punta al primo carattere del messaggio 0
retlw 'C'
retlw 'i'
retlw 'a'
retlw 'o'
retlw 0x00 ;Ultimo carattere del messaggio 0
Mess_1 equ $ ;Mess_1 punta al primo carattere del messaggio 1
retlw 'H'
retlw 'e'
retlw 'l'
retlw 'l'
retlw 'o'
retlw 0x00 ;Ultimo carattere del messaggio 1
;*********************************************************************************
;Delay_var: Questa procedura a scopo generale realizza una temporizzazione variabile
;tra 50 mS e 12.8". Si impiega un prescaler di 256 e il TMR0 viene caricato con 195.
;La velocità di lavoro è di 4Mhz e quindi il TMR0 aumenta ogni uS. In
;questo modo, il TMR0 deve contare 195 eventi che, con un prescaler di 256 fa un
;intervallo totale di 50000 uS/50 mS (195 * 256). Il valore 195 deve essere espresso
;in Hex. (c3) e poiché il TMR0 è ascendente bisognerà caricare il suo complemento (3C
hex.)
;Tale intervallo di 50 mS si ripete tante volte quante ne indica la variabile
"Delay_cont",
;è per questo che il delay minimo è di 50 mS ("Delay_cont=1) e il massimo di 12.8"
;(Delay_cont=255).
Delay_var: bcf INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0x3c ;Complemento hex. di 195
movwf TMR0 ;Carica il TMR0
Intervallo clrwdt ;Aggiornare il WDT
btfss INTCON,T0IF ;Overflow del TMR0 ??
goto Intervallo ;Ancora no
decfsz Delay_Cont,F ;Diminuisci contatore di intervalli
goto Delay_var ;Ripeti l'intervallo di 50 mS
return
;*************************************************************************************
;Messaggio: Questa procedura visualizza sull'LCD il messaggio il cui inizio è indicato
;nell'accumulatore. La fine di un messaggio si determina mediante il codice 0x00
Messagg movwf Temporal_1 ;Salva posizione della tabella
Messagg_1 movf Temporal_1,W ;Recupera posizione della tabella
call Tabella_Messaggi ;Cerca carattere di uscita
movwf Temporal_2 ;Mantieni il carattere
movf Temporal_2,F
btfss STATUS,Z ;Guarda se è l'ultimo
goto No_è_ultimo
return
No_è_ultimo call LCD_DATO ;Visualizza sull'LCD
incf Temporal_1,F ;Carattere succesivo
goto Messagg_1
;**********************************************************************************
;
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP0 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come usicta
movlw b'00011000'
movwf TRISA ;RA0-RA2 uscite, RA3-RA4 entrate
movlw b'00000111'
movwf OPTION_REG ;Prescaler di 256 per il TMR0
bcf STATUS,RP0 ;Seleziona banco 0
call LCD_INI ;Sequenza di inizio dell'LCD
movlw b'00001100'
call LCD_REG ;Invia istruzione: LCD ON, Cursore OFF e blink OFF
Loop movlw b'00000001'
call LCD_REG ;Cancella LCD e Home (collocare cursore in 1ª
posizione)
movlw Mess_0
call Messagg ;Visualizza il messaggio 0
movlw .20
movwf Delay_Cont
call Delay_var ;Temporizza 2 secondi
movlw b'00000001'
call LCD_REG ;Cancella LCD e Home (collocare cursore in 1ª
posizione)
movlw Mess_1
call Messagg ;Visualizza il messaggio 1
movlw .20
movwf Delay_Cont
call Delay_var ;Temporizza 2 secondi
goto Loop
end ;Fine del programma principale
;
; ESEMPIO 2.22
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;L'uso dello schermo LCD, ancora più messaggi.
;
;Questo esempio vuole introdurci all'utilizzo dello schermo LCD, per visualizzare
;differenti messaggi.
;
;Va ricordato che le linee RA0-RA2 agiscono ora come uscita di segnali di controllo verso
;l'LCD. Essendo connesse con i propri interruttori nel MicroPIC Trainer, questi devono
;essere permanentemente a livello logico "1" .
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Lcd_var equ 0x0c ;Variabili (2) delle procedure di utilizzo dell'LCD
Delay_Cont equ 0x0e ;Variabile per la temporizzazione
Temporal_1 equ 0x0f ;Variabile temporale
Temporal_2 equ 0x10 ;Variabile temporale
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva vettore di interrupt
include "LCD_Cxx.inc" ;Include le procedure di utilizzo dell'LCD
;****************************************************************************************
**
;Secondo il valore contenuto nel registro W, si restituisce il carattere da visualizzare
Tabel_Messaggi movwf PCL ;Calcola lo spostamento sulla tabella
;***********************************************************************************
;La direttiva dt genera tante istruzioni retlw quanti bytes o caratteri contiene
Mess_0 equ $ ;Mess_0 punta al primo carattere del messaggio 0
dt "Microsystems",0x00
Mess_1 equ $ ;Mess_1 punta al primo carattere del messaggio 1
dt "Engineering",0x00
Mess_2 equ $ ;Mess_2 punta al primo carattere del messaggio 2
dt "Gral. Concha 39",0x00
Mess_3 equ $ ;Mess_3 punta al primo carattere del messaggio 3
dt "48012 Bilbao",0x00
;*********************************************************************************
;Delay_var: Questa procedura di scopo generale realizza una temporizzazione variabile
;tra 50 mS e 12.8". Si impiega un prescaler di 256 e il TMR0 viene caricato con 195.
;La velocità di lavoro è di 4Mhz e quindi il TMR0 aummenta ogni uS. In
;questo modo, il TMR0 deve contare 195 eventi che, con un prescaler di 256 fa un
;intervallo totale di 50000 uS/50 mS (195 * 256). Il valore 195 deve essere espresso
;in Hex. (c3) e poiché il TMR0 è ascendente bisognerà caricare il suo complemento (3C
hex.)
;Tale intervallo di 50 mS si ripete tante volte quante ne indica la variabile
"Delay_cont",
;è per questo che il delay minimo è di 0 mS ("Delay_cont=1) e il massimo di 12.8"
;(Delay_cont=255).
Delay_var: bcf INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0x3c ;Complemento hex. di 195
movwf TMR0 ;carica il TMR0
Intervallo clrwdt ;Aggiornare il WDT
btfss INTCON,T0IF ;Overflow del TMR0 ??
goto Intervallo ;Ancora no
decfsz Delay_Cont,F ;Diminuisci contatore di intervalli
goto Delay_var ;Ripeti l'intervallo di 50 mS
return
;*************************************************************************************
;Messaggio: Questa procedura visualizza sull'LCD il messaggio il cui inizio è indicato
;nell'accumulatore. La fine di un messaggio si determina mediante il codice 0x00
Messagg movwf Temporal_1 ;Salva posizione della tabella
Messagg_1 movf Temporal_1,W ;Recupera posizione della tabella
call Tabel_Messaggi ;Cerca carattere di uscita
movwf Temporal_2 ;Mantieni il carattere
movf Temporal_2,F
btfss STATUS,Z ;Guarda se è l'ultimo
goto No_è_ultimo
return
No_è_ultimo call LCD_DATO ;Visualizza sull'LCD
incf Temporal_1,F ;Carattere successivo
goto Messagg_1
;**********************************************************************************
;
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP0 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come uscita
movlw b'00011000'
movwf TRISA ;RA0-RA2 uscite, RA3-RA4 entrate
movlw b'00000111'
movwf OPTION_REG ;Prescaler di 256 per il TMR0
bcf STATUS,RP0 ;Seleziona banco 0
call LCD_INI ;Sequenza di inizio dell'LCD
movlw b'00001100'
call LCD_REG ;Invia istruzione: LCD ON, Cursore OFF e blink OFF
Loop movlw b'00000001'
call LCD_REG ;Cancella LCD e Home (collocare cursore in 1ª
posizione)
movlw Mess_0
call Messagg ;Visualizza il messaggio 0
movlw b'11000101'
call LCD_REG ;Colloca cursore in 2ª fila dell'LCD
movlw Mess_1
call Messagg ;Visualizza messaggio 1
movlw .40
movwf Delay_Cont
call Delay_var ;Temporizza 4 secondi
movlw b'00000001'
call LCD_REG ;Cancella LCD e Home (collocare cursore in 1ª
posizione)
movlw Mess_2
call Messagg ;Visualizza il messaggio 2
movlw b'11000010'
call LCD_REG ;Colloca cursore in 2ª fila dell'LCD
movlw Mess_3
call Messagg ;Visualizza il messaggio 3
movlw .40
movwf Delay_Cont
call Delay_var ;Temporizza 4 secondi
goto Loop
end ;Fine del programma principale
;
; ESEMPIO 2.23
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;L'uso dello schermo LCD. Un semplice generatore di messaggi.
;
;Questo esempio vuole realizzare un generatore di messaggi per l'LCD. Con RA4 a "1", il
;sistema è nel modo di programmazione. In questo modo il messaggio è registrato nella
EEPROM
;di dati. Con RA4 a "0" entriamo nel modo di riproduzione. Il messaggio registrato nella
;EEPROM viene visualizzato sull'LCD.
;
;Quando l'interruttore RA3 è a livello "1", nella posizione attuale del cursore appaio-
;no sequenzialmente i distinti caratteri disponibili. Mettendolo a "0" si sele-
;ziona l'attuale e si registra nella EEPROM. Ritornando di nuovo a "1" si seleziona il
se-
;guente carattere.
;
;Va ricordato che le linee RA0-RA2 ora agiscono come uscita di segnali di controllo verso
;l'LCD. Essendo connesse ai propri interruttori nel MicroPIC Trainer, questi devono
;essere permanentemente a livello logico "1" .
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Lcd_var equ 0x0c ;Variabili (2) delle procedure d'uso dell'LCD
Delay_Cont equ 0x0e ;Variabile per la temporizzazione
Temporale_1 equ 0x0f ;Variabile temporale
Temporale_2 equ 0x10 ;Variabile temporale
Cur_Pos equ 0x11 ;Posizione del cursore
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva vettore di interrupt
include "LCD_Cxx.inc" ;Include le procedure d'uso dell'LCD
;*********************************************************************************
;Delay_20_ms: Questa procedura di temporizzazione ha per scopo di eliminare l'"effetto
;rimbalzo" delle periferiche elettromeccaniche. Realizza un delay di 20 mS. Se il PIC
;lavora a una frequenza di 4MHz, il TMR0 cambia ogni uS. Se vogliamo temporiz-
;zare 20000 uS (20 mS) con un prescaler di 128, il TMR0 dovrà contare 156 eventi
;(156 * 128). Il valore 156 equivale a 9c hex. e poiché il TMR0 è ascedente bisognerà
;caricare il suo complemento a 1 (63 hex.).
Delay_20_ms: bcf INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0x63 ;Complemento hex. di 156
movwf TMR0 ;carica il TMR0
Delay_20_ms_1 clrwdt ;Aggiornare il WDT
btfss INTCON,T0IF ;Overflow del TMR0 ??
goto Delay_20_ms_1 ;Ancora no
bcf INTCON,T0IF ;Adesso sì, rimettere il flag
return
;*********************************************************************************
;Delay_var: Questa procedura a scopo generico realizza una temporizzazione variabile
;tra 50 mS e 12.8". Si impiega un prescaler di 256 e il TMR0 viene caricato con 195.
;La velocità di lavoro è di 4Mhz e quindi il TMR0 aumenta ogni uS. In
;questo modo, il TMR0 deve contare 195 eventi che, con un prescaler di 256 fa un
;intervallo totale di 50000 uS/50 mS (195 * 256). Il valore 195 deve essere espresso
;in Hex. (c3) e poiché il TMR0 è ascendente bisognerà caricare il suo complemento (3C
hex.)
;Tale intervallo di 50 mS si ripete tante volte quante ne indica la variabile
"Delay_cont",
;è per questo che il delay minimo è di 50 mS ("Delay_cont=1) e il massimo di 12.8"
;(Delay_cont=255).
Delay_var: bcf INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0x3c ;Complemento hex. di 195
movwf TMR0 ;carica il TMR0
Intervallo clrwdt ;Aggiornare il WDT
btfss INTCON,T0IF ;Overflow del TMR0 ??
goto Intervallo ;Ancora no
decfsz Delay_Cont,F ;Diminuisci contatore di intervalli
goto Delay_var ;Ripeti l'intervallo di 50 mS
return
;****************************************************************************************
;EE_Write: Registra un byte nella EEPROM di dati. L'indirizzo sarà quello contenuto in
EEADR e
;il dato si suppone sia stato precedentemente messo in EEDATA
EE_Write bsf STATUS,RP0 ;Seleziona banco 1
bsf EECON1,WREN ;Permesso di scrittura
movlw b'01010101'
movwf EECON2
movlw b'10101010'
movwf EECON2 ;Sequenza stabilita da Microchip
bsf EECON1,WR ;Ordine di scrittura
bcf EECON1,WREN ;Disconnetti permesso di scrittura
Wait btfss EECON1,EEIF ;Testare flag di fine scrittura
goto Wait
bcf EECON1,EEIF ;Rimettere flag di fine scrittura
bcf STATUS,RP0 ;Seleziona banco 0
return
;**************************************************************************************
;EE_Read: Leggere un byte della EEPROM. Si suppone che il registro EEADR sia caricato con
l'indiriz-
;zo da leggere. In EEDATA apparirà il dato letto.
EE_Read bsf STATUS,RP0 ;Selezione di banco 1
bsf EECON1,RD ;Ordine di lettura
bcf STATUS,RP0 ;Selezione di banco 0
return
;**********************************************************************************
;
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP0 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come uscita
movlw b'00011000'
movwf TRISA ;RA0-RA2 uscite, RA3-RA4 entrate
movlw b'00000111'
movwf OPTION_REG ;Prescaler di 256 per il TMR0
bcf STATUS,RP0 ;Seleziona banco 0
movlw 0x80
movwf Cur_Pos ;Posizione iniziale del cursore
call LCD_INI ;Sequenza di inizio dell'LCD
movlw b'00000001'
call LCD_REG ;Cancella LCD e Home
movlw b'00001110'
call LCD_REG ;Invia istruzione: LCD ON, Cursore ON e blink OFF
clrf EEADR ;Indirizzo iniziale della EEPROM
Loop btfss PORTA,4 ;Modo programmazione ??
goto Riprodurre ;No, modo di riproduzione
Programmare movlw 0x20
movwf Temporale_1 ;Primo carattere ASCII
Program_1 btfss PORTA,3 ;Registrare il byte in EEPROM ??
goto Registrare ;Sì
movf Cur_Pos,W
call LCD_REG ;Colloca il cursore
movf Temporale_1,W
call LCD_DATO ;Visualizza il carattere
movlw .10
movwf Delay_Cont
call Delay_var ;Temporizza 0.5 secondi
incf Temporale_1,F ;Seguente carattere ASCII
btfss Temporale_1,7 ;E' l'ultimo carattere ASCII ??
goto Program_1 ;No
goto Programmare ;Sì, iniziare dal primo
Registrare call Delay_20_ms ;Elimina rimbalzi
decf Temporale_1,W
movwf EEDATA ;Dato da registrare nella EEPROM
call EE_Write ;Registra il carattere
incf EEADR,F ;Seguente indirizzo EEPROM
clrf EEDATA
call EE_Write ;Registra 0x00
incf Cur_Pos,F ;Seguente posizione del cursore
Registr_1 clrwdt ;Aggiornare il WDT
btfss PORTA,3 ;Aspettare che RA3 torni a "1"
goto Registr_1
call Delay_20_ms ;Eliminare rimbalzi
goto Loop ;Seguente carattere del messaggio
Riprodurre movlw b'00000001'
call LCD_REG ;Cancella LCD e Home
movlw b'00001100'
call LCD_REG ;LCD = ON, cursore = OFF
clrf EEADR ;Indirizzo iniziale EEPROM
Riprodurre_0 clrwdt ;Aggiornamento del WDT
call EE_Read ;Leggi carattere della EEPROM
movf EEDATA,F
btfsc STATUS,Z ;E' l'ultimo del messaggio ?? (0x00)
goto Riprodurre_1 ;Sì
movf EEDATA,W
call LCD_DATO ;Visualizza il carattere
incf EEADR,F ;Seguente carattere
goto Riprodurre_0
Riprodurre_1 movlw .40
movwf Delay_Cont
call Delay_var ;Mantieni il messaggio 2 secondi
;**************************** SEQUENZA DI INTERMITTENZA
**********************************
Blink movlw .6
movwf Temporale_2 ;Avvia contatore di intermittenze
Blink_1 movlw b'00001100'
call LCD_REG ;LCD in ON
movlw .5
movwf Delay_Cont
call Delay_var ;Temporizza 0.25 secondi
movlw b'00001000'
call LCD_REG ;LCD in OFF
movlw .5
movwf Delay_Cont
call Delay_var ;Temporizza 0.25 secondi
decfsz Temporale_2,F
goto Blink_1 ;Ripeti l'intermittenza
movlw .20
movwf Delay_Cont
call Delay_var ;Temporizza 1 secondo
goto Loop
end ;Fine del programma principale
;
; ESEMPIO 2.24
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;La memoria EEPROM di dati e l'LCD.La macchina "SUO TURNO", versione migliorata.
;
;Si tratta di simulare il funzionamento delle macchine tipo "SUO TURNO" comuni in
molteplici
;attività. Sull'LCD verrà visualizzato il numero del turno attuale (2 cifre). Questo
;aumenta a ogni impulso applicato da RA4. Nella memoria EEPROM del PIC16F84 viene
immagazzinato
;l'ultimo numero visualizzato, in modo che, davanti a un difetto di alimentazione (p.e.),
si riprenda
;il conto dall'ultimo numero.
;
;Se si inizia utilizzando il sistema per la prima volta, verrà visualizzto lo 00
;
;Va ricordato che le linee RA0-RA2 agiscono come uscita di segnali di controllo verso il
;LCD. Essendo connesse ai propri interruttori nel MicroPic Trainer, questi devono essere
;permanentemente a livello logico "1" .
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
Lcd_var equ 0x0c ;Variabili (2) per procedure d'uso dell'LCD
Contatore_L equ 0x0e ;Variabile per il contatore parte bassa
Contatore_H equ 0x0f ;Variabile per il contatore parte alta
Temporale_1 equ 0x10 ;Variabile temporale
Temporale_2 equ 0x11 ;Variabile temporale
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva vettore di interrupt
include "LCD_Cxx.inc" ;Include le procedure d'uso dell'LCD
;****************************************************************************************
;EE_Write: Registra un byte nella EEPROM di dati. L'indirizzo sarà quello contenuto in
EEADR e si suppone
;che il dato sia stato precedentemente messo in EEDATA
EE_Write bsf STATUS,RP0 ;Seleziona banco 1
bsf EECON1,WREN ;Permesso di scrittura
movlw b'01010101'
movwf EECON2
movlw b'10101010'
movwf EECON2 ;Sequenza stabilita da Microchip
bsf EECON1,WR ;Ordine di scrittura
bcf EECON1,WREN ;Disconnetti permesso di scrittura
Wait btfss EECON1,EEIF ;Testare flag di fine scrittura
goto Wait
bcf EECON1,EEIF ;Rimettere flag di fine scrittura
bcf STATUS,RP0 ;Selezione banco 0
return
;**************************************************************************************
;EE_Read: Leggere un byte della EEPROM. Si suppone che il registro EEADR sia caricato con
l'indi-
;rizzo da leggere. In EEDATA apparirà il dato letto.
EE_Read bsf STATUS,RP0 ;Selezione di banco 1
bsf EECON1,RD ;Ordine di lettura
bcf STATUS,RP0 ;Selezione di banco 0
return
;**********************************************************************************
;Secondo il valore contenuto nel registro W, si restituisce il carattere ASCII da
visualiz-
;zare nell'LCD
Tabella_Mess: movwf PCL ;Spostamento sulla tabella
;**********************************************************************************
;La direttiva dt genera tante istruzioni retlw quanti bytes o caratteri contiene
;chiusi tra "
Mess_0 equ $ ;Mess_0 punta al primo carattere
dt "Suo TURNO : ",0x00
;*********************************************************************************
;Delay_20_ms: Questa procedura di temporizzazione ha per scopo di eliminare l'"effetto
;rimbalzo" delle periferiche elettromeccaniche. Realizza un delay di 20 mS. Se il PIC
;lavora a una frequenza di 4MHz, il TMR0 cambia ogni uS. Se vogliamo temporiz-
;zare 20000 uS (20 mS) con un prescaler di 128, il TMR0 dovrà contare 156 eventi
;(156 * 128). Il valor 156 equivale a 9c hex. e poiché il TMR0 è ascendente bisognerà
;caricare il suo complemento a 1 (63 hex.).
Delay_20_ms: bcf INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0x63 ;Complemento hex. de 156
movwf TMR0 ;carica il TMR0
Delay_20_ms_1 clrwdt ;Aggiornare il WDT
btfss INTCON,T0IF ;Overflow del TMR0 ??
goto Delay_20_ms_1 ;Ancora no
bcf INTCON,T0IF ;Adesso sì, rimettere il flag
return
;*************************************************************************************
;Messaggio: Questa procedura visualizza sull'LCD il messaggio il cui inizio è indicato
;nell'accumulatore. La fine di un messaggio si determina mediante il codice 0x00
Messagg movwf Temporale_1 ;Salva posizione della tabella
Messagg_1 movf Temporale_1,W ;Recupera posizione della tabella
call Tabella_Mess ;Cerca carattere di uscita
movwf Temporale_2 ;Conserva il carattere
movf Temporale_2,F
btfss STATUS,Z ;Guarda se è l'ultimo
goto No_è_ultimo
return
No_è_ultimo call LCD_DATO ;Visualizza sull'LCD
incf Temporale_1,F ;Seguente carattere
goto Messagg_1
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP0 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come uscita
movlw b'00011000'
movwf TRISA ;RA0-RA2 entrate, resto entrate
movlw b'00000110'
movwf OPTION_REG ;Prescaler di 128 per il TMR0
bcf STATUS,RP0 ;Seleziona banco 0
call LCD_INI ;Sequenza di inizio del LCD
movlw b'00001100'
call LCD_REG ;Invia istruzione LCD ON, Cursore OFF e Blink OFF
movlw Mess_0
call Messagg ;Visualizza Mess_0 (Suo TURNO è: )
clrf EEADR ;Seleziona indirizzo 00 di EEPROM
call EE_Read ;Leggi byte della EEPROM
movlw 0x09
subwf EEDATA,W
btfsc STATUS,C ;Contatore_H maggiore di 9 ??
goto Ini_0 ;Sì, mettere a 0 il contatore
goto Ini_1 ;No
Ini_0 clrf Contatore_L
clrf Contatore_H ;Mettere a 0 il contatore
goto Loop
Ini_1 movf EEDATA,W
movwf Contatore_H ;Aggiorna Contatore_H
incf EEADR,F ;Seguente posizione della EEPROM
call EE_Read ;Leggi il byte della EEPROM
movlw 0x09
subwf EEDATA,W
btfsc STATUS,C ;Contatore_L maggiore di 9 ??
goto Ini_0 ;Sì, mettere a 0 il contatore
movf EEDATA,W
movwf Contatore_L ;Aggiorna Contatore_L
Loop movlw 0x8d
call LCD_REG ;Posiziona il cursore dell'LCD
movf Contatore_H,W
iorlw 0x30 ;Converti in ASCII Contatore_H
call LCD_DATO ;Visualizza Contatore_H
movf Contatore_L,W
iorlw 0x30 ;Converti in ASCII Contatore_L
call LCD_DATO ;Visualizza contatore_L
Wait_0 clrwdt ;Aggiorna il WDT
btfss PORTA,4 ;RA4 è a "1" ??
goto Wait_0 ;No, aspettare
call Delay_20_ms ;Eliminare rimbalzi
Wait_1 clrwdt ;Aggiornare il WDT
btfsc PORTA,4 ;RA4 è a "0" ??
goto Wait_1 ;No, aspettare
call Delay_20_ms ;Eliminare rimbalzi. C'è stata un impulso
incf Contatore_L,F ;Aumenta contatore_L
movlw .10
subwf Contatore_L,W
btfss STATUS,Z ;Contatore maggiore di 9 ??
goto Write ;No, aggiornare EEPROM
clrf Contatore_L ;Si, Contatore_L passa a 0
incf Contatore_H,F ;Aumenta Contatore_H
movlw .10
subwf Contatore_H,W
btfss STATUS,Z ;Contatore_H maggiore di 9
goto Write ;No, aggiornare EEPROM
clrf Contatore_H ;Si, Contatore_H passa a 0
Write clrf EEADR ;Seleziona indirizzo 00 della EEPROM
movf Contatore_H,W
movwf EEDATA
call EE_Write ;Registra Contatore_H nella EEPROM
incf EEADR,F ;Indirizzo 01 della EEPROM
movf Contatore_L,W
movwf EEDATA
call EE_Write ;Registra Contatore_L nella EEPROM
goto Loop
end ;Fine del programma principale
;
; ESEMPIO 2.25
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;Il modo "sleep" e il "wake-up" (sveglia) mediante il watch-dog Timer (WDT)
;
;Questo esempio vuole mostrare l'impiego dell'istruzione SLEEP per mettere il PIC nel
;modo standby a basso consumo. Il "risveglio" dello stesso avverrà ogni volta che il WDT
eccede.
;In questo momento si produrrà un incremento del valore della porta B che agirà da
contatore
;binario e si tornerà nuovamente alla situazione di standby.
;
;Il prescaler si associerà al WDT e sarà compreso tra 1 e 128, a seconda dello stato
;logico degli interruttori RA0-RA2.
;
;Il valore nominale del WDT è di 18mS. Vale a dire, con un prescaler di 1, il pic "si
sveglierà"
;ogni 18mS, con un prescaler di 128, lo farà ogni 2,3 secondi.
List p=16F84 ;Tipo di processore
include "P16F84.INC" ;Definizioni di registri interni
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva vettore di interrupt
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP0 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come uscita
movlw b'00011111'
movwf TRISA ;RA0-RA4 entrate
movlw b'00001000'
movwf OPTION_REG ;Prescaler di 1 per el WDT
bcf STATUS,RP0 ;Seleziona banco 0
Loop sleep ;Modo Standby
incf PORTB,F ;Aumenta il contatore binario sulla porta B
movf PORTA,W
andlw b'00000111' ;Leggi lo stato degli interruttori RA0-RA2
iorlw b'00001000'
bsf STATUS,RP0 ;Seleziona banco 1
movwf OPTION_REG ;Registra valore del prescaler
bcf STATUS,RP0 ;Seleziona banco 1
goto Loop ;Tornare al modo Standby
end ;Fine del programma principale
;
; ESEMPIO 2.2
;
; Autore: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;Controllo dei leds RB0 e RB1 dall'interruttore RA0. RB0 riflette lo stato di RA0,
;RB1 il complemento di RA0
List p=16F876 ;Tipo di processore
include "P16F876.INC" ;Definizioni di registri interni
org 0x00 ;Vettore di Reset
goto Inizio
org 0x05 ;Salva il vettore di interrupt
Inizio clrf PORTB ;Cancella i latch di uscita
bsf STATUS,RP1 ;Seleziona banco 1
clrf TRISB ;Porta B si configura come uscita
movlw b'00011111'
movwf TRISA ;Porta A si configura come entrata
bcf STATUS,RP1 ;Seleziona banco 0
Loop clrwdt ;Aggiorna il WDT timer
btfsc PORTA,0 ;RA0 = 1 ??
goto RA0_es_1 ;Sì
bcf PORTB,0 ;No, disconnetti RB0
bsf PORTB,1 ;Connetti RB1
goto Loop ;Loop senza fine
RA0_es_1 bsf PORTB,0 ;Attiva RB0
bcf PORTB,1 ;Attiva RB1
goto Loop ;Loop senza fine
end ;Fine del programma principale
Top Related