Sunteți pe pagina 1din 45

;

;
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

Inizio

Stop

equ

0x10

;Determina la posizione del risultato

org
goto

0x00
Inizio

;Vettore di Reset

org

0x05
movlw 0x05
addlw 0x07
movwf Risultato

;Salva il vettore di interrupt


;Carica il 1 addendo in W
;Somma il 2 addendo
;Memorizza il risultato

nop
nop

;Metti breakpoint di arresto

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
Dato_B
Dato_C
Risultato

equ

equ
equ
equ
0x13

org
goto

0x00
Inizio

;Vettore di Reset

org

0x05

;Salva il vettore di interrupt

addwf
movwf
movf
subwf

movf Dato_A,W
;Carica il 1 addendo
Dato_B,W
;Somma il 2 addendo
Risultato
;Memorizza risultato parziale
Dato_C,W
;Carica il sottraendo
Risultato,F ;Sottrai dal minuendo e memorizza

Inizio

Stop

0x10
0x11
0x12

;Determina la posizione del dato A


;Determina la posizione del dato B
;Determina la posizione del dato C
;Determina la posizione del risultato

nop
nop

;Metti breakpoint di arresto

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
Dato_A_H
Dato_B_L
Dato_B_H
Risultato_L
Risultato_H

equ
equ
equ
equ
equ
equ

0x10
0x11
0x12
0x13
0x14
0x15

;Determina
;Determina
;Determina
;Determina
;Determina
;Determina

org
goto

0x00
Inizio

;Vettore di Reset

org

0x05

;Salva il vettore di interrupt

addwf
movwf
movf
btfsc
addlw
addwf
movwf

movf Dato_A_L,W ;Carica meno peso del dato A


Dato_B_L,W ;Somma meno peso del dato B
Risultato_L ;Memorizza il risultato
Dato_A_H,W ;Carica pi peso del dato A
STATUS,C
;C' stato trasporto anteriore ??
1
;Si, aggiungi 1 all'accumulatore
Dato_B_H,W ;Somma pi peso del dato B
Risultato_H ;Conserva il risultato

Inizio

Stop

la
la
la
la
la
la

posizione
posizione
posizione
posizione
posizione
posizione

del
del
del
del
del
del

dato A (basso)
dato A (alto)
dato B (basso)
dato B (alto)
risultato (basso)
risultato (alto)

nop
nop

;Metti breakpoint di arresto

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
Dato_A_H
Dato_B_L
Dato_B_H
Risultato_L
Risultato_H

equ
equ
equ
equ
equ
equ

0x10
0x11
0x12
0x13
0x14
0x15

;Determina
;Determina
;Determina
;Determina
;Determina
;Determina

org
goto

0x00
Inizio

;Vettore di Reset

org

0x05

;Salva il vettore di interrupt

subwf
movwf
movf
btfss
addlw
subwf
movwf

movf Dato_B_L,W ;Carica meno peso del dato B (sottraendo)


Dato_A_L,W ;Sottrai meno peso del dato A (minuendo)
Risultato_L ;Memorizza il risultato
Dato_B_H,W ;Carica pi peso del dato B (sottraendo)
STATUS,C
;C' stato trasporto(CARRY = 0) anteriore ??
1
;S, aggiungi 1 all'accumulatore (sottraendo)
Dato_A_H,W ;Sottrai pi peso del dato A (minuendo)
Risultato_H ;Conserva il risultato

Inizio

Stop

la
la
la
la
la
la

posizione
posizione
posizione
posizione
posizione
posizione

del
del
del
del
del
del

dato A (basso)
dato A (alto)
dato B (basso)
dato B (alto)
risultato (basso)
risultato (alto)

nop
nop

;Metti breakpoint d'arresto

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
Prima

equ

0x0c
equ

0x10

;Contatore interno
;Posizione iniziale

org
goto

0x00
Inizio

;Vettore di Reset

org

0x05

;Salva il vettore di interrupt

movwf
movlw
movwf
movlw

movlw .15
Contatore
Prima
FSR
0x33

Inizio

;Carica il contatore con 15 (in decimale)


;Orienta il puntatore con indirizzo iniziale
;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
nop

;Metti breakpoint d'arresto

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
Dato_B
Risultato

equ

equ
equ
0x12

org
goto

0x00
Inizio

;Vettore di Reset

org

0x05

;Salva il vettore di interrupt

subwf
btfsc
goto
btfsc
goto

movf Dato_B,W
;Carica il dato B
Dato_A,W
;Sottrai/paragona a dato A
STATUS,Z
;Sono uguali (Z=1)??
A_uguale_B ;S
STATUS,C
;No. A maggiore di B (C=0)??
A_mayor_B
;S

A_minor_B

movf
addwf
movwf
goto

Dato_A,W
Dato_B,W
Risultato
Stop

A_mayor_B

movwf Risultato
goto Stop

A_uguale_B

clrf

;Azzera il risultato

Stop

nop
nop

;Metti breakpoint d'arresto

