Area SX srl - Informatica e Microelettronica
0
Torna a: Home Page Soluzioni Microcontrollori PIC Architettura interna dei PIC16F84A

Architettura interna dei PIC16F84A

Data di pubblicazione: 17-10-2003 | Versione Italiana  | (No English Version)The English version of this article does not exists
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 -

Data di pubblicazione: 17-10-2003Hits: 47853
I marchi citati sono proprietà dei titolari dei relativi diritti. Le caratteristiche tecniche e i prezzi riportati sono indicativi e soggetti a variazioni senza preavviso. Le foto non hanno valore contrattuale. Nonostante accurate verifiche, il presente documento può contenere prezzi o specifiche errati. Area SX si scusa in anticipo e si impegna ad evitare tali imprecisioni.

 Area SX store
In questa sezione puoi ordinare direttamente i prodotti descritti in questo articolo
ICD2.PICDEM2;PICSTART+;P16F628A
Tutti i prezzi indicati sono espressi in Euro con IVA e spese di trasporto escluse. I prezzi si riferiscono al singolo pezzo
DescrizioneCodicePrezzo

Rivenditori Social Contatti Condizioni
Area SX s.r.l
Via Stefano Longanesi 25
00146 Roma

Tel: +39.06.99.33.02.57
Fax: +39.06.62.20.27.85
P.IVA 06491151004
Condizioni di vendita
Procedura di rientro in garanzia
Condizioni per i rivenditori