PICmicro. PICMICRO cult

Introduzione ai PICmicro

Cosa sono i PICMICRO, realizziamo un semplice lampeggiatore a led, scrittura e compilazione di un programma in assembler

I PICmicro sono dei circuiti integrati prodotti dalla Microchip Technology Inc., che appartengono alla categoria dei microcontroller, ovvero quei componenti che integrano in un unico dispositivo tutti i circuiti necessari a realizzare un completo sistema digitale programmabile.
Come si può vedere in figura,

i PICmicro (in questo caso un PIC16F84A) si presentano esternamente come dei normali circuiti integrati TTL o CMOS, ma internamente dispongono di tutti dispositivi tipici di un sistema a microprocessore, ovvero:


  • Una CPU (Central Processor Unit) ovvero una unita' centrale di elaborazione il cui scopo e' interpretare le istruzioni di programma.
  • Una memoria FLASH in cui sono memorizzare in maniera permanente le istruzioni del programma da eseguire.
  • Una memoria RAM (Random Access Memory) utilizzata per memorizzare le variabili utilizzate dal programma.
  • Una serie di LINEE DI I/O (Input/Output) ovvero linee di ingresso e uscita per pilotare dispositivi esterni o ricevere impulsi da sensori, pulsanti, ecc.
  • Una serie di dispositivi ausiliari al funzionamento quali generatori di clock, bus, contatori, ecc.

La presenza di tutti questi dispositivi in uno spazio estremamente contenuto, consente al progettista di avvalersi degli enormi vantaggi derivanti dall'uso di un sistema a microprocessore, anche in quei circuiti che fino a poco tempo fa erano destinati ad essere realizzati con circuiterie tradizionali.
I PICmicrosono disponibili in un'ampia gamma di modelli per meglio adattarsi alle esigenze di progetto specifiche, differenziandosi per numero di linee di I/O e per dotazione di dispositivi. Si parte dai modelli più piccoli identificati dalla sigla PIC12C5xx dotati di soli 8 pin, fino ad arrivare ai modelli più grandi con sigla PIC18Cxx dotati di 40 e più pin.

Una descrizione dettagliata delle tipologie di PICmicro è disponibile presso il sito web della Microchip raggiungibile via internet, che consiglio senz'altro di esplorare per la grande quantita' di informazioni tecniche, software di supporto, esempi di applicazioni e aggiornamenti disponibili.
Per questo corso ho scelto un modello intermedio di PICmicro il PIC16F84A.

Il PIC16F84A è dotato di 18 pin di cui ben 13 disponibili per l'I/O ovvero per i collegamenti al resto del nostro circuito e di alcune caratteristiche che lo rendono maggiormente adatto alle esigenze del nostro corso.
In particolare il PIC16F84A dispone di una memoria per contenere il programma di tipo FLASH che può essere riscritta quante volte vogliamo e quindi ideale per i nostri esperimenti.
Nella figura seguente vengono riportati i pin di cui dispone il PIC16F84A.


Come e' possibile vedere i pin sono disposti su due file parallele da 9 pin ciascuna. I pin contrassegnati in BLU rappresentano le linee di I/O disponibili per le nostre applicazioni, i pin in ROSSO e NERO sono i pin di alimentazione, i pin in VERDE sono riservati al funzionamento del PICmicro (MCLR per il reset e OSC1-2 per il clock).
Passiamo immediatamente al nostro primo esempio pratico.

Realizziamo un semplice lampeggiatore a LED

Realizziamo un circuito molto semplice il cui scopo è quello di far lampeggiare un diodo led. Vedremo come si scrive un programma in assembler, come si compila e come si trasferisce all'interno della FLASH del PICmicro per lanciarlo in esecuzione.

Il circuito da realizzare e' riportato nel seguente figura seguente:

Per alimentare il circuito è necessario fornire una tensione stabilizzata di 5 volt in continua che possiamo ottenere da un piccolo alimentatore da laboratorio oppure da un qualsiasi alimentatore autocostruito scelto tra i tanti presentati sulle varie riviste di elettronica.
La tensione di alimentazione di 5 volt viene inviata ai pin Vdd (pin 14) e Vss (pin 5) collegati rispettivamente al positivo ed alla massa.
Il pin MCLR (pin 4) serve per poter effettuare il reset del PICmicro. Normalmente viene mantenuto a 5 volt tramite la resistenza di pull up R1 e messo a zero quando si desidera resettare il PICmicro. Grazie alla circuiteria interna di reset di cui il PICmicro è dotato, non è necessario collegare al pin MCLR pulsanti o circuiti RC per ottenere il reset all'accensione.
I pin OSC1/CLKIN (pin 16) e OSC2/CLKOUT (pin 15) sono collegati internamente al circuito per la generazione della frequenza di clock utilizzata per temporizzare tutti i cicli di funzionamento interni al chip. Da questa frequenza dipende la quasi totalità delle operazioni interne ed in particolare la velocità con cui il PICmicro esegue le istruzioni del programma.
Nel caso del PIC16F84A-04/P tale frequenza può raggiungere un massimo di 4Mhz (anche se in realtà è pratica comune spingere tale frequenza a valori molto superiori, operazione chiamata overclocking) da cui si ottiene una velocità di esecuzione delle istruzioni pari a 1 MIPS. Nel nostro caso per la generazione del clock viene utilizzato un quarzo esterno da 4 MHz e due condensatori da 15 o 22pF.
Il pin RB0 (pin 6) è una delle linee di I/O disponibili sul PICmicro per i nostri scopi. In questo caso questa linea è stata collegata ad un led tramite una resistenza di limitazione.

Scrittura e compilazione di un programma assembler

Come per qualsiasi sistema a microprocessore, anche per il PICmicro è necessario preparare un programma per farlo funzionare.

Un programma e' costituito da una sequenza di istruzioni, ognuna delle quali identifica univocamente una funzione che il PICmicro deve svolgere. Ogni istruzione è rappresentata da un codice operativo (in inglese operation code o più brevemente opcode) composto da 14 bit ed è memorizzata in una locazione di memoria dell'area programma. Tale memoria nel PIC16F84A e' di tipo FLASH e dispone di 1024 locazioni ognuna delle quali e' in grado di contenere una sola istruzione oppure una coppia istruzione/dato.
Un esempio di opcode in notazione binaria viene riportato di seguito:

00 0001 0000 0000

ma e' più probabile che un opcode venga rappresentato in notazione esadecimale ovvero:

0x100

che rappresenta esattamente lo stesso valore ma in forma più breve. La 0x davanti al valore indica che si tratta di una notazione esadecimale. Lo stesso valore può essere rappresentato in assembler con la notazione H'0100'.
Questi codici, completamente privi di senso per un essere umano, sono gli unici che il PICmicro è in grado di capire. Per fortuna esistono alcuni strumenti che consentono di facilitare il compito al programmatore rendendo le istruzioni più comprensibili.
Per convenzione si associa, ad ogni opcode, una breve sigla detta mnemonica, ovvero una sigla che aiuti a ricordare la funzione svolta da ogni istruzione.

L'opcode 0x100 dell'esempio precedente, effettua l'azzeramento del registro W (accumulatore - vedremo meglio di seguito) che in inglese viene indicato con la frase CLEAR W REGISTER, ovvero "AZZERA IL REGISTRO W" che nella forma abbreviata diventa CLRW.
Altre sigle mnemoniche consentono di definire tutte le istruzioni che il PICmicro è in grado di eseguire ma anche variabili, costanti ed etichette (label). L'insieme di queste sigle e le regole per ordinarle per formare un programma completo viene chiamato LINGUAGGIO ASSEMBLER.