end

;Fine del programma principale

Inizio

0x10
0x11

Risultato

;Variabile del dato A


;Variabile del dato B
;Variabile per il risultato

;No, A minore di B
;Somma A pi B
;Conserva il risultato

;
;
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

Inizio

Loop1

Loop2

equ

0x10

;Variabile per il contatore

org
goto

0x00
Inizio

;Vettore di Reset

org

0x05

;Salva il vettore di interrupt

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
movwf
clrf
movlw
movwf

.250
Contatore
INTCON
.7
TMR0

;Attiva la variabile contatore


;Disconnetti flag del TMR0 e interrupt
;Carica il TMR0 con complemento di 250

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
Stop

Loop1

nop
nop

;Metti breakpoint di arresto

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

;Inizio di definizione di variabili

Moltiplicando
Moltiplicatore
Risultato_H
Risultato_L
Estatus_Temp
Contatore

;Variabile per il moltiplicando


;Variabile per il moltiplicatore
;Parte alta del risultato
;Parte bassa del risultato
;Reg. di stato temporale
;Variabile con numero di volte per eseguire operazioni

endc

;Fine delle definizioni

org
goto

0x00
Inizio

;Vettore di Reset

org

0x05

;Salva il vettore di interrupt

clrf
movlw
movwf
bcf

clrf Risultato_H
Risultato_L ;Metti a 0000 il risultato iniziale
0x08
Contatore
;Avvia il contatore con 8
STATUS,C
;Cancella il carry

Inizio

Loop

0x10

movf Moltiplicando,W
btfsc Moltiplicatore,0
addwf Risultato_H,F

;Carica il moltiplicando
;E' 1 il bit di minor peso del moltiplicatore ??
;S, si somma il moltiplicando

rrf
rrf

;Spostamento a destra del risultato

Risultato_H,F
Risultato_L,F

;Ruota a destra il moltiplicatore senza che si modifichi il flag Carry


Ruota_sen_Carry
movwf
rrf
movf
movwf

movf STATUS,W
Estatus_Temp
Moltiplicatore,F
Estatus_Temp,W
STATUS

decfsz
goto Loop
Stop

;Salva provvisoriamente il carry


;Sposta a destra il moltiplicatore
;Recupera il carry originale

Contatore,F ;Ripeti il loop 8 volte

nop
nop

;Metti breakpoint d'arresto

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
Buffer_H
Buffer_L
Temp_1

equ
equ

0x10

0x13

;Valore binario iniziale


;Parte alta del risultato
;Parte bassa del risultato
;Registro temporale

org
goto

0x00
Inizio

;Vettore di Reset

org

0x05

;Salva il vettore di interrupt

Inizio
clrf

BIN_BCD_1

BIN_BCD_2

BIN_BCD_3

Stop

equ
0x11
0x12
equ

movf
Binario,W
;Carica il valore binario iniziale
Buffer_L
clrf
Buffer_H
;Attiva registri di lavoro
addlw
btfss
goto
movwf
incf
movf
xorlw
btfss
goto
clrf
incf
movf
goto

0xf6
STATUS,C
BIN_BCD_3
Temp_1
Buffer_L,F
Buffer_L,W
b'00001010'
STATUS,Z
BIN_BCD_2
Buffer_L
Buffer_H,F
Temp_1,W
BIN_BCD_1

addlw
swapf
iorwf

H'0A'
Buffer_L,F
Buffer_L,F

;Sottrai 10 mediante somma di complemento a 2.


;C' Carry?
;NO.
;SI.Conservare nel registro temporale.
;Aumentare byte basso, conservarlo e inviare...
;..copia al ==> W...
;..0Ah xor W.
;Buffer_L uguale a 10 ??
;NO.
;SI. Metti Buffer_L a 0
;Incrementare Buffer_H
;Recuperare il dato.
;Continuare l'operazione.
;TEMPO + 0Ah
;<3:0> <==> <7:4> y ==> Buffer_L
;W OR Buffer_L ==> Buffer_L

nop
nop

;Metti breakpoint d'arresto

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
Gray

equ
equ

0x10
0x11

;Valore BCD iniziale


;Valore ottenuto in codice GRAY

org
goto

0x00
Inizio

;Vettore di Reset

org

0x05

;Salva il vettore di interrupt

Tabel

addwf
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw

PCL,F
b'00000000'
b'00000001'
b'00000011'
b'00000010'
b'00000110'
b'00000111'
b'00000101'
b'00000100'
b'00001100'
b'00001101'

;Calcola spostamento sulla tabella


;Codice GRAY della cifra 0
;Codice GRAY della cifra 1
;Codice GRAY della cifra 2
;Codice GRAY della cifra 3
;Codice GRAY della cifra 4
;Codice GRAY della cifra 5
;Codice GRAY della cifra 6
;Codice GRAY della cifra 7
;Codice GRAY della cifra 8
;Codice GRAY della cifra 9

Inizio

movf
call Tabel
movwf Gray

