| |
|
Corso di
PICmicro™
Sapete
cos'è questo mostro a sinistra? Beh, forse se state leggendo queste
righe non lo sapete ma vi interessa.. Lo scopo di questo articolo è
infatti introdurre a tutti, anche ai nuovi arrivati, l'utilizzo dei
PICmicro.
Questo articolo spiega come partire da 0 nella creazione del programmatore,
come programmare un chip, come compilare il codice e come scrivere questo
"codice" da inserire dentro il PIC. Questo va visto infatti
come una macchina che esegue delle istruzioni sequenzialmente e tali istruzioni
risiedono nel suo interno. Vi assicuro che nell'arco di una settimana
sarete degli abili programmatori.. è molto semplice. Ringrazio
il corso sull'assembly per pic di Tanzilli (al quale rimando come referenza
sulla programmazione e dal quale ho preso qualche immagine :). Vi consiglio
di scaricarvi subito il datasheet del PIC18f84 dal sito della della Microchip,
come consigliato in seguito.. prima l'avete e prima si inizia... ^_^
I
PIC MicroChip
sono una famiglia di integrati molto versatili: il
12c508 è utilizzato ad esempio per la modifica alla
playstation,
il 16f84 è utilizzatissimo e sta avendo un successone dato
che molti lo usano per vedere il satellite 'a sbafo'! Noi è proprio
di quest'ultimo che ci occuperemo, indicando caratteristiche, come programmare
il chip, come scrivere i programmi e come farlo funzionare.
Nota x i più esperti: quando avrete imparato
ad utilizzarli, li userete al posto di un 555, al posto di una not, per
fare giochi di luce (es. supercar), insomma, potete programmarli come
volete e farvi da voi i vostri integrati!
 

Caratteristiche di rilievo dell'integrato:
- Alimentazione: 2V < Vcc < 6V
- 13 pin di i/o (configurabili via software come i/o singolarmente)
su 18 piedini!
- Frequenza: 0 < 16f84/04 < 4MHz oppure 0 < 16f84/20 < 20MHz
(Oscillatore anche con RC)
- Memoria: programma 1K flash, ram 68 bytes, eeprom 64bytes interna(!)
- Output 20ma a livello alto e 25ma a livello basso (ottimo per pilotare
direttamente LED)
- Interrupts, timers, 15uA consumo a 2V (con 2 batterie vai avanti anni!),
sleep mode, watchdog, ...
- Architettura RISC a 35 istruzioni (una decina le più usate)
-
 Piedinatura
e descrizione linee:
rA0 -> rA4:
5linee di i/o
rB0 -> rB7:
8linee di i/o
Vss: Massa
Vcc: +V (da 2 a 6V)
MCLR:
reset. di default a Vcc con una resistenza (10k). Aggiungere un tasto
a massa x il reset manuale.
OSC1/OSC2: oscillatori.
|
Ci sono 4 possibili modi per fornire un clock all'integrato:

- il più semplice (modo 'RS') consiste nel mettere dal piedino
16 una resistenza a Vcc ed un condesatore a massa. (con R=4.7K e C=20pF
si ottiene circa un MHz)
- poi (modo 'XT') si può utilizzare un oscillatore al quarzo. In
tal caso il quarzo verrà collegato tra i piedini 15 e 16. Sempre
su questi piedini si collegano 'dietro' il quarzo 2 condensatori da 22pF
con il 2° pin dei condensatori in comune a massa.
- Esistono altri modi, ma non li analizziamo. Aggiungo solo che si può
dare un clock esterno al PIC con un tasto o con un 555 o con un gdf..
basta collegarsi solo al pin 16.
Riepilogo: per fare 'girare' il programma in un pic,
è necessario: collegare vcc e massa, collegare una res tra mclr
e vcc, aggiungere la coppia rc sul 16 o il quarzo. La prima basetta la
montate in 2 minuti.
Nota: per visualizzare lo stato di una uscita ra o rb, porre in serie
un led con resistenza a massa. Suggerisco R=280Ohm collegata al piedino,
e al diodo led con catodo (taglietto) a massa.
 

Esistono diversi tipi di programmatori, e se andate a comprarli nei negozi,
i più miseri costano più di 200K£; questo scoraggia
molto. Esistono però molti programmatori 'alternativi' come il
ludipipo o il JDM. Il primo è il più usato perchè
composto da 4 resistenze, 1 condensatore e 2 diodi!!

