Architettura interna dei PIC16F84AData di pubblicazione: 17-10-2003 | Versione Italiana | (No English Version) Parole chiave: - PIC - |
Dopo aver fatto un p� di pratica nella lezione precedente,
passiamo ora alla teoria. Iniziamo a vedere com'� fatto internamente un PICmicro,
quali dispositivi contiene e come interagiscono tra loro.
Nella figura seguente viene riprodotto lo schema a blocchi
semplificato dell'architettura interna del PIC16F84A che ci
aiuter� a seguire meglio quanto verr� spiegato di seguito. Le parti
evidenziate in giallo, sono le componenti che di volta in volta andremo ad
analizzare.
Iniziamo dalla memoria programma o PROGRAM MEMORY
e dalla memoria dati o REGISTER FILE.

La Program Memory
La PROGRAM MEMORY � una memoria speciale di tipo FLASH, non
cancellabile elettricamente, ed utilizzata nel PICmicro per tenere memorizzato
il programma da eseguire.
La sua capacit� di memorizzazione � di 1024
locazioni ognuna in grado di contenere un opcode
a 14 bit ovvero una istruzione base del PICmicro. Il programma pi�
complesso che potremo realizzare non potr� essere quindi pi� lungo di 1024
istruzioni.
Gli indirizzi riservati alla PROGRAM MEMORY vanno da 0x000
a 0x3FF (0x3FF esadecimale = 1023 decimale).
Il PICmicro pu� solamente eseguire le istruzioni memorizzate
in queste locazioni. Non pu� in alcun modo leggere, scrivere o cancellare
quanto in esse contenuto. Questo vale in particolar modo per i PIC16F84A mentre
su altri modelli quali i PIC16F87x � possibile anche aggiornare la
memoria programma a run time ovvero a programma in esecuzione.
Per scrivere, leggere e cancellare queste locazioni �
necessario un dispositivo esterno denominato programmatore. Un
esempio di programmatore � l' il o PICSTART prodotto dalla Microchip o molti
altri ancora disponibili in commercio.
La prima locazione di memoria, all'indirizzo zero, deve
contenere la prima istruzione che il PICmicro dovr� eseguire al reset
e per questo viene nominata Reset Vector.
Come ricorderete, nel source LED.ASM
presentato nella lezione precedente era stata inserita la direttiva:
ORG 0x00
per segnare l'inizio del programma. Questa direttiva tiene
conto del fatto che l'esecuzione del programma al reset parte dall'indirizzo
0x000 dell'area programma.
L'istruzione che segue immediatamente la direttiva ORG 0x00:
bsf STATUS,RP0
sar� quindi la prima istruzione ad essere eseguita.
Il Register File
Il REGISTER FILE � un'insieme di locazioni
di memoria RAM
ovvero memorie con cui � possibile leggere e modificare il contenuto senza
l'ausilio di programmatori esterni e direttamente dal programma in esecuzione
sul PICmicro.
Date le sue caratteristiche il REGISTER FILE � la memoria
normalmente utilizzata per memorizzare le variabili di programma, ovvero tutti
quei valori il cui contenuto varia durante l'esecuzione.
Contrariamente alla PROGRAM MEMORY il REGISTER FILE perde il
suo contenuto quando il PICmicro viene spento per cui � necessario
reinizializzare i valori di tutte le sue locazioni prima di poterla usare.
Alcune locazioni del REGISTER FILE ed in particolare quelle
che si trovano agli indirizzi pi� bassi vengono usate per il controllo
dell'hardware del PICmicro secondo quanto illustrato di seguito.
Le locazioni di memoria presenti nel
REGISTER FILE sono indirizzabili direttamente in uno spazio di memoria
che va da 0x00 a 0x2F per un totale di
48 byte, denominato pagina 0. Un secondo spazio
di indirizzamento denominato pagina 1 va da 0x80
a 0xAF. Per accedere a questo secondo spazio �
necessario ricorrere ai due bit ausiliari RP0 e RP1
secondo le modalit� che andremo a spiegare pi� avanti.
Le prime 12 locazioni della pagina 0
(da 0x00 a 0x0B) e della pagina 1 (da 0x80
a 0x8B) sono quelle riservate alle funzioni speciali
per il funzionamento del PICmicro e non possono essere utilizzate per
altri scopi.
Le 36 locazioni in pagina 0
indirizzate da 0x0C a 0x2F possono essere
utilizzate liberamente dai nostri programmi per memorizzare variabili,
contatori, ecc.
Nel nostro esempio LED.ASM
la direttiva:
ORG 0x0C
indica proprio l'indirizzo di inizio dell'area dati
utilizzabile dal nostro programma.
La direttiva che segue:
Count RES 2
riserva uno spazio di due locazioni, che il programma
utilizzer� per memorizzare i contatori di ritardo della subroutine
Delay.
|
 |