Bcd,W
;Carica il valore BCD originale
;Converti in GRAY
;Conserva il risultato

Stop

nop
nop

;Metti breakpoint di arresto

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
goto

0x00
Inizio

;Vettore di Reset

org

0x05

;Salva il vettore di interrupt

bsf
clrf
movlw
movwf
bcf

clrf
STATUS,RP0
TRISB
b'00011111'
TRISA
STATUS,RP0

PORTB
;Cancella i latch di uscita
;Seleziona banco 1
;Porta B si configura come uscita

Inizio

;Porta A si configura come entrata


;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
goto
bcf
goto
bsf
goto

RA1_es_1:

end

PORTA,1
RA1_es_1
PORTB,7
Loop
PORTB,7
Loop

;Controlla RA1
;E' a "1"
;Disconnetti punto decimale
;Attiva punto decimale

;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
goto

0x00
Inizio

;Vettore di Reset

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
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw

PCL,F
b'00111111'
b'00000110'
b'01011011'
b'01001111'
b'01100110'
b'01101101'
b'01111101'
b'00000111'
b'01111111'
b'01100111'
b'01110111'
b'01111100'
b'00111001'
b'01011110'
b'01111001'
b'01110001'

;Spostamento sulla tabella


;Cifra 0
;Cifra 1
;Cifra 2
;Cifra 3
;Cifra 4
;Cifra 5
;Cifra 6
;Cifra 7
;Cifra 8
;Cifra 9
;Cifra
A
;Cifra b
;Cifra
C
;Cifra d
;Cifra
E
;Cifra
F

bsf
clrf
movlw
movwf
bcf

clrf
STATUS,RP0
TRISB
b'00011111'
TRISA
STATUS,RP0

PORTB
;Cancella i latch di uscita
;Seleziona banco 1
;Porta B si configura come uscita

Inizio

Loop

;Porta A si configura come entrata


;Seleziona banco 0

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
goto

0x00
Inizio

;Vettore di Reset

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
bsf
clrf
movlw
movwf
movlw
movwf
bcf

clrf
STATUS,RP0
TRISB
b'00011111'
TRISA
b'00000110'
OPTION_REG
STATUS,RP0

PORTB
;Cancella i latch di uscita
;Seleziona banco 1
;Porta B si configura come uscita
;Porta A si configura come entrata
;Prescaler di 128 per il TMR0
;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
goto Down

Up

incf

PORTB,F

;RA1 = 1
;No, conto discendente
;Conto ascendente

Down

goto

Loop

decf
goto

PORTB,F
Loop

end

;Conto discendente

;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
goto

0x00
Inizio

;Vettore di Reset

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
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw

PCL,F
b'00111111'
b'00000110'
b'01011011'
b'01001111'
b'01100110'
b'01101101'
b'01111101'
b'00000111'
b'01111111'
b'01100111'

;Spostamento sulla tabella


;Cifra 0
;Cifra 1
;Cifra 2
;Cifra 3
;Cifra 4
;Cifra 5
;Cifra 6
;Cifra 7
;Cifra 8
;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
bsf
clrf
movlw
movwf

clrf
STATUS,RP0
TRISB
b'00011111'
TRISA

PORTB
;Cancella i latch di uscita
;Seleziona banco 1
;Porta B si configura come uscita
;Porta A si configura come entrata

movlw
movwf
bcf
clrf
Loop

Wait_0

Wait_1

Up

Down

b'00000110'
OPTION_REG ;Prescaler di 128 per il TMR0
STATUS,RP0 ;Seleziona banco 0
Contatore
;Mettere a 0 del contatore

movf Contatore,W
call Tabella
;Converti BCD in 7 segmenti
movwf PORTB
;Visualizza il valore del contatore
clrwdt
;Aggiornare il WDT
btfss PORTA,0
;Aumento del segnale RA0 ?
goto Wait_0
;No
call Delay_20_ms ;Elimina rimbalzi
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
goto Down

;RA1 = 1
;No, conto discendente

incf
movlw
subwf
btfss
goto
clrf
goto

Contatore,F
.10
Contatore,W
STATUS,Z
Loop
Contatore
Loop

;Aumenta contatore

decf
movlw
subwf
btfss
goto
movlw
movwf
goto

Contatore,F
0xff
Contatore,W
STATUS,Z
Loop
0x09
Contatore
Loop

end

;E' maggiore di 9 ??
;No
;S, mettere a 0 il contatore

;Diminuisci il contatore

;E' minore di 0 ??
;No
;S, mettere a 9 il contatore

;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
W_Temp
Status_Temp equ
org
goto
org
goto

equ
equ
0x0e

0x0c
0x0d

0x00
Inizio
0x04
Interrupt

;Variabile di frequenza
;W temporale
;Registro di stato temporale
;Vettore di Reset
;Vettore di 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.:
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw

Interrupt