MultiPippo:
Il multipippo al quale faccio riferimento è un programmatore creato
da ooz e bubz (due nomi storici per le pay tv italiane :) sulla base del
ludipipo originale di Ludwig cattas. Il LudiPipo è compatibile
con tantissimo software freeware: pic.exe, picprog, icprog, ponyprog,
k-burner (l'ho fatto io!!), etc.. e supporta 16c84, 16f84, tutte le eeprom
24cxx (04,16,32,64,..), il 12c508 (modifica psx!), e tanti altri, è
indispensabile e costa come un paio di caffè!

MultiPippo schematics:
Se andate sui link che vi propongo alla fine, trovate tanti programmatori del genere, io mi limito
a farvi lo schema, visto che nel sito sono presenti solo i pcb per le
basette fatte con l'acido!
PCB lato componenti
|
PCB lato rame
|
Schema ricavato dai pcb qui sopra
|
Si nota che negli schemi appaiono gli 8 contatti per lo zoccolino 4+4
che dovrà ospitare le eeprom 24cxx. E' molto utile e vi consiglio
di montare pure quello, vedrete che a breve potrebbe servirvi.. altrimenti
montate lo schema che ho disegnato qui sora. In pratica la linea 3 viene
mandata a +10V e questo consente di mandare il chip in modalità
programmazione e inoltre di fornirgli, tramite un circuito di adattamento
i 5V, necessari per il funzionamento. I pin 4 e 8 servono rispettivamente
per scrivere/leggere dalla linea rB7 del PIC. Infine la linea 7 serve
solmente per dare il clock in fase di programmazione.

Lista materiali:
tutte le resistenze sono da 1/4 di watt. I diodi da 1/2.
| R1 2200 Ohm |
R2 2200 Ohm |
R3 10 KOhm |
| R4 22 KOhm |
C1 10uF elettrolitico |
D1 1N4148 |
| DZ1 ZENER 5,6 Volts |
Z1 Zoccolino 8 (4+4) pins |
Z1 Zoccolino 18 (9+9) pins |
| CON1 Connettore seriale femmina 90° a saldare
(da millefori) |
|
Riepilogo: correte a comprare il materiale se non lo
avete in casa e vedrete che in 5 minuti al massimo montate lo schemino
che vi ho riportato.. 4res, 2diodi, 2c.. Montate tutto su millefori (consiglio
componenti stagnati su millefori e collegamenti fatti sotto con filo),
vi basteranno 5x4cm al massimo, vedrete che ne vale la pena...
 

Costruito il programmatore? Se si continua a leggere, se no, fallo lo
stesso, così vedi quanto è facile programmare un pic! Io
consiglio di usare il 'pic.exe' (anche 'pic24c13.exe' reperibile in giro per la rete)
che però può dare problemi se usato da windows, quindi al
riavvio del PC, shift+F5 e siete al prompt, così lanciate pic.exe
senza problemi. Anche ICprog x Win9x è buono, ma di win mi fido
sempre poco :-). NB attualmente ICprog è alla versione 1.2, mentre
quello nella foto è il 0.9e..
pic.exe (1.10)
|
ICprog (0.9e)
|
Prima di programmare il PIC che andrà inserito nello zoccolo del
programmatore (collegato al pc tramite una prolunga seriale) è
necessario settare i parametri di comunicazione. La comport dove è
'appeso' il programmatore (1 o 2 se avete il mouse su com1). Se avete
il modem su com2 e il mouse su com1 staccate il modem quando programmate
e usate la com2. Successivamente settiamo il programmatore come 'LudiPipo'
o 'JDM' se il primo è assente. Infine settiamo il tipo di PIC da
programmare come 16f84. Attenzione! il pic 16f84A potrebbe
dare problemi di programmazione su computer che hanno schede madri scadenti.
Ora che sono stati settati i parametri di comunicazione è
necessario caricare l'hex e settare i fuses.
A) caricamento dell'hex. Tale file non è altro
che la mappa della memoria programma del pic, che durante la programmazione
sarà copiata all'interno del pic.I file hex sono il risultato creato
dalla compilazione di un file asm. Tale file contiene le istruzioni che
il pic dovrà eseguire. Un apposito programma converte le istruzioni
in numeri e genera il file 'nome.hex' che andrà inserito nel pic.
Se usate pic.exe i file hex vanno copiati nella cartella del pic (consiglio
c:\pic) così state presto ad entrarci da dos. Andate in 'loal hex'
dal menu file e apritene uno. Analoga procedura per i programmi da
windows,
che però consentono di spostarsi tra le cartelle.