I registri specializzati del PIC vengono utilizzati molto di
frequente nei programmi.
Ad esempio, si ricorre alla coppia di registri specializzati TRISA
(0x85) e TRISB (0x86), per definire quali linee di I/O sono in
ingresso e quali in uscita. Lo stesso stato logico delle linee di I/O dipende
dal valore dei due registri PORTA (0x05) e PORTB
(0x06).
Alcuni registri riportano lo stato di funzionamento dei
dispositivi interni al PICmicro o il risultato di operazioni aritmetiche e
logiche.
E' necessario conoscere esattamente quale funzione svolge
ciascun registro specializzato e quali effetti si ottengono nel manipolarne il
contenuto.
Per facilitare le operazioni sui registri specializzati, nel
file P16F84.INC
(che come ricorderete era stato incluso nel source LED.ASM
con la direttiva INCLUDE) la Microchip ha inserito una lista di
nomi che identificano univocamente ciascun registro specializzato e a cui sono
associati gli indirizzi corrispondenti nell'area dei REGISTER FILE.
Se, ad esempio, volessimo definire tutte le linee della porta
B del PIC in uscita agendo sul registro TRISB, potremmo
scegliere di referenziare direttamente il registro con il suo indirizzo:
movlw B'00000000'
movwf 0x86
oppure, referenziare lo stesso registro con il suo nome
simbolico:
movlw B'00000000'
movwf TRISB
avendo per� l'accortezza di inserire la direttiva INCLUDE
"P16F84.INC" nel nostro source.
La ALU

La ALU (acronimo di Arithmetic
and Logic Unit ovvero unit� aritmetica e
logica) � la componente pi� complessa del PICmicro in quanto contiene tutta la
circuiteria delegata a svolgere le funzioni di calcolo e manipolazione dei dati
durante l'esecuzione di un programma.
La ALU � una componente presente in tutti i
microprocessori e da essa dipende direttamente la potenza di calcolo del micro
stesso.
La ALU del PIC16F84A � in
grado di operare su valori ad 8 bit, ovvero valori numerici non
pi� grandi di 255. Esistono microprocessori con ALU a 16, 32, 64 bit e oltre.
La famiglia Intel� 80386�, 486� e Pentium� ad esempio dispone di una ALU a
32 bit. Le potenze di calcolo raggiunte da questi micro sono notevolmente
superiori a scapito della complessit� della circuiteria interna ed accessoria e
conseguentemente dello spazio occupato.
L'Accumulatore o registro W
Direttamente connesso con la ALU c'� il registro W
denominato anche accumulatore. Questo registro consiste di una
semplice locazione di memoria in grado di contenere un solo valore a 8 bit.
La differenza sostanziale tra il registro W e le altre
locazioni di memoria consiste proprio nel fatto che, per referenziare ill
registro W, la ALU non deve fornire nessun indirizzo di memoria, ma pu�
accedere direttamente.
Il registro W viene utilizzato molto spesso nei programmi per PICmicro.
Facciamo un esempio pratico. Supponiamo di voler inserire
nella locazione di memoria 0xC del REGISTER FILE
il valore 0x01. Cercando tra le istruzioni del PICmicro ci
accorgiamo subito che non esiste un'unica istruzione in grado di effettuare
questa operazione ma dobbiamo necessariamente ricorrere all'accumulatore ed
usare due istruzioni in sequenza.
Vediamo perch�:
Come detto nei passi precedenti, l'opcode di una istruzione
non pu� essere pi� grande di 14 bit mentre a noi ne
servirebbero:
8 bit per specificare il valore che
intendiamo inserire nella locazione di memoria,
7 bit per specificare in quale locazione di memoria vogliamo
inserire il nostro valore,
6 bit per spcificare quale istruzione intendiamo utilizzare.
per un totale di 8 + 7 + 6 = 21 bit.
Dobbiamo quindi ricorrere a due istruzioni, ovvero:
movlw 0x01
movwf 0x0C
che prima inseriscono nel registro W il
valore 0x01H con l'istruzione MOVe Literal
to W e poi lo "muovono" nella locazione 0x0C con
l'istruzione MOVe W to F.
Il Program Counter (PC)