addwf PCL,F
;Calcola spostamento della tabella
0x00
;0 KHz
0x86
;1 KHz
0xc5
;2 KHz
0xda
;3 KHz
0xe4
;4 KHz
0xea
;5 KHz
0xee
;6 KHz
0xf1
;7 KHz

movwf W_Temp
swapf STATUS,W

;Salva il W

movwf Status_Temp ;Salva il registro di stato


movf
movwf
bcf
movlw
xorwf

Valore,W
TMR0
;Ricarica il TMR0
INTCON,T0IF ;Disattiva il flag TMR0
b'00000001'
PORTB,F
;Fai oscillare RB0

swapf
movwf
swapf
swapf

Status_Temp,W
STATUS
;Recupera il registro di stato
W_Temp,F
W_Temp,W
;Recupera il registro W

retfie
Inizio
bsf
clrf
movlw
movwf
movlw
movwf
bcf
movlw
movwf

clrf
STATUS,RP0
TRISB
b'00011111'
TRISA
b'00000001'
OPTION_REG
STATUS,RP0
b'00100000'
INTCON

PORTB
;Cancella i latch di uscita
;Seleziona banco 1
;Porta B si configura come uscita
;Porta A si configura come entrata
;Prescaler di 4 per il TMR0
;Seleziona banco 0
;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
movwf
bsf
goto
end

Tabella
Valor
INTCON,GIE
Loop

;Determina valore da caricare in TMR0


;Carica la variabile
;Interrupt ON

;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
Delay_Cont

equ

equ
0x0d

0x0c

org
goto
org

0x00
Inizio
0x05

;Numero aleatorio
;Contatore di intervalli
;Vettore di Reset
;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:

Intervallo

bcf
INTCON,T0IF
movlw 0x3c
movwf TMR0
clrwdt
btfss INTCON,T0IF

;Disconnetti il flag di overflow


;Complemento hex. de 195
;carica il TMR0
;Aggiornare il WDT
;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
bsf
clrf
movlw
movwf
movlw
movwf
bcf

clrf
STATUS,RP0
TRISB
b'00011111'
TRISA
b'00000111'
OPTION_REG
STATUS,RP0

PORTB
;Cancella i latch di uscita
;Seleziona banco 1
;Porta B si configura come uscita
;Porta A si configura come entrata
;Prescaler di 256 per il TMR0
;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
btfsc PORTA,0
goto RA0_1
movf Numero,W
movwf PORTB

movlw
movwf
call
clrf
goto
end

d'60'
Delay_Cont
Delay_var
PORTB
Loop

;Aggiorna il WDT
;Disattivato RA0 ??
;Ancora no
;E' stato prodotto un impulso in RA0, si legge
;il valore catturato del TMR0 (N aleatorio)
;e si toglie con i leds della PORTA B

;Introduci variabile di temporizzazione


;Temporizza 3 secondi
;Disconetti le uscite

;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
Delay_Cont
Temporale

equ
equ

equ
0x0d
0x0e

0x0c

org
goto
org

0x00
Inizio
0x05

;Numero aleatorio
;Contatore di intervalli
;Variabile temporale
;Vettore di Reset
;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:
retlw
retlw
retlw
retlw
retlw
retlw
retlw

addwf PCL,F
b'00111111'
b'00000110'
b'01011011'
b'01001111'
b'01100110'
b'01101101'
b'01111101'

;Spostamento sulla tabella


;Cifra 0
;Cifra 1
;Cifra 2
;Cifra 3
;Cifra 4
;Cifra 5
;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:

Intervallo

bcf
INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0x3c
;Complemento hex. de 195
movwf TMR0
;carica il TMR0
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
bsf
clrf
movlw
movwf
movlw
movwf
bcf

Loop

clrf
STATUS,RP0
TRISB
b'00011111'
TRISA
b'00000111'
OPTION_REG
STATUS,RP0

PORTB
;Cancella i latch di uscita
;Seleziona banco 1
;Porta B si configura come uscita
;Porta A si configura come entrata
;Prescaler di 256 per il TMR0
;Seleziona banco 0

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:
subwf
movwf
sublw
btfss
goto
incf

movlw d'6'
Numero,W
Numero
d'5'
STATUS,C
Dividi
Numero,F

;Sottrai 6 al numero aleatorio


;conservalo
;Guarda se minore de 5
;No
;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:
RA0_1

movlw d'6'
movwf Temporale
;Avvia il contatore del dado
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

call
movwf
movlw
movwf
call
clrf

movf Numero,W
;Riprendi l'aleatorio
Tabella
;Lo converte in 7 segmenti
PORTB
;Uscita sul Display
d'60'
Delay_Cont ;avvia variabile di temporizzazione
Delay_var
;Temporizza 3"
PORTB
;Disconnetti l'uscita

goto

Loop

Uscita:

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
goto
org

0x00
Inizio
0x05

;Vettore di Reset

bsf
clrf
movlw
movwf
movlw
movwf
bcf

clrf
STATUS,RP0
TRISB
b'00011111'
TRISA
b'00110000'
OPTION_REG
STATUS,RP0

