2012/2013
26013 CREMA giancarlo.livraga@istruzione.it
IL MICROCONTROLLORE PIC16F690
NOTA: questo fascicolo vuole solo essere un manualetto di rapida consultazione durante la scrittura ed il debugging di programmi per il
PIC16F690 sotto la guida di un docente o per chi, in qualche misura, abbia conoscenze precedenti su microprocessori e periferiche.
Il PIC12F690 è un microcontrollore RISC a 8bit con architettura HARVARD (area programmi separata
dall‟area dati), ed è una sostanziale espansione dei suoi fratelli più piccoli come il PIC12F675. Di questi ha le
medesime prestazioni generali (istruzioni, frequenza di clock etc.) ma un maggior numero di linee di I/O e
alcune potenti funzioni hardware in più.
La figura a lato mostra il layout dell‟integrato dove
sono utilizzati nomi multipli sui pin per indicare le
diverse funzioni che ciascuno di essi può svolgere.
NOTA: In questa dispensa, salvo errori o dimenticanze, si
useranno solo i nomi associati ai port (RA, RB e RC) an-
che se i pin sono configurati per altre funzioni.
Elenco dei registri dell‟area RAM (per nome, descrizione e indirizzo RAM)
NOTA: il valore dell’indirizzo specifica solo i 7 bit bassi dell’indirizzo effettivo (9bit), i restanti due bit definiscono il banco RAM
e sono forniti dai bit STATUS,RP<1,0>. Alcuni registri sono indifferentemente accessibili da più banchi RAM.
registri del PIC16F690 banco RAM
(nelle colonne a lato è indicato esplicitamente solo il primo indirizzo –quello del banco RAM più basso. indirizzo 0 1 2 3
Le x segnano le ulteriori posizioni nelle quali il registro è raggiungibile)
INDF (usato per indirizzamento indiretto, non è un registro reale) 00h x x x x
TMR0 (timer 0) registro contatore a 8 bit 01h x x
OPTION_REG controlla TMR0, WPU e GP2 interrupt 81h x x
PCL contatore di programma, parte bassa 02h x x x x
STATUS flag vari e controlla banco RAM attivo 03h x x x x
FSR indice per l’indirizzamento indiretto 04h x x x x
PORTA 6 bit di I/O chiamati RA<5:0> equivalente al registro GPIO del PIC12F675 05h x x
TRISA 6 bit corrispondenti a PORTA per definire il verso dei pin in/out come TRISIO 85h x x
WPUA 5 bit corrispondenti a PORTA per definire se attivare le singole Resistenze di pull-up 95h x
IOCA 6 bit corrispondenti a PORTA per abilitare o meno interrupt su cambiamento di stato 96h x
PORTB 4 bit di I/O chiamati RB<7:4> 06h x x
TRISB 4 bit corrispondenti a PORTB per definire il verso dei pin in/out 86h x x
WPUB 4 bit corrispondenti a PORTB per definire se attivare le singole Resistenze di pull-up 115h x
IOCB 4 bit corrispondenti a PORTB per abilitare o meno interrupt su cambiamento di stato 116h x
PORTC 8 bit di I/O chiamati RC<7:0> 07h x x
TRISC 8 bit corrispondenti a PORTC PORTB per definire il verso dei pin in/out 87h x x
PCLATH Il program counter ha 13 bit e le istruzioni che hanno PCL come destinazione (ad esempio ADDWF PCL,d) 0AH x x x x
forniscono solo 8 bit di indirizzo –parte bassa- ; i restanti 5 bit –parte alta- sono forniti da PCLATH<4:0>.
Le istruzioni GOTO e CALL utilizzano un op.code ridotto e forniscono 11 bit di indirizzamenti –parte bassa-;
i restanti 2 bit sono forniti da PCLATH<4:3>.
INTCON Abilitazioni varie di interrupt e alcuni flag (flag= bit di segnalazione) 0Bh x x x x
PIR1 Insieme di flag vari 0Ch x
PIR2 Insieme di flag vari 0Dh x
PIE1 Insieme di bit di abilitazione interrupt 8Ch x
PIE2 Insieme di bit di abilitazione interrupt 8Dh x
EEDAT port dati da e verso EEROM 10Ch x
EECON1 18Ch x
EEADR 10Dh x
EECON2 18Dh x
EEDATH 10Eh x
EEADRH 10Fh x
EEADRH 10Fh x
T1CON 10Fh x
TMR1L 8 bit bassi (dei 16 totali) del contatore/timer 1 0Eh x
TMR1H 8 bit alti (dei 16 totali) del contatore/timer 1 0Fh x
PCON 8Eh x
OSCCON 8Fh x
OSCTUNE 90h x
TMR2 8 bit del contatore/timer 2 11h x
T2CON 12h x
PR2 registro RW costantemente comparato con il valore del timer 2. La condizione di uguaglianza, postscalata dal 92h x
rapporto definito in T2CON setta il flag TMR2IF che, se abilitato, genera una richiesta di interrupt.
CCPR1L registro RW utilizzato per catturare il valore del timer1 in modo CAPTURE o per contenere gli 8 bit più significativi 15h x
(di 10) da utilizzare per determinare il duty cycle in modo PWM
CCPR1H registro RW utilizzato per catturare il valore del timer1 in modo CAPTURE o per caricare gli 8 bit da CCPR1L che 16h x
verranno poi comparati con il valore di TMR2 per determinare il duty cycle in modo PWM
CCP1CON 17h x
PWM1CON 1Ch x
PSTRCON 19Dh x
ECCPAS 1Dh x
CM1CON0 119h x
CM2CON0 11Ah x
CM2CON1 11Bh x
SRCON 19Eh x
VRCON 118h x
ANSEL 11Eh x
ANSELH 11Fh x
ADCON0 1Fh x
ADCON1 9Fh x
T1CON
ADRESH Risultato della conversione AD –parte alta- 1Eh x
ADRESL Risultato della conversione AD –parte bassa- 9Eh x
Il bit<7> (d) specifica la destinazione del risultato dell’operazione (d=0 il risultato è nell’accumulatore W, d=1 il risultato è nel registro
indirizzato).
I 9 bit necessari a coprire lo spazio indirizzabile della RAM (da 000h…1FFh) sono costruiti automaticamente
unendo i bit RP1,RP0 del registro di STATUS con i 7 bit per l‟indirizzamento disponibili nelle istruzioni.
L‟area RAM appare quindi divisa in quattro banchi (convenzionalmente banco 0, 1, 2 e 3) corrispondenti allo
stato di questi due bit. Nella scrittura di un programma si deve quindi fare attenzione e tenere traccia del
banco attivo commutando RP0,RP1 quando necessario.
NOTA: nella maggior parte degli assemblatori si può usare la direttiva
banksel <registro|0|1|2|3>
per generare automaticamente le due istruzioni che settano correttamente i bit RP1 e RP0 del registro di STATUS.
Nella tabella che segue sono riportate le istruzioni del PIC con le seguenti convenzioni
destinazione del risultato (0=accumulatore, 1=registro).
f indirizzo del registro (o nome simbolico se dichiarato) d Vale 0 per default (se non esplicitamente scritta)
k costante numerica, label b posizione del bit nel registro (7…0)
La colonna dello Status flag mostra quali bit del registro di STATUS siano influenzati dalla istruzione.
OPERAZIONI SUI BYTE
Codice mne-
Status flag commento
monico
CLRF f Z (clear file: azzera il registro f)
CLRW Z (clear w: azzera l‟accumulatore)
MOVF f,d Z (mov f: il contenuto di f è ricopiato in d)
MOVWF f (mov w f: il contenuto dell‟accumulatore è ricopiato in f)
ADDWF f,d C, DC, Z (add w f: somma algebrica W+f) d
SUBWF f,d C, DC, Z (sub w f: sottrazione algebrica f-W) d
ANDWF f,d Z (and w f: funzione AND bit con bit tra W ed f) d
IORWF f,d Z (inclusive or w f: funzione OR bit con bit tra W ed f) d
XORWF f,d Z (xor w f: funzione XOR bit a bit tra W ed f) d
COMF f,d Z (complement f: complementa tutti I bit di f) d
DECF f,d Z (decrement f: decrementa f) d
DECFSZ f,d (decrement f skip zero: decrementa f, scavalca prossima istruzione se risultato =0) d
INCF f,d Z (increment f: incrementa f) d
INCFSZ f,d (increment f skip zero: incrementa f, scavalca prossima istruzione se risultato =0) d
RLF f,d C (rotate left: rotazione sinistra di f attraverso il carry) d
RRF f,d C (rotate right: rotazione destra di f attraverso il carry) d
SWAPF f,d (swap file: scambia tra loro i 4 bit bassi/alti di f) d
OPERAZIONI SUI BIT
Codice mnemonico commento
BCF f,b (Bit clear file: azzera il bit specificato)
BSF f,b (Bit set file: porta allo stato 1 il bit specificato)
BTFSS f,b (bit test file skip set: se il bit specificato vale 1 salta la prossima istruzione)
BTFSC f,b (bit test file skip clear: se il bit specificato vale zero salta la prossima istruzione)
I registri TRISC, WPUC replicano le medesime funzioni dei corrispondenti registri del portA con la unica dif-
ferenza del loro indirizzo, dell‟adattamento dei loro nomi, della posizione e del nome dei singoli bit.
Manca invece il corrispondente registro IOC_ di abilitazione dell‟interrupt sui singoli bit.
T2CON (19H) controllo del timer T2
7
6 TOUTPS3 selezione rapporto di postscaler 0000 = 1:1
5 TOUTPS2 0001 = 1:2
RW …
4 TOUTPS1
1111 = 1:16
3 TOUTPS0
2 TMR2ON RW 1= timer2 on 0= timer2 off
1 T2CKPS1 selezione rapporto prescaler
RW 00 = 1:1 01 = 4 1x = 16
0 T2CKPS1
Il registro PR2 è un normale registro RW che è continuamente comparato con il valore corrente del timer 2.
La condizione di uguaglianza, postscalata con il rapporto definito da T2CON setta il flag TMR2IF che, se abi-
litato, può generare interrupt.
IL MODULO ECCP (Enanched Capture Compare PWM)
Il modulo ECCP, con i suoi tre modi di funzionamento con i suoi tre modi di funzionamento, è estremamente flessibile e può liberare la
programmazione da molto lavoro aumentando le prestazioni del microcontrollore.
modo CAPTURE. Il valore di TIMER1 viene catturato nel registro
CCPR1H in conseguenza di un fronte (edge) di salita o di discesa sul pin
RC5. La disponibilità di un prescaler programmabile permette di attivare la
cattura del timer ogni 1, 4 o 16 fronti sul pin RC5. La cattura è accompa-
gnata dal set del flag CCP1IF (nel registro PIR1). Ogni valore catturato
sovrascrive il contenuto dei registri CCPR1H/L ed il flag CCP1IF se abili-
tato può generare interrupt.
Con 10 bit di risoluzione il quanto di conversione è Vref/1023 mentre trascurando i due bit meno significativi il quanto è Vref/255.
Utilizzando Vref=Vdd (5V classici) si ottengono sensibilità dell’ordine di ~5mV e ~20mV rispettivamente. Per avere maggiore sensi-
bilità (ma minore portata) si può utilizzare una tensione di riferimento esterna al pin GP1 configurando il bit ADVON0,VCFG.
Portare contemporaneamente allo stato 1 i due bit ADON e GO (accensione modulo e start contemporaneamente) porta ad un erro-
re nella conversione: usare due istruzioni separate: prima accendere il modulo e successivamente iniziare una conversione.
**************** IL SEGUITO riprende i contenuti della dispensa sul PIC12F675 – IN ATTESA DI REVISIONE***********************
EEROM
Il PIC dispone di 128 byte EEPROM (electrically erasable programmable read-only memory) con indirizzi lo-
cali <00…7Fhche vengono usati per salvare dati volatili necessari alla successiva riaccensione. Le opera-
zioni di scrittura/lettura scrittura sono gestite dai seguenti registri:
EEDAT contiene i dati (8 bit lettura/scrittura) da trasferire tra RAM EEPROM
EEDATH contiene i dati (6 bit lettura/scrittura) da trasferire tra
RAM EEPROM sequenza di scrittura
EEADR contiene l‟indirizzo (8 bit) EEPROM sul quale fare il trasferimento su EEPROM
…
EEADRH contiene l‟indirizzo (4 bit) EEPROM sul quale fare il trasferimento bsf EECON1,WREN
EECON1 registro di controllo: bcf INTCON,GIE
bit movlw 0x55h
7 1= accede RAM programma, movwf 0=accede RAM SFR
EECON2
6, 5, 4 non usati movlw 0xAAh
3 WRERR (flag di scrittura) 1=scrittura abortita, 0=scrittura completata movwf EECON2
2 WREN (enable bit): 1=abilita cicli di scrittura, 0=disabilita bsf EECON1,WR
1 WR (se bit 7=0): 1=inizia scrittura, azzeramento automatico a fine scrittura
0 RD (read control): 1=inizia lettura, azzeramento automatico a fine lettura
Per leggere un dato dalla EEPROM si deve mettere l‟indirizzo in EEADR e settare EECON1,RD := 1. Il dato
sarà in EEDATA nel ciclo macchina successivo.
Per scrivere un dato nella EEPROM, dopo avere caricato il dato in EEDATA e l‟indirizo in EEADR si deve
obbligatoriamente seguire la sequenza a fianco (il registro EECON2 non è un registro reale):
quenzialmente
alle locazioni
RAM a partire
dalla locazione
nnn. Nel caso
del PIC12F675
la RAM dispo-
nibile comincia
alla locazione
0x20h
endc termina
la lista iniziata
con cblock
Equ Dichiarazione di equivalenza, ad esempio GPIO EQU 5. Con questa dichiarazione è pos-
sibile utilizzare il nome GPIO al posto del numero 5. In questo caso la istruzione
MOVWF GPIO verrà interpretata come MOVWF 5 risultando più comprensibile.
Altro esempio: banco0 equ BCF STATUS,RP0. Posto che STATUS ed RP0 sono stati
precedentemente definiti con una loro equ con questa dichiarazione, ogni volta che si
vuole commutare su banco0 si potrà utilizzare il nome simbolico banco0 al posto della
istruzione completa.
Org nnn Fissa il Program Counter al valore nnn specificato. Nel caso del PIC12F675 si devono
specificare la origine org 0x00 che è il vettore di reset (l‟indirizzo che viene raggiunto in
seguito ad un reset o ad una accensione) ed org 0x04 che è il vettore di interrupt
(l‟indirizzo che viene raggiunto a seguito di una richiesta di interruzione da parte di una
periferica abilitata). Quindi l‟inizio del codice di programma per un PIC12F675 di solito è:
org 0x00 goto STAR
org 0X04 goto INTE
START: qui inizia i
… …
ESEMPI DI PROGRAMMAZIONE
NOTA: In un file sorgente che deve essere assemblato ogni andata a capo fatta con il tasto INVIO definisce
una nuova riga ed ogni riga può contenere solo uno statement. Gli esempio sviluppati sono formattati per
comodità di lettura ed il testo viene “wrappato” automaticamente con un rientro quando arriva sul bordo pa-
gina: questa forma grafica non è disponibile nell‟ambiente di sviluppo MPLAB.
ESEMPIO 1: comparatore
GP2 = 1 quando la tensione su GP0 sale sopra quella di GP1, GP5 è il negato di GP2.
- #include<p12F675.inc>;il file P12F675.inc contiene una serie di dichiarazioni EQU che permettono di utilizzare i nomi simbolici dei registri e dei bit.
- __config 0x3194 ;il PIC è configurato per: oscillatore interno, GP<5,4,3> liberi per I/O, MCLR interno, altre opzioni disabilitate
- #define bank0 bcf STATUS,RP0 ;Assegna il nome simbolico bank0 alla istruzione che commuta su RAM banco 0
- #define bank1 bsf STATUS,RP0 ;Assegna il nome simbolico ban1 alla istruzione che commuta su RAM banco 1
- ;**************AREA PROGRAMMA semplice riga di commento per marcare le varie zone del programma
- org 0x00 ;Program counter:=00. All‟atto della accensione o dopo un reset il PIC comincia sempre dalla posizione 0x00, quindi il programm
- goto start ;…e qui trova un salto necessario per scavalcare la posizione 0x04…
- org 0x04 ;Il PIC esegue la istruzione alla posizione 0x04 in risposta ad una richiesta di interruzione…
- retfie ;…ed in que
- ;**************PROLOGO DI CONFIGURAZIONE
- start: ;è una label (etichetta). Assegna un nome simbolico a questa posizione di programma
- bank1 ;Attiva RAM banco1 (la scritta bank1 sarà sostituita dalla corrispondente direttiva EQU)
- clrf ANSEL ;Azzera il registro ANSEL (nessun pin connesso all‟AD converter)
- movlw b'00000011' ;Carica un dato binario nell‟accumulatore…
- movwf TRISIO ;…e lo trasferisce a TRISIO (configura GP<1..0> come input e gli altri come output)
- bsf PIE1,CMIE ;il bit indirizzato viene posto ad 1 (abilita localmente l‟interrupt dal comparatore)
- bank0 ;seleziona banco 0 (istruzione definita prima con una EQU)
- movlw b'00000001' ;Carica dato binario nell‟accumulatore…
- movwf CMCON ;…e lo trasferisce a CMCON (configura modo 001, uscita non invertita)
- clrf INTCON;Azzera il registro INTCON (e quindi non ammette alcun interrupt, nemmeno quello del ;comparatore che è stato localme
- ;**************TERMINE PROLOGO DI CONFIGURAZIONE, INIZIO PROGRAMMA
- loop:
- btfsc CMCON,COUT ;(bit test file skip clear) scavalca la prossima istruzione se il bit CMCON,COUT vale zero
- goto V_high ;Salta alla label V_high
- V_low: ;label
- bsf GPIO,5 ;forza allo stato 1 il bit 5 del registro GPIO
- goto loop ;Salta alla label loop
- V_high: ;label
- bcf GPIO,5 ;forza allo stato 0 il bit 5 del registro GPIO
- goto loop ;salta alla label loop
- end ;fine del programma. Tutto quello che fosse scritto dopo la direttiva end sarà ignorato
In questo esempio il comparatore è stato configurato in modo 001. Dalla tabella del registro CMCON si vede
che in questa configurazione il comparatore utilizza tutti i pin a disposizione e la sua uscita COUT è connes-
sa a GP2. Il programma, dopo avere definito una configurazione minima (solo i registri ed i bit strettamente
interessati al problema) si limita ad un loop che testa il bit interno CMCON,COUT (e non lo stato di GP2 che
potrebbe essere alterato da una errata condizione di carico) per forzare GP5 al suo complemento. I due loop
tratteggiati si diramano alla riga 23 che scavalca la riga successiva se il bit indirizzato (CMCON,COUT) vale
zero.
ESEMPIO 2: comparatore
L’esempio precedente utilizza una procedura di POLLING per testare ciclicamente lo stato del sistema (in
questo caso solo lo stato del comparatore). Un simile approccio non è certamente il massimo della efficienza
per due motivi: il cambiamento di stato non viene rilevato sino a che il programma non passa per le istruzioni
che fanno il test e le istruzioni di test vengono ripetute continuamente anche se lo stato non cambia. La mo-
dalità di INTERRUPT invece è molto più efficace: le istruzioni di test e le conseguenze stanno scritte in una
subroutine che, sotto condizione di abilitazione, viene chiamata automaticamente dall’evento associato (in
questo caso dal cambiamento di stato del comparatore). Si propone quindi una variante del programma pre-
cedente utilizzando una procedura di INTERRUPT (ed anche u cambio di configurazione del comparatore).
GP5=1se V(GP0)>2V.
La variante proposta lascia inalterate le prime 10 righe dell’esercizio precedente che non vengono riscritte.
- ….
- org 0x00
- goto start
- org 0x04 ;Entrata da richiesta di interrupt…
- goto interrupt ;…e dirottamento alla subroutine di servizio interrupt
- start:
- bank1 ;Seleziona banco1
- clrf ANSEL ;Nessun pin per AD converter
- movlw b'00000011' ;
- movwf TRISIO ;GP0 e GP1 input (e GP3 input di suo), gli altri output
- bsf PIE1,CMIE ;Abilita interrupt da cambiamento di stato del comparatore
- movlw b’10000101’ ;Accende generatore di tensione di riferimento, uscita alto range…
- movwf VRCON ;…ed imposta per Vref=VDD(1/4+5/32)=2.03V (con VDD=5V)
- bank0 ;Seleziona banco 0
- movlw b'00011110' ;Modo 110 (vedi registro CMCON) CIS=1 (connette GP0)…
- movwf CMCON ;…CINV=1 (inversione dei segni)
- bsf INTCON,PEIE ;Abilita interrupt da gruppo periferiche (vedi PIE1)
- bsf INTCON,GIE ;Abilita interrupt globale (vedi INTCON)
- goto $ ;Loop di attesa
- interrupt:
- bcf INTCON,GIE ;GIE=0 automaticamente in risposta ad interrupt, per ora lasciata a promemoria.
- bcf PIR1,CMIF ;Azzera il flag che ha segnalato il cambiamento di stato del comparatore
- btfss CMCON,COUT ;Scavalca la prossima istruzione se la uscita del comparatore vale uno…
- goto low ;…oppure salta a “low” se vale zero.
- high:
- bsf GPIO,GP5 ;Qui se la uscita del comparatore vale uno, allora GP5 = 1
- retfie ;Riabilita (globale) interrupt e torna al punto nel quale era stato interrotto
- low:
- bcf GPIO,GP5 ;Qui se la uscita del comparatore era bassa, allora GP5=0
- retfie ;
- end ;fine del programma. Tutto quello che fosse scritto dopo la direttiva end sarà ignorato
Come spiegato in apertura questo secondo esempio, avendo a disposizione un “evento” che segnala la ne-
cessità di una operazione utilizza la modalità di “interrupt” per la gestione del sistema. Il programma è libero
di fare altre cose (anche se nell‟esempio resta fermo sul “goto $” ) e, se opportunamente abilitato, verrà in-
terrotto dall‟evento (in questo caso il cambio dello stato della uscita del comparatore).
Possono esserci più eventi abilitati a chiedere un interupt al programma: in questo caso, poiché il PIC ha so-
lo una entrata di interrupt, la subroutine di servizio dovrà effettuare una procedura di polling esplorando i flag
delle periferiche abilitate per determinare quale (o quali) abbiano chiesto interrupt per poi svolgere le opera-
zioni previste.
Il PIC rende disponibili in RAM gli 8 bit parte bassa del program counter (registro PCL, indirizzo 0x02 dupli-
cato anche in banco1 a 0x82)e la istruzione RETLW K che è una istruzione di ritorno da subroutine con la
costante K nell‟accumulatore. Il combinato di queste prestazioni rende possibile la implementazione di ta-
belle mediante la realizzazione di quello che il manuale chiama “goto computato” e che corrisponde al clas-
sico salto relativo cioè ad un salto di “n” posizioni in avanti (o anche indietro).
L‟esempio seguente usa il “goto computato” per implementare la tabella di verità della conversione da codice
gray a 4 bit a codice binario a fianco riportata.
NOTA 1: questa procedura è equivalente a risolvere le funzioni logiche indipendenti ABCD della tabella di verità e quindi è di uso gene-
rale.
NOTA 2: la variabile tableLenght può essere usata sia per controllare che il dato non origini un salto fuori dalla
tabella (e conseguente crash del programma) sia per gestire un loop che volesse leggere tutta la tabella. GRAY ... binario
NOTA 3: la effettiva tabella (da tableStart: a tableEnd) può anche essere messa in un file esterno ed inserita ....... A B C D
in questa posizione con una direttiva include<>) rendendo il codice più pulito. 0000 ... 0 0 0 0
0001 ... 0 0 0 1
- … 0011 ... 0 0 1 0
- org 0x00 0010 ... 0 0 1 1
- goto start 0110 ... 0 1 0 0
- org 0x04 0111 ... 0 1 0 1
- retfie 0101 ... 0 1 1 0
- TABLE: ;il codice gray è contenuto nell’accumulatore W in forma 0000xxxx 0100 ... 0 1 1 1
- addwf PCL,F;il contenuto dell’accumulatore è sommato alla parte bassa del program counter così1100
generando
... 1 0un0 salto
0 in avanti pari al c
- tableStart: 1101 ...;accumulatore
1001 valore di rito
- retlw b’00000000’ 1111 ... 1 0 1 ;0000
0 00
- retlw b’00000001’ 1110 ... 1 0 1 ;0001
1 00
- retlw b’00000011’ 1010 ... 1 1 0 ;0010
0 00
- retlw b’00000010’ 1011 ... 1 1 0 ;0011
1 00
- retlw b’00000111’ 1001 ... 1 1 1 ;0100
0 01
- …. ;avanti a1000
riempire
...tutte
1 1 1le 1righe
- retlw b’00001010’ ;1111 10
- tableEnd:
- tableLenght = (tableEnd-tableStart-1) ;lunghezza della tabella
- start:
- … ;tutto quello che si vuole
- … ;posto che nell’accumulatore ci sia il codice da trasformare nella forma 0000xxxx
- call TABLE ;
- … ;di ritorno da TABLE l’accumulatore contiene il valore associato al codice
- …
- end
NOTA IMPORTANTISSIMA: il salto realizzato con la istruzione “addwf PCL,F” non genera riporto del carry
agli 8 bit parte alta del program counter per cui è obbligatorio che la tabella sia contenuta in una pagina della
memoria di programma. Per intenderci: la dimensione massima della tabella è di 255 byte ammesso che la
istruzione di salto sia nella posizione xx00 (già nell’esempio la istruzione di salto è all’indirizzo xx05 e la massima dimensione
della tabella è di 255-5=250 byte)
1. G
P3 e GP0 siano configurat1 come input e tutti gli altri pin siano configurati come output
2. I
l comparatore sia nello stato OFF (modalità 111)
3. La routine di interrupt generi ciclicamente la sequenza
GP< 5 4 2 1> GP5
1 0 0 0 GP4
0 1 0 0 GP2
0 0 1 0 GP1
0 0 0 1
1 0 0 0 ;ripete da capo
…
cblock 0x20
contatore ;il registro contatore verrà usato ler leggere la tabella
endc
…
org 0x00
goto start
org 0x04
goto interupt
TABLE: ;
addwf PCL,F ;
tableStart: ;
retlw b’00100000’ ;
retlw b’00010000’ ;
retlw b’00000100’ ;
retlw b’00000010’ ;
tableEnd:
tableLenght = (tableEnd-tableStart) ;lunghezza della tabella
start:
…
movlw b’00001001’
movwf TRISIO ;GP3 e GP0 come input, altro come output
…
movlw b’00000111’
movwf CMCON ;Comparatore spento
…
clrf contatore ;prepara pulito
decf contatore ;anticipa di un incremento
…
…
interrupt:
bcf INTCON,GIE
bcf INTCON,T0IE
movlw tableLen
subwf contatore
btfss STATUS,C
goto ripristina