Per scrivere un programma in linguaggio assembler occorre conoscere le istruzioni disponibili sul micro che si intende usare (in questo caso il PICmicro), le regole sintattiche per definire variabili, parametri, ecc e disporre di un editor di testo con cui digitare il nostro programma.
Il file di testo così ottenuto, viene denominato source o sorgente assembler.
Il passo successivo consiste nel tradurre il nostro sorgente assembler nella giusta sequenza di istruzioni in formato binario che il PICmicro è in grado di capire. Questo tipo di programma si chiama compilatore assembler o assemblatore.
Nella figura seguente viene schematizzato il flusso di operazioni ed i file generati necessari per ottenere un PICmicro programmato.

Come già detto, la prima operazione da effettuare è la scrittura del source assembler e la sua memorizzazione in un file di testo. L'estensione di questo file deve essere .ASM.
Possiamo usare allo scopo un semplice editor ASCII quale, ad esempio NOTEPAD di Windows anche se e' vivamente consigliabile un edit ascii pensato appositamente per sviluppare sorgenti. Un ottimo programma da utilizzare sotto windows e' Ultraedit32.
E' possibile generare questo file anche con programmi di elaborazione testi più sofisticati quali Word o Star Office avendo pero l'accortezza di memorizzare sempre il file prodotto in formato testo e non in formato nativo (i .DOC tanto per intenderci). Questo per evitare che vengano memorizzati anche i caratteri di controllo della formattazione del testo che il compilatore assembler non e' in grado di trattare.
Nel nostro primo esperimento pratico utilizzeremo il file LED.ASM.
Il passo successivo e' la compilazione del source, ovvero la trasformazione in opcode dei codici mnemonici o istruzioni assembler in esso contenute.
Il compilatore assembler che utilizzeremo e' l'MPASM.EXE prodotto dalla Microchip.
Come e' possibile vedere nella figura precedente, oltre al nostro source con estensione .ASM e' necessario fornire al compilatore un secondo file prodotto dalla Microchip con estensione .INC, differente a seconda del tipo di PICmicro che stiamo utilizzando. Nel nostro caso il file e' il P16F84A.INC. Questo source contiene alcune definizioni dipendenti dal chip utilizzato che vedremo più avanti.
Durante la compilazione, l'assemblatore genera una serie di file con il nome identico al source da cui derivano, ma con estensione diversa. Vediamo quali sono e cosa contengono:


  • .HEX è il file contenete gli opcode da inserire nella memoria programma del PICmicro.
  • .LST è un file di testo in cui viene riportato l'intero source assembler e la corrispondente traduzione in opcode. Non e' utilizzabile per la programmazione del PICmicro ma è estremamente utile per verificare i processi di compilazione che ha eseguito l'assemblatore.
  • .ERR contiene la lista degli errori di compilazione riscontrati ed il numero di linea all'interno del source assembler in cui sono stati rilevati.

I file .LST e .ERR vengono utilizzati per il controllo di quanto effettuato in compilazione. Solo il file .HEX viene utilizzato realmente per programmare il PICmicro.

Il file .HEX non e' un file in formato binario ma un file codificato in un formato inventato dalla Intel per la descrizione dei file binari in formato ASCII. Senza entrare troppo nei dettagli è utile sapere che tale formato è direttamente riconoscibile da qualsiasi programmatore di PICmicro il quale provvederà a leggere da questo formato gli opcode ed a trasferirli nella memoria del PICmicro.

Analizziamo un Source assembler

Analizziamo ora linea per linea il contenuto del nostro source LED.ASM

Per chi dispone di una stampante è utile effettuare una stampa del source per poter meglio seguire la nostra descrizione. Altrimenti è preferibile visualizzare il source in una finestra separata in modo da seguire simultaneamente il source e la relativa spiegazione.

Partiamo dalla prima linea di codice:

PROCESSOR	16F84