PORTB
;Cancella i latch di uscita
;Seleziona banco 1
;Porta B si configura come uscita

Inizio

Loop
Loop1:

clrf
btfsc
goto
movf
andlw
bsf
iorwf
bcf
movf
movwf
goto
end

;Salva vettore di interrupt

;Porta A si configura come entrata


;TMR0 contatore sensibile al discendente di RA4
;Seleziona banco 0

TMR0
;Mettere a 0 il contatore
clrwdt
;Aggiorna il WDT
PORTA,3
;Controlla se I3 attivo (RESET)
Loop
;S Conto arrestato e settaggio a 0
PORTA,W
;No, leggere I2-I0 per formare il nuovo valore
b'00000111'
;del prescaler
STATUS,RP0
;Seleziona pagina 1
OPTION_REG,F
;Aggiorna il nuovo valore del prescaler
STATUS,RP0 ;Seleziona pagina 0
TMR0,W
;Leggi il valore del contatore
PORTB
;Uscita ai leds
Loop1
;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
goto
org

0x00
Inizio
0x05

;Vettore di Reset
;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

Wait

bsf
bsf
movlw
movwf
movlw
movwf
bsf
bcf
btfss
goto
bcf
bcf
return

STATUS,RP0 ;Seleziona banco 1


EECON1,WREN ;Permesso di scrittura
b'01010101'
EECON2
b'10101010'
EECON2
;Sequenza stabilita da Microchip
EECON1,WR ;Ordine di scrittura
EECON1,WREN ;Disconnetti permesso di scrittura
EECON1,EEIF ;Controllare flag di fine di scrittura
Wait
EECON1,EEIF ;Rimettere flag di fine di scrittura
STATUS,RP0 ;Selezione banco 0

;**************************************************************************************
;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
bsf
bcf
return

STATUS,RP0 ;Selezione di banco 1


EECON1,RD ;Ordine di lettura
STATUS,RP0 ;Selezione di banco 0

;**********************************************************************************
;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:
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw

addwf PCL,F
b'00111111'
b'00000110'
b'01011011'
b'01001111'
b'01100110'
b'01101101'
b'01111101'
b'00000111'
b'01111111'
b'01100111'

;Spostamento sulla tabella


;Cifra 0
;Cifra 1
;Cifra 2
;Cifra 3
;Cifra 4
;Cifra 5
;Cifra 6
;Cifra 7
;Cifra 8
;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

Ini_0
Ini_1

bsf
clrf
movlw
movwf
movlw
movwf
bcf

clrf
STATUS,RP0
TRISB
b'00011111'
TRISA
b'00000110'
OPTION_REG
STATUS,RP0

PORTB
;Cancella i latch di uscita
;Seleziona banco 1
;Porta B si configura come uscita

clrf
call
movlw
subwf
btfsc
goto
goto
clrf
goto
movf
movwf

EEADR
EE_Read
0x09
EEDATA,W
STATUS,C
Ini_0
Ini_1
Contatore
Loop
EEDATA,W
Contatore

;Seleziona indirizzo 00 di EEPROM


;Leggi byte dalla EEPROM

;Porta A si configura come entrata


;Prescaler di 128 per il TMR0
;Seleziona banco 0

;Maggiore di 9 ??
;S, mettere a 0 il contatore
;No
;Mettere a 0 il 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
movlw
subwf
btfsc
clrf
movf
movwf
call
goto
end

Contatore,F
.10
Contatore,W
STATUS,Z
Contatore
Contatore,W
EEDATA
EE_Write
Loop

;Aumenta contatore

;Contatore maggiore di 9 ??
;S, ritorno a 00

;Registra il nuovo valore del contatore nella EEPROM

;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
org
goto
org

0x00
Inizio
0x05

include
Inizio
bsf
clrf
movlw
movwf
bcf

0x0c

Loop

;Vettore di Reset
;Salva vettore di interrupt

"LCD_Cxx.inc"

clrf
STATUS,RP0
TRISB
b'00011000'
TRISA
STATUS,RP0

call LCD_INI
movlw b'00001111'
call LCD_REG
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call

;Variabili (2) delle procedure di utilizzo dell'LCD

'C'
LCD_DATO
'i'
LCD_DATO
'a'
LCD_DATO
'o'
LCD_DATO
' '
LCD_DATO

;Include le procedure di utilizzo dell'LCD

PORTB
;Cancella i latch di uscita
;Seleziona banco 1
;Porta B si configura come uscita
;RA0-RA2 uscite, RA3-RA4 entrate
;Seleziona banco 0
;Sequenza di inizio dell'LCD
;Invia istruzione: LCD ON, Cursore ON e blink ON

;Visualizza C
;Visualizza i
;Visualizza a
;Visualizza o
;Visualizza bianco

sleep
goto Loop

;Messa in Standby
;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
Delay_Cont
Temporal_1
Temporal_2

equ
equ
equ

equ
0x0e
0x0f
0x10