Come abbiamo gi� visto nei passi precedenti, il PIC16F84A
inizia l'esecuzione del programma a partire dal vettore di reset (Reset
Vector) ovvero dall'istruzione memorizzata nella prima locazione di
memoria (indirizzo 0x000).
Dopo aver eseguito questa prima istruzione passa quindi
all'istruzione successiva memorizzata nella locazione 0x001 e cos� via. Se non
esistesse nessuna istruzione in grado di influenzare in qualche modo
l'esecuzione del programma, il PICmicro arriverebbe presto ad eseguire tutte le
istruzione presenti nella sua memoria fino all'ultima locazione disponibile.
Sappiamo ovviamente che non � cos� e che qualsiasi
microprocessore o linguaggio di programmazione dispone di istruzioni di salto,
ovvero di istruzioni in grado di modificare il flusso di esecuzione del
programma in base alle esigenze del programmatore.
Una di queste istruzioni � la GOTO
(dall'inglese GO TO, vai a) che ci permette di cambiare la
sequenza di esecuzione e di "saltare" direttamente ad un qualsiasi
punto, all'interno della memoria programma, e di continuare quindi
l'esecuzione a partire da quel punto.
Facciamo un esempio:
ORG 0x00
Point1
movlw 10
goto Point1
Al reset il PICmicro eseguir� l'istruzione MOVLW
10 memorizzata alla locazione 0x000, la quale inserir� nell'accumulatore il
valore decimale 10, quindi passer� ad eseguire l'istruzione successiva GOTO
Point1. Questa istruzione determiner� un salto incondizionato alla locazione di
memoria puntata dalla label Point1 ovvero di nuovo alla locazione 0x000. Nel suo
insieme quindi, questo programma non far� altro che eseguire continuamente le
due istruzioni elencate.
Durante questo ciclo (o loop), per determinare quale sar�
l'istruzione successiva da eseguire, il PIC utilizza uno speciale registro
denominato PROGRAM COUNTER (dall'inglese contatore di
programma) la cui funzione � proprio quella di mantenere traccia dell'indirizzo
che contiene la prossima istruzione da eseguire.
Questo registro viene incrementato automaticamente ad ogni
istruzione eseguita per determinare il passaggio all'istruzione successiva. Al
momento del RESET
del PIC il PROGRAM COUNTER viene azzerato, determinando cos� l'inizio
dell'esecuzione a partire dall'indirizzo 0x000.
L'istruzione GOTO consente l'inserimento a programma di un
nuovo valore nel PROGRAM COUNTER ed il di conseguente salto ad una locazione
qualsiasi dell'area programma del PIC.
Lo Stack Pointer
Un'altra istruzione molto utile, che influenza il valore del
PROGRAM COUNTER � la CALL (dall'inglese chiamata) con la quale
� possibile effettuare delle CHIAMATE A SUBROUTINE.
Questa istruzione funziona in maniera molto simile alla GOTO.
Come la GOTO infatti permette di scrivere nel PROGRAM COUNTER un nuovo indirizzo
di esecuzione del programma. La differenza sostanziale consiste per� nel fatto
che prima di eseguire il salto,. il PIC memorizza, in un altro registro
speciale, denominato STACK, l'indirizzo di quella che sarebbe
dovuta essere la successiva istruzione da eseguire se non si fosse
incontrata la CALL.
Vediamo meglio con un esempio:
ORG 0x00
Point1
movlw 10
call Point2
goto Point1
Point2
movlw 11
return
In questo caso il PICmicro, dopo aver eseguito la MOVLW 10
passa ad eseguire listruzione CALL Point2. Prima di saltare per�, memorizza
nello STACK l'indirizzo 0x002, ovvero l'indirizzo della locazione successiva
alla CALL. L'esecuzione passa quindi all'istruzione MOVLW 11 e quindi alla
istruzione RETURN (dall'inglese ritorno). Questa istruzione, come dice il suo
nome, consente di "ritornare", ovvero di riprendere l'esecuzione a
partire dall'istruzione successiva alla CALL che aveva determinato l'abbandono
del flusso principale del programma utilizzando il valore memorizzato nel
registro di STACK.
Come detto l'operazione appena effettuata viene denominata
CHIAMATA A SUBROUTINE, ovvero una interruzione momentanea del normale
flusso di programma per "chiamare" in esecuzione una serie di
istruzioni per poi ritornare al normale flusso di esecuzione.
La parola STACK in inglese significa "catasta"
ed infatti su questa catasta � possibile depositare, uno sull'altro, pi�
indirizzi per recuperarli quando servono. Questo tipo di memorizzazione viene
anche denominata LIFO dall'inglese Last In
First Out, in cui l'ultimo elemento inserito (last
in) deve necessariamente essere il primo ad uscire (last out). Grazie a questa
caratteristica � possibile effettuare pi� CALL annidate ovvero l'una
nell'altra e mantenere sempre traccia del punto in cui riprendere il flusso al
momento che si incontra una istruzione RETURN.
Vediamo un altro esempio:
ORG 0x00
Point1
movlw 10
call Point2
goto Point1
Point2
movlw 11
call Point3
return
Point3
movlw 12
return
In questo caso nella subroutine Point2 viene effettuata
un'ulteriore CALL alla subroutine Point3. Al ritorno da quest'ultima il
programma dovr� rientrare nella subroutine Point2 eseguire la RETURN e quindi
tornare nel flusso principale.
Gli indirizzi da memorizzare nello stack sono due in quanto
viene incontrata una seconda CALL prima ancora di incontrare la RETURN
corrispondente alla prima.
Il PIC16F84A dispone di uno stack a 8 livelli, ovvero uno
stack che consente fino ad 8 chiamate annidate..
E' importante assicurasi, durante la stesura di un programma,
che ci sia sempre una istruzione RETURN per ogni CALL per evitare pericolosi
disallineamenti dello stack che in esecuzione possono dar adito a errori
difficilmente rilevabili.
Realizziamo le "luci in sequenza"
Proviamo ora a fissare i concetti finora appresi rielaborando il
source LED.ASM
presentato nella prima lezione per realizzare un lampeggiatore sequenziale a
quattro led. Il nuovo source modificato si chiamer� SEQ.ASM.
Nella figura seguente viene riportato lo schema elettrico del nuovo
circuito, sostanzialmente equivalente al circuito presentato nella prima
lezione, con l'unica variante che ora i led collegati sono quattro anzich� uno.

Le linee di I/O utilizzate sono RB0
per primo led, RB1
per il secondo, RB2
per il terzo ed RB3
per il quarto. Esse vanno quindi configurate tutte in uscita all'inizio del
programma cambianto le istruzioni:
movlw B'11111110'
movwf TRISB
in
movlw B'11110000'
movwf TRISB
in cui i quattro bit meno significativi, corrispondenti alle
linee RB0,1,2,3 vengono messi a zero per definire tali linee in uscita.
Nell'area di memoria del REGISTER FILE (che nel source inizia
con la direttiva ORG 0x0C)
oltre ai due byte referenziati dalla label Count, riserviamo un ulteriore byte
con label Shift che utilizzeremo per determinare la sequenza di accensione dei
led. La direttiva da inserire �:
Shift RES 1
Prima di eseguire il ciclo principale (label MainLoop)
inizializiamo il nuovo registro Shift a 00000001B con le seguenti istruzioni
istruzioni:
movlw B'00000001'
movwf Shift
A questo punto, nel ciclo principale del
nostro programma, ci occuperemo di trasferire il valore memorizzato nel registro
Shift sulla Porta B ottenendo quindi l'accensione del primo led,
con le seguenti istruzioni:
movf Shift,W
movwf PORTB
quindi di effettuare lo shift a sinistra del
valore contenuto in Shift di un bit, con le seguenti istruzioni:
bcf STATUS,C
rlf Shift,F
la prima istruzione serve ad azzerare il bit
CARRY del registro di stato STATUS che verr� analizzato nelle lezioni
successive. L'istruzione RLF Rotate Left F
through Carry (ruota a sinistra attraverso il bit di carry) sposta di un bit
verso sinistra il valore memorizzato nel registro Shift inserendo nella
posizione occupata dal bit 0 il valore del bit di Carry (che come gi� detto
andremo a vedere in seguito). Per far si che il bit inserito sia sempre zero
viene eseguita prima della RLF l'istruzione BCF STATUS,C per azzerare questo
bit.
A questo punto il registro Shift varr�
00000010, quindi, al ciclo successivo, una volta trasferito tale valore sulla
port B si otterr� lo spegnimento del LED1 e l'accensione del LED2 e cos� via
per i cicli successivi.
Quando il bit 4 di Shift varr� 1, vorr� dire
che tutti e quattro i led sono stati accesi almeno una volta e occorre quindi
ripartire dal led 1. Le istruzioni seguenti svolgono questo tipo di controllo:
btfsc Shift,4
swapf Shift,F
L'istruzione BTFSC Shift,4 controlla appunto
se il bit 4 del registro Shift vale 1. Se si esegue l'istruzione successiva
SWAPF Shift,F altrimenti la salta.
L'istruzione SWAP (dall'inglese
"scambia") in pratica scambia i quattro bit pi� significativi
contenuti nel registro Shift con i quattro meno significativi. Dal valore
iniziale del registro Shift pari a 00010000 ottenuto dopo alcune ripetizioni del
ciclo MainLoop si ottiene il valore 00000001 ed in pratica alla riaccensione del
primo led.
Segnala questo articolo:
Parole chiave: - PIC -
|