PROCESSOR è una direttiva del compilatore assembler che consente di definire per quale microprocessore è stato scritto il nostro source. Le direttive non sono delle istruzioni mnemoniche che il compilatore traduce nel rispettivo opcode, ma delle semplici indicazioni rivolte al compilatore per determinarne il funzionamento durante la compilazione. In questo caso informiamo il compilatore che le istruzioni che abbiamo inserito nel nostro source sono relative ad un PIC16F84.

RADIX		DEC

La direttiva RADIX serve ad informare il compilatore che i numeri riportati senza notazione, sono da intendersi come numeri decimali. Ovvero se intendiamo specificare, ad esempio il numero esadecimale 10 (16 decimale) non possiamo scrivere solamente 10 perché verrebbe interpretato come 10 decimale, ma 0x10 oppure H'10'.

ERRORLEVEL -302

La direttiva ERRORLEVEL serve ad escludere la segnalazione di alcuni errori di compilazione. Nel nostro caso viene utilizzata per evitare che il compilatore ci segnali questi due errori:

Message[302] C:\EPIC\LED.ASM 37 : 
Register in operand not in bank 0.
Ensure that bank bits are correct.

Message[302] C:\EPIC\LED.ASM 40 : 
Register in operand not in bank 0.
Ensure that bank bits are correct.

I quali ci avvertono che alla linea 37 e 40 del nostro sorgente vengono usati dei registri che non
si trovano sul banco 1 e ci ricordano di commutare banco. Vedremo in seguito il significato reale di questi errori. Per ora limitiamoci a filtrarli.

INCLUDE "P16F84A.INC"

Ancora un'altra direttiva per dire al compilatore la nostra intenzione di includere nel source un secondo file denominato P16F84A.INC. Il compilatore si limiterà a sostituire la linea contenente la direttiva INCLUDE con il contenuto del file indicato e ad effettuare quindi la compilazione come se fosse anch'esso parte del nostro source.

LED	EQU	0   

Ancora direttive ! Ma quando arrivano le istruzioni ? Ancora un po di pazienza :-).

La direttiva EQU e' molto importante in quanto ci consente di definire delle costanti simboliche all'interno del nostro source. In particolare la parola LED da questo punto in poi del source sarà equivalente al valore 0. Lo scopo principale dell'esistenza della direttiva EQU è quindi rendere i source più leggibili e consentire di cambiare i valori costanti in un unico punto del source.
E' importante notare che la parola LED non identifica una variabile ma semplicemente un nome simbolico valido durante la compilazione. Non sarà quindi possibile inserire instruzioni tipo LED = 3 all'interno del source in quanto l'assegnazione dinamica di un valore ad una variabile è un'operazione che richiede l'intervento della CPU del PICmicro e che quindi deve essere espressa con istruzioni e non con direttive.

Le direttive hanno senso solo durante la compilazione del source quindi un PICmicro non potrà mai eseguire una direttiva.

Vediamo ora la linea seguente:

ORG 0x0C 

Anche ORG è una direttiva e ci consente di definire l'indirizzo da cui vogliamo che il compilatore inizi ad allocare i dati o le istruzioni seguenti. In questo caso stiamo per definire un'area dati all'interno del PICmicro ovvero un'area in cui memorizzare variabili e contatori durante l'esecuzione del nostro programma. Quest'area coincide con l'area RAM del PICmicro definita dalla Microchip come area dei FILE REGISTER.
I file register altro non sono che locazioni RAM disponibili per l'utente a partire dall'indirizzo 0x0C. Questo indirizzo di inizio è fisso e non può essere cambiato in quanto le locazioni precedenti sono occupate da altri registri specializzati per uso interno.

Count	RES 2   