org
goto
org

0x00
Inizio
0x05

include

0x0c

;Variabili (2) delle procedure d'uso dell'LCD


;Variabile per la temporizzazione
;Variabile temporale
;Variabile temporale
;Vettore di Reset
;Salva vettore di interrupt

"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
'C'
'i'
'a'
'o'
0x00

;Mess_0 punta al primo carattere del messaggio 0

retlw
retlw
retlw
retlw
retlw

equ
'H'
'e'
'l'
'l'
'o'
0x00

retlw
retlw
retlw
retlw
retlw
retlw

Mess_1

;Ultimo carattere del messaggio 0


;Mess_1 punta al primo carattere del messaggio 1

;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:

Intervallo

bcf
INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0x3c
;Complemento hex. di 195
movwf TMR0
;Carica il TMR0
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
Messagg_1

No__ultimo

movwf
movf
call
movwf
movf
btfss
goto
return
call
incf
goto

Temporal_1
;Salva posizione della tabella
Temporal_1,W
;Recupera posizione della tabella
Tabella_Messaggi ;Cerca carattere di uscita
Temporal_2
;Mantieni il carattere
Temporal_2,F
STATUS,Z
;Guarda se l'ultimo
No__ultimo
LCD_DATO
Temporal_1,F
Messagg_1

;Visualizza sull'LCD
;Carattere succesivo

;**********************************************************************************
;
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
movlw b'00001100'
call LCD_REG
Loop

movlw b'00000001'
call LCD_REG

;Sequenza di inizio dell'LCD


;Invia istruzione: LCD ON, Cursore OFF e blink OFF

;Cancella LCD e Home (collocare cursore in 1

posizione)
movlw
call
movlw
movwf
call
movlw
call

Mess_0
Messagg
;Visualizza il messaggio 0
.20
Delay_Cont
Delay_var
;Temporizza 2 secondi
b'00000001'
LCD_REG
;Cancella LCD e Home (collocare cursore in 1

movlw
call
movlw
movwf
call
goto

Mess_1
Messagg
.20
Delay_Cont
Delay_var
Loop

posizione)
;Visualizza il messaggio 1

;Temporizza 2 secondi

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
Delay_Cont
Temporal_1
Temporal_2

equ
equ
equ

equ
0x0e
0x0f
0x10

org
goto
org

0x00
Inizio
0x05

include

0x0c

;Variabili (2) delle procedure di utilizzo dell'LCD


;Variabile per la temporizzazione
;Variabile temporale
;Variabile temporale
;Vettore di Reset
;Salva vettore di interrupt

"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
dt

equ
$
;Mess_0 punta al primo carattere del messaggio 0
"Microsystems",0x00

dt

equ
$
;Mess_1 punta al primo carattere del messaggio 1
"Engineering",0x00

dt

equ
$
;Mess_2 punta al primo carattere del messaggio 2
"Gral. Concha 39",0x00

dt

equ
$
;Mess_3 punta al primo carattere del messaggio 3
"48012 Bilbao",0x00

Mess_1

Mess_2

Mess_3

;*********************************************************************************
;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:

Intervallo

bcf
INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0x3c
;Complemento hex. di 195
movwf TMR0
;carica il TMR0
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
Messagg_1

No__ultimo

movwf
movf
call
movwf
movf
btfss
goto
return
call
incf
goto

Temporal_1
Temporal_1,W
Tabel_Messaggi
Temporal_2
Temporal_2,F
STATUS,Z
No__ultimo

;Salva posizione della tabella


;Recupera posizione della tabella
;Cerca carattere di uscita
;Mantieni il carattere

LCD_DATO
Temporal_1,F
Messagg_1

;Visualizza sull'LCD
;Carattere successivo

;Guarda se l'ultimo

;**********************************************************************************
;
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
movlw b'00001100'
call LCD_REG
Loop

movlw b'00000001'
call LCD_REG

;Sequenza di inizio dell'LCD


;Invia istruzione: LCD ON, Cursore OFF e blink OFF

;Cancella LCD e Home (collocare cursore in 1

posizione)
movlw
call
movlw
call
movlw
call
movlw
movwf
call
movlw
call

Mess_0
Messagg
;Visualizza il messaggio 0
b'11000101'
LCD_REG
;Colloca cursore in 2 fila dell'LCD
Mess_1
Messagg
;Visualizza messaggio 1
.40
Delay_Cont
Delay_var
;Temporizza 4 secondi
b'00000001'
LCD_REG
;Cancella LCD e Home (collocare cursore in 1

movlw
call
movlw
call
movlw

Mess_2
Messagg
b'11000010'
LCD_REG
Mess_3

posizione)
;Visualizza il messaggio 2
;Colloca cursore in 2 fila dell'LCD

call
movlw
movwf
call
goto
end

Messagg
.40
Delay_Cont
Delay_var
Loop

;Visualizza il messaggio 3

;Temporizza 4 secondi