B) settaggio dei 'fuses'. I fuses sono delle celle
di memoria che vengono programmate sul pic alla fine della scrittura del
codice. Servono per indicare la modalità di funzionamento. Sono
4:
- CodeProtect: Default[NO] Indica se il codice del pic deve
essere protetto da lettura. Utile per evitare spinaggio industriale, ma
inutile per noi, dato che dopo il pic non sarà più
scrivibile!
- PowerUpTimer: Default[YES] Attende 50mSec prima di iniziare
l'esecuzione del programma, in modo che l'alimentazione si stabilizzi.
- WatchDogDimer: Default[NO] Inutile a noi, serve per evitare
che il programma si pianti. Se il programma non dà segnale di vita
entro un certo tempo, viene resettato il pic. Controproducente.
- Oscillator: Default[XT o RS] Setta il tipo di oscillatore:
XT = quarzo o esterno RS = rc LP,HS non utilizzati da noi.
Perchè il pic funzioni correttamente è importante il settaggio
dei fuses; di solito NO,YES,NO,RS.

Ora è possibile programmare il pic cliccando su program. Se avete
seguito le istruzioni alla lettera entro breve la barretta arriverà
al 100% segnando la fine della programmazione. Vedrete che dalla seconda
programmazione in poi, farete tutto in 10 secondi!
Riepologo: Per programmare inserire il pic e collegare
la seriale al pc. Copiare l'hex nella cartella del pic.exe, lanciarlo,
caricare l'hex, settare i fuses (se non sono gia corretti nell'hex caricato),
programmare e se volete per sicurezza controllate la scrittura ('compare').
Siete pronti per mettere il pic sulla sua basetta e godervi il frutto
delle vostre fatiche!!
 