In questa linea incontriamo una label: Count e una direttiva: RES.
La direttiva RES indica al compilatore che intendiamo riservare un certo numero di byte o meglio di file register all'interno dell'area dati; in questo caso 2 byte. La label Count, dove Count è un nome scelto da noi, è un marcatore che nel resto del source assumerà il valore dell'indirizzo in cui e' stato inserito. Dato che precedentemente avevamo definito l'indirizzo di partenza a 0x0C con la direttiva ORG, Count varrà 0x0C. Se ad esempio inseriamo una label anche alla linea successiva essa varrà 0x0C + 2 (due sono i byte che abbiamo riservato) ovvero 0x0E. I nomi delle label possono essere qualsiasi ad eccezione delle parole riservate al compilatore quali sono le istruzioni mnemoniche e le direttive).
Una label si distingue da una costante simbolica perché il suo valore viene calcolato in fase di compilazione e non assegnato da noi staticamente.

ORG  0x00 

Questa seconda direttiva ORG fa riferimento ad un indirizzo in area programma (nella FLASH) anziché in area dati. Da questo punto in poi andremo infatti ad inserire le istruzioni mnemoniche che il compilatore dovrà convertire negli opportuni opcode per il PICmicro.
Il primo opcode eseguito dal PICmicro dopo il reset è quello memorizzato nella locazione 0, da qui il valore 0x00 inserito nella ORG.

bsf    STATUS,RP0 