;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
Delay_Cont equ
Temporale_1 equ
Temporale_2 equ
Cur_Pos
org
goto
org

equ
0x0e
0x0f
0x10
equ

0x0c

0x11

0x00
Inizio
0x05

include

;Variabili (2) delle procedure d'uso dell'LCD


;Variabile per la temporizzazione
;Variabile temporale
;Variabile temporale
;Posizione del cursore
;Vettore di Reset
;Salva vettore di interrupt

"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:

Intervallo

bcf
INTCON,T0IF ;Disconnetti il flag di overflow
movlw 0x3c
;Complemento hex. di 195
movwf TMR0
;carica il TMR0
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

Wait

bsf
bsf
movlw
movwf
movlw
movwf
bsf
bcf
btfss
goto
bcf
bcf
return

STATUS,RP0 ;Seleziona banco 1


EECON1,WREN ;Permesso di scrittura
b'01010101'
EECON2
b'10101010'
EECON2
;Sequenza stabilita da Microchip
EECON1,WR ;Ordine di scrittura
EECON1,WREN ;Disconnetti permesso di scrittura
EECON1,EEIF ;Testare flag di fine scrittura
Wait
EECON1,EEIF ;Rimettere flag di fine scrittura
STATUS,RP0 ;Seleziona banco 0

;**************************************************************************************
;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
bsf
bcf
return

STATUS,RP0 ;Selezione di banco 1


EECON1,RD ;Ordine di lettura
STATUS,RP0 ;Selezione di banco 0

;**********************************************************************************
;
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
clrf
Loop

btfss PORTA,4
goto Riprodurre

Programmare movlw
movwf
Program_1
btfss
goto
movf
call
movf
call
movlw
movwf
call
incf
btfss
goto
goto
Registrare

Registr_1

Riprodurre

LCD_REG
EEADR

;Invia istruzione: LCD ON, Cursore ON e blink OFF


;Indirizzo iniziale della EEPROM
;Modo programmazione ??
;No, modo di riproduzione

0x20
Temporale_1 ;Primo carattere ASCII
PORTA,3
;Registrare il byte in EEPROM ??
Registrare
;S
Cur_Pos,W
LCD_REG
;Colloca il cursore
Temporale_1,W
LCD_DATO
;Visualizza il carattere
.10
Delay_Cont
Delay_var
;Temporizza 0.5 secondi
Temporale_1,F
;Seguente carattere ASCII
Temporale_1,7
;E' l'ultimo carattere ASCII ??
Program_1
;No
Programmare ;S, iniziare dal primo

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
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
movlw
call
movlw
call
clrf

Riprodurre_0
call
movf
btfsc
goto
movf
call
incf
goto

b'00000001'
LCD_REG
;Cancella LCD e Home
b'00001100'
LCD_REG
;LCD = ON, cursore = OFF
EEADR
;Indirizzo iniziale EEPROM
clrwdt
;Aggiornamento del WDT
EE_Read
;Leggi carattere della EEPROM
EEDATA,F
STATUS,Z
;E' l'ultimo del messaggio ?? (0x00)
Riprodurre_1
;S
EEDATA,W
LCD_DATO
;Visualizza il carattere
EEADR,F
;Seguente carattere
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
Contatore_L
Contatore_H
Temporale_1
Temporale_2

equ
equ
equ
equ

equ
0x0e
0x0f
0x10
0x11

org
goto
org

0x00
Inizio
0x05

include

0x0c

;Variabili (2) per procedure d'uso dell'LCD


;Variabile per il contatore parte bassa
;Variabile per il contatore parte alta
;Variabile temporale
;Variabile temporale
;Vettore di Reset
;Salva vettore di interrupt

"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

Wait

bsf
bsf
movlw
movwf
movlw
movwf
bsf
bcf
btfss
goto
bcf
bcf
return

STATUS,RP0 ;Seleziona banco 1


EECON1,WREN ;Permesso di scrittura
b'01010101'
EECON2
b'10101010'
EECON2
;Sequenza stabilita da Microchip
EECON1,WR ;Ordine di scrittura
EECON1,WREN ;Disconnetti permesso di scrittura
EECON1,EEIF ;Testare flag di fine scrittura
Wait
EECON1,EEIF ;Rimettere flag di fine scrittura
STATUS,RP0 ;Selezione banco 0

;**************************************************************************************
;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
bsf
bcf
return

STATUS,RP0 ;Selezione di banco 1


EECON1,RD ;Ordine di lettura
STATUS,RP0 ;Selezione di banco 0

;**********************************************************************************
;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
$
"Suo TURNO : ",0x00

dt

;Mess_0 punta al primo carattere

;*********************************************************************************
;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
Messagg_1

movwf
movf
call
movwf
movf
btfss
goto
return
call
incf
goto

No__ultimo

Inizio

Temporale_1
Temporale_1,W
Tabella_Mess
Temporale_2
Temporale_2,F
STATUS,Z
No__ultimo

;Salva posizione della tabella


