; ESEMPIO 1 - UniBg

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

Transcript of ; ESEMPIO 1 - UniBg

Page 1: ; ESEMPIO 1 - UniBg

;

; 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

Page 2: ; ESEMPIO 1 - UniBg

;

; 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

Page 3: ; ESEMPIO 1 - UniBg

;

; 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

Page 4: ; ESEMPIO 1 - UniBg

;

; 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

Page 5: ; ESEMPIO 1 - UniBg

;

; 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

Page 6: ; ESEMPIO 1 - UniBg

;

; 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

Page 7: ; ESEMPIO 1 - UniBg

;

; 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

Page 8: ; ESEMPIO 1 - UniBg

;

; 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

Page 9: ; ESEMPIO 1 - UniBg

;

; 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

Page 10: ; ESEMPIO 1 - UniBg

;

; 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

Page 11: ; ESEMPIO 1 - UniBg

;

; 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

Page 12: ; ESEMPIO 1 - UniBg

;

; 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

Page 13: ; ESEMPIO 1 - UniBg

;

; 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

Page 14: ; ESEMPIO 1 - UniBg

goto Loop

Down decf PORTB,F ;Conto discendente

goto Loop

end ;Fine del programma principale

Page 15: ; ESEMPIO 1 - UniBg

;

; 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

Page 16: ; ESEMPIO 1 - UniBg

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

Page 17: ; ESEMPIO 1 - UniBg

;

; 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

Page 18: ; ESEMPIO 1 - UniBg

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

Page 19: ; ESEMPIO 1 - UniBg

;

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

Page 20: ; ESEMPIO 1 - UniBg

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

Page 21: ; ESEMPIO 1 - UniBg

;

; 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

Page 22: ; ESEMPIO 1 - UniBg

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

Page 23: ; ESEMPIO 1 - UniBg

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

Page 24: ; ESEMPIO 1 - UniBg

;

; 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

Page 25: ; ESEMPIO 1 - UniBg
Page 26: ; ESEMPIO 1 - UniBg

;

; 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

Page 27: ; ESEMPIO 1 - UniBg

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

Page 28: ; ESEMPIO 1 - UniBg

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

Page 29: ; ESEMPIO 1 - UniBg

;

; 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

Page 30: ; ESEMPIO 1 - UniBg

;

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

Page 31: ; ESEMPIO 1 - UniBg

;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

Page 32: ; ESEMPIO 1 - UniBg

end ;Fine del programma principale

Page 33: ; ESEMPIO 1 - UniBg

;

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

Page 34: ; ESEMPIO 1 - UniBg

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

Page 35: ; ESEMPIO 1 - UniBg

call Messagg ;Visualizza il messaggio 3

movlw .40

movwf Delay_Cont

call Delay_var ;Temporizza 4 secondi

goto Loop

end ;Fine del programma principale

Page 36: ; ESEMPIO 1 - UniBg

;

; 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

Page 37: ; ESEMPIO 1 - UniBg

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

Page 38: ; ESEMPIO 1 - UniBg

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

Page 39: ; ESEMPIO 1 - UniBg

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

Page 40: ; ESEMPIO 1 - UniBg

;

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

Page 41: ; ESEMPIO 1 - UniBg

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

Page 42: ; ESEMPIO 1 - UniBg

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

Page 43: ; ESEMPIO 1 - UniBg

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

Page 44: ; ESEMPIO 1 - UniBg

;

; 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

Page 45: ; ESEMPIO 1 - UniBg

;

; 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