A questo punto dovreste almeno essere in grado di discernere un pic da
un'aspirapolvere, riuscure ad inserirlo nel programmatore (dove stavate
cercando di inserire la coda del gatto) e programmarlo con un file hex
(se durante la programmazione si illumina + di una lampadina da 100W e
fa + fumo dei fumogeni da disco, allora non dovevate collegarlo al 220!).
Ok, ora arriva la parte software che inizialmente può essere un
po difficile da comprendere, ma alla fine vedrete che risulta naturale,
dato che si utilizzano al massimo una ventina di istruzioni diverse (su
35 che il pic ci mette a disposizione).
Iniziamo a descrivere il processo di compilazione, ovvero di creazione
di un .hex a partire da un .asm. Tale operazione viene eseguita dall'
MPASM, il compilatore free che la microchip mette a disposizione aggratis.
Dal sito www.microchip.com scaricatevi l'ultima versione dell'MPLAB (attuale
5.11.03), il software che vi permette di scrivere il programma per pic,
compilarlo e vedere se presenta errori. In caso contrario produrrà
il file hex relarivo al programma.
Come si vede dal disegno qui sotto, per programmare un pic bisogna seguire
le seguenti fasi:
- Con un editor (Notepad, edit, o direttamente l'MPLAB che consiglio)
si scrive il programma come una serie di istruzioni e direttive una sotto
l'altra.
- Il compilatore MPASM (se usate l'MPLAB c'è il tasto verde per
lanciarlo direttamente) prende il file asm scritto da voi e eventuali
files di include .inc per dare in uscita 4 files che hanno lo stesso nome
dell'asm, ma estensione divesa.
-
Nel caso non ci siamo errori, l'hex è buono e
possiamo scriverlo sul pic, altrimenti nell'err (o nella schermata di
errore dell'MPLAB) trovate la descrizione degli errori.
Quanto detto risulta molto più semplice a farsi che a dirsi.
Cmq voi prelevate il programma, installatelo e vedrete che è
semplicissimo da usare. L'importante è all'inizio creare un project
e dargli un nome. Con quello stesso nome dovrete creare il file asm,
tornare nel progetto, fare 'add node' e specificare il file asm creato.
Una volta fatto ciò non avrete più problemi di compilazione!
Finora vi ho dato gli stumenti per creare un programma partendo da un
testo, e metterlo all'interno della flash del pic. Ora
però vi serve per forza una mini guida su come programmare. Esiste
'Pic by Example', una guida in italiano di Sergio Tanzilli, disponibile
su www.tanzilli.com che insegna partendo da zero l'assembly per pic.
L'ho utilizzata io agli inizi, e vi assicuro che in un giorno se gia
sapete qualcosa, guardando gli esempi diverrete degli abilissimi programmatori.
Riepilogo: Scaricare ed installare l'MPLAB. Creare
un nuovo pregetto con con pic 16f84. Creare un file asm (inizialmente
vuoto) e salvarlo con nome nomeprogetto.asm. Andare in Edit Project
->add node, specificare il file asm e dare ok. Scrivete il programma
nella finestra dell'asm, compilate per vedere se ci sono errori. Se
no, verrà creato il file .hex che tratterete come già
descritto.
Primo esempio: effetto SuperCar con 12
LED!
Spero che prima di arrivare qui abbiate gia guardato il corso di Tanzilli
xè la descrizione che qui darò dei comandi sarà
molto sinetica. Riporto di seguito il codice dell'ASM in questione (lo
faccio al momento, ma dovrebbe essere esatto) commentandolo ove si presenti
la necessità.
Per realizzare un effetto supercar, possiamo utilizzare le porte di
i/o del pic settate come uscita. Ma poichè rA4 è open-collector
(non da in uscita il livello alto), evitiamo di usarlo. Utilizzeremo
quindi rB0-rB7 e rA0-rA3. 12 linee che saranno collegate tramite altrettante
resistenze ad una fila di led con il catodo (il taglietto) a massa.
Per Settare dei valori alti/bassi, è sufficiente scrivere sulla
porta (a o b). Ovviamente possiamo anche compiere rotazioni, e facendolo
sulla porta otteniamo lo scorrimento di un led. Ma come passare da rb7
a ra0 e viceversa? il concetto è semplice. Ruotando, si spostano
tutti i bit a destra o sinistra di uno, il bit che entra proviene dal
carry (che noi metteremo a zero per far entrare uno zero) e quello che
esce va a finire nel carry. Va da se che ruotando a sinistra la porta
B, il bit che esce andrà in carry e ruotando a sinistra la porta
A, otterremo il passaggio del bit uscito da rb7 a rA0. Useremo inoltre
due routines, una che fa salire il bit e una che lo fa scendere, con
un controllo alla fine per invertire il senso di marcia dei bit. Infine
ci sarà una routine di delay che ci permetterà di vedere
l'effetto supercar, che, se non ci fosse il ritardo via software si
tramuterebbe in una riga di led sempre accesi. Analizziamo dunque il
sorgente
PROCESSOR 16F84
RADIX DEC
INCLUDE "P16F84.INC"
- Direttiva PROCESOR: dice al programma che stiamo utilizzando
il PIC 16f84
- Direttiva RADIX: specifica che i numeri sono in formato decimale.
Cioè se scrivo 10 significa il numero decimale 10, diverso da 0x10
(esadecimale del numero 16) e 00000010B (binario di 2)
- Direttiva INCLUDE: specifica al compilatore di caricare quel
file, che include le definizioni di alcuni parametri standard. Vedremo
meglio più avanti
__CONFIG 3FF3H
- Direttiva CONFIG: setta i fuses del pic. 3FF3 significa
NO,YES,NO,RS.
Vedere la sezione 'burning'. La si mette solo per evitare di inserirli
manualmente
ORG 0CH
Count RES 2
Direz RES 1
- Direttiva ORG 0Ch: Dice al compilatore che cio che segue fa parte della
ram. Segue la:
- Direttiva RES: Riserva 'n' bytes di memoria per la variabile
(2 bytes per Count e 1 per Direz)
ORG 00H
- Direttiva ORG 00H: Dice al compilatore che da qui in poi inizia
il programma vero e proprio. In caso di reset del pic, si riparte da
qui.
bsf STATUS,RP0
movlw 00000000B
movwf TRISA
movlw 00000000B
movwf TRISB
bcf STATUS,RP0
- Instruzione BSF: mette a 1 il bit specificato (RP0) nel registro specificato
(STATUS). In realtà RP0 e STATUS sono dei numeri e sono definiti
in quel file .inc che abbiamo incluso sopra. Ovviamente RP0 sarà
un numero che va da 0 a 7 dato che ogni registro o cella di ram ha 8
bit. Ad esempio:
bsf PORTB,4 -> alza il 5° piedino (rB4) della porta
B, ponendolo a livello alto.
- Istruzione MOVLW: carica nell'accumulatore (indicato con 'W'
nei PIC) una costante. Nel caso 0.
- Istruzione MOVWF: Mette l'accumulatore nel registro specificato (TrisA)
- Istruzione BCF: contrario di BSF, mette a 0 il bit.
Significato di questo blocco: TRISA e TRISB sono i registri (8 cellette
di memoria) che specificano se le porte A e B sono di ingresso o uscita.
0 significa uscita, 1 ingresso. Caricando 0 in a e in B, otteniamo la
configurazione delle 2 porte come porte di uscita. Per andare a modificare
questi 2 registri dobbiamo prima mettere a 1 RPO. Alla fine lo rimettiamo
a 0. Una istruzione tipo:
bsf TRISB,3 -> non fà nulla se RP0 è basso,
mentre se viene eseguita prima che venga abbassato RP0, setta la 4a linea
della porta A come ingresso.
movlw 00000001B
movwf PORTB
clrf PORTA
clrf Direz
clrf Count
clrf Count+1
bcf STATUS,C
- Istruzione CLRF: mette a 0 una variabile o registro.
Significato del blocco. PORTB è la porta B; scrivendo su questa
si vanno a cambiare gli stati delle linee della porta B. In pratica;
della porta B viene attivata solo la prima linea (bit 0) le altre tutte
basse. Tutte basse anche quelle della porta A. Mettiamo a 0 la variabile
Direzione (0 = salita 1 = discesa), la Count e la Count+1 (che non ha
nome, ma per count avevamo riservato 2 bytes). Notare che Count+2 corrisponderebbe
a Direz. Infine viene pulito il bit CARRY che si trova nel registro
STATUS, dove avevamo incontrato anche RP0.
Ora arriva il programma principale:
MainLoop
call Delay
btfss Direz,0
goto Sali
- Istruzione CALL: chiama una subroutine. In questo caso lancia la funzione
'delay'.
- Istruzione BTFSS Direz,0: Controlla il bit '0' della variabile 'Direz' e salta l'istruzione successiva se il bit è uno, mentre
l'eseguirà se il bit è zero.
In questo blocco, dopo avere ritardato di un po' l'esecuzione con la
funzione delay, si controlla se stiamo salendo o scendendo. Nel primo
caso il bit 0 di direz è a 0, per cui salterà alla funzione
'Sali', mentre se fosse a 1 continuerebbe l'esecuzione saltando il 'goto
Sali'. Ovviamente laddove salterà ci sarà la funzione
scendi.
Scendi
rrf PORTA,F
rrf PORTB,F
btfsc PORTB,0
bcf Direz,0
goto MainLoop
- Istruzione RRF: ruota a destra una variabile, inserendo come
nuovo bit il carry e ponendo quello che esce nel carry.
Come spiegato in precendenza, faccio scorrere verso giu il bit ruotando
a destra dalla porta A alla porta B. Successivamente controllo se sono
a fine discesa (cioè ho l'1 nel bit 0 della PORTB). Se no, continua
daccapo, altrimenti cambia direzione (da 1 a 0) e riparti daccapo.
Sali
rlf PORTB,F
rlf PORTA,F
btfsc PORTA,3
bsf Direz,0
goto MainLoop
Come la precedente scendi. Viene chiamata si il bit 0 di 'Direz' vale
'0'. Ruota a sinistra finchè non raggiungiamo il 4° bit della
porta A, a quel punto.. si scende!
Delay
movlw 40
movwf Count+1
DelayLoop
decfsz Count,F
goto DelayLoop
decfsz Count+1,F
goto DelayLoop
return
- Istruzione DECFSZ: Decrementa una variabile e salta l'istruzione successiva
se vale zero. Per fare un delay, l'istruzione successiva sarà
un goto a questa istruzione, di modo che decrementi ciclicamente la
variabile e quando vale 0, esca dal ciclo.
- Istruzione RETURN: termina una call, tornando al programma principale
dove era stata chiamata la funzione.
In questo blocco, settiamo a 40 il valore di Count+1. Poi c'è
un ciclo interno che ripete 256 volte il decremento di Count e la goto,
e un ciclo più esterno che ripeterà 40 volte il ciclo
interno. Per ottenere un ritardo accettabile insomma, dobbiamo fare
circa ventimila operazioni per niente!!
END
Finalmente l'ultima direttiva: END chissà a che serve...
Riepilogo: Per assemblare il codice e fare l'hex ricopiare
il programma in un .asm e compilarlo con l'MPLAB come descritto nel
3° capitolo. In seguito mettetelo nel pic, create il circuito base
come descritto nel punto uno, stagnate i led in fila con il meno a massa
e le resistenze in ordine da rB0 a rA4. Alimentate con una pila da 4,5
o 6 volt e il gioco è fatto!
Note
della RedazioneElettronicaNet, declina ogni
possibile
responsabilità derivante
dall''uso delle informazioni tecniche pubblicate su questa pagina
Qualora vengano segnalati contenuti non conformi alla legge
o protetti da copyright, questi verranno immediatamente rimossi
|
|
|