;Recupera posizione della tabella
;Cerca carattere di uscita
;Conserva il carattere

LCD_DATO
Temporale_1,F
Messagg_1

;Visualizza sull'LCD
;Seguente carattere

bsf
clrf
movlw
movwf
movlw
movwf
bcf

clrf
STATUS,RP0
TRISB
b'00011000'
TRISA
b'00000110'
OPTION_REG
STATUS,RP0

call

LCD_INI

;Guarda se l'ultimo

PORTB
;Cancella i latch di uscita
;Seleziona banco 1
;Porta B si configura come uscita
;RA0-RA2 entrate, resto entrate
;Prescaler di 128 per il TMR0
;Seleziona banco 0
;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
call
movlw
subwf
btfsc
goto
goto
clrf
clrf
goto

EEADR
EE_Read
0x09
EEDATA,W
STATUS,C
Ini_0
Ini_1
Contatore_L
Contatore_H
Loop

movf
movwf
incf
call
movlw
subwf
btfsc
goto
movf
movwf

EEDATA,W
Contatore_H
EEADR,F
EE_Read
0x09
EEDATA,W
STATUS,C
Ini_0
EEDATA,W
Contatore_L

Loop

movlw
call
movf
iorlw
call
movf
iorlw
call

0x8d
LCD_REG
;Posiziona il cursore dell'LCD
Contatore_H,W
0x30
;Converti in ASCII Contatore_H
LCD_DATO
;Visualizza Contatore_H
Contatore_L,W
0x30
;Converti in ASCII Contatore_L
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

Ini_0

Ini_1

incf
movlw
subwf
btfss
goto
clrf
incf
movlw
subwf
btfss
goto
clrf
Write

;Seleziona indirizzo 00 di EEPROM


;Leggi byte della EEPROM

;Contatore_H maggiore di 9 ??
;S, mettere a 0 il contatore
;No
;Mettere a 0 il contatore

;Aggiorna Contatore_H
;Seguente posizione della EEPROM
;Leggi il byte della EEPROM

;Contatore_L maggiore di 9 ??
;S, mettere a 0 il contatore
;Aggiorna Contatore_L

Contatore_L,F
;Aumenta contatore_L
.10
Contatore_L,W
STATUS,Z
;Contatore maggiore di 9 ??
Write
;No, aggiornare EEPROM
Contatore_L ;Si, Contatore_L passa a 0
Contatore_H,F
;Aumenta Contatore_H
.10
Contatore_H,W
STATUS,Z
;Contatore_H maggiore di 9
Write
;No, aggiornare EEPROM
Contatore_H ;Si, Contatore_H passa a 0

clrf EEADR
;Seleziona indirizzo 00 della EEPROM
movf Contatore_H,W
movwf EEDATA

call
incf
movf
movwf
call
goto
end

EE_Write
;Registra Contatore_H nella EEPROM
EEADR,F
;Indirizzo 01 della EEPROM
Contatore_L,W
EEDATA
EE_Write
;Registra Contatore_L nella EEPROM
Loop
;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
goto
org

0x00
Inizio
0x05

;Vettore di Reset

bsf
clrf
movlw
movwf
movlw
movwf
bcf

clrf
STATUS,RP0
TRISB
b'00011111'
TRISA
b'00001000'
OPTION_REG
STATUS,RP0

PORTB
;Cancella i latch di uscita
;Seleziona banco 1
;Porta B si configura come uscita

Inizio

Loop

sleep
incf
movf
andlw
iorlw
bsf
movwf
bcf
goto
end

;Salva vettore di interrupt

;RA0-RA4 entrate
;Prescaler di 1 per el WDT
;Seleziona banco 0

;Modo Standby
PORTB,F
PORTA,W
b'00000111'
b'00001000'
STATUS,RP0
OPTION_REG
STATUS,RP0
Loop

;Aumenta il contatore binario sulla porta B


;Leggi lo stato degli interruttori RA0-RA2
;Seleziona banco
;Registra valore
;Seleziona banco
;Tornare al modo

1
del prescaler
1
Standby

;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
goto

0x00
Inizio

;Vettore di Reset

org

0x05

;Salva il vettore di interrupt

bsf
clrf
movlw
movwf
bcf

clrf
STATUS,RP1
TRISB
b'00011111'
TRISA
STATUS,RP1

PORTB
;Cancella i latch di uscita
;Seleziona banco 1
;Porta B si configura come uscita

Inizio

Loop

RA0_es_1

clrwdt
btfsc PORTA,0
goto RA0_es_1
bcf
PORTB,0
bsf
PORTB,1
goto Loop
bsf
bcf
goto
end

PORTB,0
PORTB,1
Loop

;Porta A si configura come entrata


;Seleziona banco 0
;Aggiorna il WDT timer
;RA0 = 1 ??
;S
;No, disconnetti RB0
;Connetti RB1
;Loop senza fine
;Attiva RB0
;Attiva RB1
;Loop senza fine
;Fine del programma principale

S-ar putea să vă placă și