Ecco finalmente la prima istruzione mnemonica completa di parametri. I PICmicro hanno una CPU interna di tipo RISC per cui ogni istruzione occupa una sola locazione di memoria, opcode e parametri inclusi. In questo caso l'istruzione mnemonica bsf sta per BIT SET FILE REGISTER ovvero metti a uno (condizione logica alta) uno dei bit contenuti nella locazione di ram specificata.
Il parametro STATUS viene definito nel file P16F84A.INC tramite una direttiva EQU. Il valore assegnato in questo file è 0x03 e corrisponde ad un file register (ovvero una locazione ram nell'area dati) riservato.
Anche il parametro RP0 viene definito nel file P16F84.INC con valore 0x05H e corrisponde al numero del bit che si vuole mettere a uno. Ogni file register è lungo 8 bit e la numerazione di ciascuno parte da 0 (bit meno significativo) fino ad arrivare a 7 (bit più significativo)
Questa istruzione in pratica mette a 1 il quinto bit del file register STATUS. Questa operazione è necessaria, come vedremo nelle lezioni successive, per accedere ai file register TRISA e TRISB come vedremo ora.

movlw     B'00011111' 

Questa istruzione sta a significare: MOVE LITERAL TO W REGISTER ovvero muovi un valore costante nell'accumulatore. Come avremo modo di vedere più avanti, l'accumulatore è un particolare registro utilizzato dalla CPU in tutte quelle situazioni in cui vengono effettuate operazioni tra due valori oppure in operazioni di spostamento tra locazioni di memoria. In pratica è un registro di appoggio utilizzato dalla CPU per memorizzare temporaneamente un byte ogni volta che se ne presenta la necessita.
Il valore costante da memorizzare nell'accumulatore è 00011111 ovvero un valore binario a 8 bit dove il bit più a destra rappresenta il bit 0 o bit meno significativo.
Nell'istruzione successiva:

movwf     TRISA

il valore 00011111 viene memorizzato nel registro TRISA (come per il registro STATUS anche TRISA è definito tramite una direttiva EQU) la cui funzione è quella di definire il funzionamento di ogni linea di I/O della porta A. In particolare ogni bit ad uno del registro TRISA determina un ingresso sulla rispettiva linea della porta A mentre ogni 0 determina un'uscita.
Nella seguente tabella viene riportata la configurazione che assumeranno i pin del PICmicro dopo l'esecuzione di questa istruzione:

N.bit registro TRISA Linea porta A N.Pin Valore Stato
0 RA0 17 1 Ingresso
1 RA1 18 1 Ingresso
2 RA2 1 1 Ingresso
3 RA3 2 1 Ingresso
4 RA4 3 1 Ingresso
5 - - 0 -
6 - - 0 -
7 - - 0 -

Come è possibile vedere i bit 5, 6 e 7 non corrispondono a nessuna linea di I/O e quindi il loro valore non ha alcuna influenza.
Le due istruzioni successive svolgono le stesse funzioni per la porta B del PICmicro:

movlw     B'11111110'
movwf     TRISB 

in questo caso la definizione delle linee sarà la seguente:

N.bit registro TRISB Linea porta B N.Pin Valore Stato
0 RB0 6 0 Uscita
1 RB1 7 1 Ingresso
2 RB2 8 1 Ingresso
3 RB3 9 1 Ingresso
4 RB4 10 1 Ingresso
5 RB5 11 1 Ingresso
6 RB6 12 1 Ingresso
7 RB7 13 1 Ingresso

Notate come il valore 0 nel bit 0 del registro TRISB determini la configurazione in uscita della rispettiva linea del PICmicro. Nella nostra applicazione infatti questa linea viene utilizzata per pilotare il LED da far lampeggiare.
Abbiamo visto che l'istruzione movwf TRISB trasferisce il valore contenuto nell'accumulatore (inizializzato opportunamente con l'istruzione movlw B'11111110') nel registro TRISB. Il significato di movwf è infatti MOVE W TO FILE REGISTER.

bcf   STATUS,RP0

Questa istruzione è simile alla bsf vista in precedenza, con la sola differenza che azzera il bit anziché metterlo a uno. La sigla un questo caso è BIT CLEAR FILE REGISTER.
Dal punto di vista funzionale questa istruzione è stata inserita per consentire l'accesso ai registri interni del banco 0 anziché ai registri interni del banco 1 di cui fanno parte TRISA e TRISB. Una descrizione più dettagliata verrà data più avanti in questo corso.

bsf  PORTB,LED 

Con questa istruzione viene effettuata la prima operazione che ha qualche riscontro all'esterno del PICmicro. In particolare viene acceso il led collegato alla linea RB0. PORTB è una costante definita in P16F84A.INC e consente di referenziare il file register corrispondente alle linee di I/O della porta B mentre LED è il numero della linea da mettere a 1. Se ben ricordate, all'inizio del source la costante LED è stata definita pari a 0, quindi la linea interessata sara' RB0.

MainLoop 

Questa linea contiene una label ovvero un riferimento simbolico ad un indirizzo di memoria. Il valore della label, come detto in precedenza, viene calcolato in fase di compilazione in base al numero di istruzioni, alle direttive ORG e alle altre istruzione che in qualche modo allocano spazio nella memoria del PICmicro. In questo caso, se contiamo le istruzioni inserite a partire dall'ultima direttiva ORG possiamo calcolare il valore che verrà assegnato a MainLoop ovvero 0x07.
In realtà il valore che assumono le label non ha molta importanza in quanto il loro scopo è proprio quello di evitare di dover conoscere la posizione precisa degli opcode nella memoria del PICmicro permettendo comunque di referenziare una determinata locazione di memoria.
In questo caso la label MainLoop viene utilizzata come punto di ingresso di un ciclo (dall'inglese Loop) di accensione e spegnimento del led, ovvero una parte di codice che verrà ripetuta ciclicamente all'infinito. Incontreremo più avanti un riferimento a questa label.

call  Delay

Questa istruzione determina una chiamata (dall'inglese call) ad una subroutine che inizia in corrispondenza della label Delay.
Le subroutine sono delle parti di programma specializzare ad effettuare una funzione specifica. Ogni qualvolta è necessaria quella funzione è sufficiente richiamarla con una sola istruzione, anziché ripetere ogni volta tutte le istruzioni necessarie ad effettuarla. In questo caso la subroutine inserisce un ritardo pari al tempo di accensione e spegnimento del led.
Le istruzioni che compongono la subroutine Delay sono inserite più avanti in questo stesso source.

btfsc  PORTB,LED

Il significato di questa istruzione è BIT TEST FLAG, SKIP IF CLEAR ovvero controlla lo stato di un bit all'interno di un registro e salta l'istruzione successiva se il valore di tale bit è zero. Il bit da controllare corrisponde alla linea di uscita cui è collegato il diodo led, tramite questo test potremo determinare quindi se il led è acceso o spento e quindi agire di conseguenza, ovvero se il led è già acceso lo spegneremo, se il led è spento lo accenderemo.

goto  SetToZero 

Questa istruzione è un salto incondizionato (dall'inglese GO TO, vai a)alla label SetToZero dove troveremo le istruzioni per spegnere il led. Questa istruzione verrà saltata dall'istruzione successiva se il led è già spento.

bsf   PORTB,LED
goto  MainLoop 

Queste due istruzioni semplicemente accendono il led e rimandano il programma all'ingresso del ciclo di lampeggiamento.

SetToZero 
	bcf   PORTB,LED 
	goto  MainLoop 

Queste due istruzioni semplicemente spengono il led e rimandano il programma all'ingresso del ciclo di lampeggiamento.

Praticamente otterrete una "cosa" del genere

Anche se estremamente semplice, veder lampeggiare il LED la prima volta da una soddisfazione enorme!
E pensate poi, che "l'esistenza in vita" (in genere proprio un LED lampeggiante) è una pratica comune anche nei sistemi piu complessi!

La subroutine Delay

Come descritto in precedenza questa subroutine inserisce un ritardo di circa un secondo e può essere chiamata più volte nel source tramite l'istruzione call Delay.

Vediamo come funziona:

Delay
	clrf      Count
	Count+1   DelayLoop
	decfsz     Count,1
	goto        DelayLoop
	decfsz     Count+1,1
	goto        DelayLoop
	retlw       0

Delay e DelayLoop sono due label. Delay identifica l'indirizzo di inizio della subroutine e viene utilizzato per le chiamate dal corpo principale del programma. DelayLoop viene chiamato internamente dalla subrountine e serve come punto di ingresso per il ciclo (dall'inglese loop) di ritardo.
In pratica il ritardo viene ottenuto eseguendo migliaia di istruzioni che non fanno nulla!
Questo tipo di ritardo si chiama ritardo software o ritardo a programma. E' il tipo di ritardo più semplice da implementare e può essere utilizzato quando non è richiesto che il PICmicro esegua altri compiti mentre esegue il ritardo.

Le istruzioni:

     clrf   Count
     clrf   Count+1

CLEAR FILE REGISTER azzerano le due locazioni di ram riservate precedentemente con l'istruzione:

Count	RES 2   

Queste due locazioni sono adiacenti a partire dall'indirizzo referenziato dalla label Count.

Count,1

L'istruzione significa DECREMENT FILE REGISTER, SKIP IF ZERO ovvero decrementa il contenuto di un registro (in questo caso Count e salta l'istruzione successiva se il valore raggiunto è zero). Se il valore raggiunto non è zero viene eseguita l'istruzione successiva:

goto   DelayLoop

Che rimanda rimanda l'esecuzione all'inizio del ciclo di ritardo. Una volta raggiunto lo zero con il contatore Count vengono eseguite le istruzioni:

decfsz   Count+1,1
goto   DelayLoop

Che decrementano il registro seguente fino a che anche questo raggiunge lo zero. Il registro Count+1 in particolare verrà decrementato di uno ogni 256 decrementi di Count.

Quando anche Count+1 avrà raggiunto lo zero l'istruzione:

return

il cui significato è RETURN FROM SUBROUTINE determinerà l'uscita dalla routine di ritardo ed il proseguimento dell'esecuzione dall'istruzione successiva la call Delay.

Per finire END è una direttiva che indica al compilatore la fine del source assembler.

Compiliamo un source assembler

Vediamo ora come è possibile effettuare in pratica la compilazione di un source assembler.

Per prima cosa creiamo sul nostro disco fisso una directory di lavoro in cui da ora in poi memorizzeremo tutti i file sorgenti del nostro corso. Scegliamo un nome quale ad esempio:

C:\PBE

(Qualsiasi altro nome di directory o drive e' ovviamente valido. Basterà sostituire nel resto del corso tutti i riferimento a C:\PBE con il nome del drive e della directory scelti).

Copiamo ora nella nostra directory di lavoro C:\PBE il file LED.ASM.Per far questo basta cliccare con il tasto destro del mouse sul nome e richiedere di salvare il file nella nostra directory di lavoro.

Scarichiamo ora da internet il compilatore MPASM disponibile gratuitamente dal sito Microchip al seguente indirizzo:

Il file da scaricare e' asm21500.zip e contiene l'assembler MPASM sia in versione Windows (MPASMWIN.EXE) che MS/DOS (MPASM.EXE) oltre ad una serie di utility e tutti file .INC per i vari microprocessori prodotti da Microchip .

Una volta espanso il contenuto dei file asm21500.zip nella nostra directory di lavoro possiamo lanciare il file MPASMWIN.EXE.

La schermata che apparirà sarà la seguente:

Premiamo il tasto "Browse..." e selezioniamo il sorgente LED.ASM. Quindi premiamo il tasto "Assemble". L'assemblatore inizierà a compilare.
Al termine della compilazione otterremo la seguente schermata:

Se andiamo ora a vedere nella directory C:\PBE nuovi file creati, troveremo il file LED.HEX contenente il codice oggetto da utilizzare per programmare il PICmicro ed i file di supporto LED.ERR e LED.LST spiegati precedentemente.
Siamo ora pronti per programmare il PIC16F84A con il programma appena compilato.

Per la programmazione del PICmicro fate riferimento alla documentazione tecnica in dotazione al programmatore che state utilizzando.

I flag di configurazione dei PICmicro

Il PICmicro dispone di una serie di flag di configurazione contenuti nella cosidetta configuration word.

Questi flag determinano alcune modalità di funzionamento del PICmicro quando esso esegue un programma. La configurazione dei flag è indicata nei source d'esempio con la
direttiva __CONFIG e dovrebbe essere letta correttamente da quasi tutti i programmatori di PICmicro. Alcuni di questi pero non lo fanno per cui i flag vanno settati manualmente prima di iniziare la programmazione.

Tutti gli esercizi riportati in questo corso, salvo quando esplicitamente indicato, utilizzato la seguente configurazione:


  • Oscillatore in modalità XT. In questa modalità il PICmicro funziona correttamente con un quarzo collegato ai pin OSC1 e OSC2 come indicato negli schemi d'esempio

  • Watch Dog Timer Disabilitato. La funzione del Watch Dog Timer viene spiegata più avanti nel corso. Per far funzionare correttamente gli esempio (salvo quando indicato esplicitamente) il watch dog timer deve essere disabilitato.

Esistono altri flag di configurazione il cui settaggio non determina cambiamenti sull'esito degli esercizi.

MPLAB Ambiente integrato di sviluppo

Pur rimanendo fondamentali le istruzioni di compilazione sopra descritte, gli sviluppi software permettono ormai di usare degli ambienti integrati, come MPLAB, software completamente gratuito e sempre aggiornato dalla Microchip

Con MPLAB è possibile creare un progetto, editare il file sorgente principale ed eventuali file , compilare e simulare direttamente il firmware tramite il simulatore SIM interno.
MPLAB lo trovate sul sito della Microchip.

Consiglio anche la lettura del corso su MPLAB per poter facilmente iniziare con i PICMICRO

Architettura interna dei PIC16F84A

La memoria programma, il register file, la ALU, il registro W, il Program Counter, lo Stack Pointer, realizziamo delle luci in sequenza

Dopo aver fatto un po 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 MEMORYe 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 capacita 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.

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

Scarica subito una copia gratis

3 Commenti

  1. Avatar photo slovati 19 Maggio 2009
  2. Avatar photo jeegrobotlee 19 Agosto 2010
  3. Avatar photo Emiliano.Bianco 2 Febbraio 2014

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend