Il PIC 16F84




Introduzione



Il 16F84 è un microcontrollore RISC a 8 bit della Microchip estremamente versatile e semplice da utilizzare. E' possibile controllare led, rele', motori e attuatori in genere oppure controllare lo stato di sensori esterni. E' molto utilizzato anche come manipolatore e generatore/ricevitore di segnali (radiocomandi, lettore di schede magnetiche e/o simcard etc...). Prima di poter utilizzare il PIC occorre programmarlo; cio' richiede l'inserimento del programma compilato anella memoria interna. Il programma invece viene realizzato e compilato con l'ausilio di un normale computer casalingo.
Una volta programmato ed acceso, il PIC inizia ad eseguire il programma e, se previsto, a comunicare opportunamente con il mondo esterno tramite i suoi 13 piedini di ingresso/uscita. Il microcontrollore è anche molto economico (un singolo pezzo può venire a costare intorno ai 7 euro, mentre se presi in stock si arriva anche a 50 centesimi l'uno) il che lo rende adatto anche per l'elettronica amatoriale.
In foto si mostra un PIC 16F84 nel classico package DIL a 18 piedini.



Caratteristiche



  • Architettura Harvard: il PIC possiede memorie separate per i dati e le istruzioni.
  • Memoria FLASH per le istruzioni da 1 K (1024 istruzioni) programmabile con l'ausilio di un computer esterno. Questa memoria supporta fino ad un massimo di 1000 cicli di cancellazione/scrittura.
  • Memoria RAM dei dati da 90 bytes, dei quali 22 utilizzati per i registri interni di sistema (SFR = Special Function Registers) e i restanti 68 come registri utente liberi (GPR = General Purpose Register)
  • Frequenza di clock massima: 10MHz (20MHz per la versione 16F84A)
  • Un set di appena 35 istruzioni. Grazie al sistema di pipelining ogni istruzione viene eseguita in un singolo ciclo macchina (4 colpi di clock) eccetto le istruzioni di salto che richiedono 2 cicli macchina (8 colpi di clock). Ad esempio, con un oscillatore esterno da 4MHz è richiesto 1 microsecondo per l'esecuzione di una istruzione non di salto e 2 microsecondi per quelle di salto (condizionato o non).
  • Memoria EEPROM interna da 64 bytes. Questa memoria può essere programmata via software dal PIC stesso e sopporta fino ad un massimo di 1 milione di cicli di cancellazione/scrittura. Tale memoria non può essere utilizzata come RAM aggiuntiva per via della sua lentezza (20 ms in scrittura) e l'accesso seriale (non e' mappata nello spazio degli indirizzi direttamente raggiungibili dalla CPU e viene letta/scritta solo tramite l'ausiliio di alcuni dei registri speciali SFR)
  • Stack a 8 livelli (Lo stack è implementato in una memoria a parte non visibile da programma e quindi non occupa lo spazio della RAM)
  • Timer interno a 8 bit
  • Watch-dog interno
  • 2 porte di I/O (porta A a 5 bit e porta B a 8 bit) per un totale di 13 piedini di ingresso/uscita. Ogni linea può essere programmata indipendentemente dalle altre come linea di ingresso o linea di uscita. Possono sembrare poche ma va sempre ricordato che il microcontrollore è alloggiato in un DIL a soli 18 piedini!
  • 4 diverse possibilità di interrupt (esterno tramite piedino apposito, del timer, esterno dovuto al cambio di stato dei piedini di I/O, interno di completamento della fase di scrittura della EEPROM)
  • Opzione di protezione del codice. Settando questa opzione viene impedito ogni tentativo di lettura della memoria FLASH d programma.
  • Tensione di alimentazione da 2 a 6 volt. Tensione di programmazione da 12 a 14 volt.



Piedinatura



Come detto prima il PIC possiede 18 piedini. 13 di questi sono adibiti all'I/O in logica TTL: questo significa che i valori booleani sono rappresentati dalle tensioni 0V e +5V rispettivamente per lo 0 e 1 logico. I rimanenti piedini vengono impiegati per il reset, l'alimentazione e per l'oscillatore esterno che fornisce il clock al PIC stesso. Come si vede in figura alcuni piedini hanno una duplice funzione (ad esempio il piedino numero 3 porta la dicitura RA4 e T0CKl) anche se di default vale la prima (il piedino numero 3 e' di default RA4). Le funzioni secondarie verranno spiegate piu' avanti.



Ecco l'elenco dei piedini e delle loro funzioni:
  • RA0, RA1, RA2, RA3, RA4 - Sono i 5 piedini della porta A (tale porta e' a 5 bit). I piedini possono essere configurati indipendentemente come linee di ingresso o di uscita.  Quando un piedino e' impostato come linea di uscita, presentera' una tensione di 0V o 5V a seconda che il PIC abbia associato uno 0 o 1 logico al piedino stesso, tramite apposite istruzioni. Quando e' impostato come ingresso, il PIC potra' ricevere un valore booleano leggendo il livello di tensione fornito al piedino in questione. Se il livello e' maggiore di 2V verra' letto un 1 logico, se inferiore a 0.8V verra' letto lo 0 logico. Applicando una tensione compresa tra 0.8 e 2V il risultato e' impredicibile.
  • RB0, RB1, RB2, RB3, RB4, RB5, RB6, RB7 - Sono gli 8 piedini della porta B. Valgono le considerazioni viste per quelli della porta A.
  • GND - Riferimento di massa
  • VDD - Tensione di alimentazione. Deve essere compresa tra 2 e 6V. Di norma e' 5V.
  • OSC1 e OSC2 - A questi piedini deve essere collegato l'oscillatore che fornisce il clock al sistema. Per alcuni tipi di oscillatori sono necessari tutti e due i piedini, per altri serve solo OSC1 e quindi OSC2 puo' essere lasciato scollegato.
  • #MCLR - Piedino di reset, detto anche MasterCLeaR. L'attivazione del piedino produce un reset del PIC, cioe' il sistema riparte da capo con l'esecuzione del programma interno, come quando viene appena acceso. Questo piedino e' l'unico ad essere attivo basso, cio' significa che solo portandolo a massa si provoca il reset del PIC; durante il funzionamento normale il piedino deve essere mantenuto a livello logico alto tramite apposita resistenza limitatrice di corrente.





Il piedino #MCLR



Per funzionare correttamente il PIC ha bisogno di tenere alto il livello logico del piedino di reset (#MCLR). Ogni volta che si desidera resettare il PIC occorrera' invece portare a massa tale piedino.
Ecco un semplice circuito di pull-up standard da interfacciare al piedino #MCLR del microcontrollore: solo due resistenze ed un interruttore.



Durante il funzionamento normale, cioe' ad interruttore aperto, il piedino #MCLR e' in stato logico alto (circa VDD Volt). Premendo l'interruttore si porta momentaneamente a massa il piedino, scatenando il reset del PIC. La resistenza da 100 ohm limita la corrente nel piedino stesso quando il pulsante e' premuto.
Come si vedra' anche negli esempi questo circuito e' praticamente sempre presente.



Oscillatore esterno



L'oscillatore esterno fornisce il clock al microcontrollore, permettendone cosi' il corretto funzionamento. Il PIC 16F84 accetta clock con frequenza fino a 10MHz (il modello 16F84A fino a 20MHz). In ogni caso il PIC impiega 4 colpi di clock per istruzione (8 nel caso di istruzioni di salto).
Esistono 4 tipi di oscillatori: XT,RC,LS e HS

  • XT
Utilizza un cristallo di quarzo da collegare ad entrambi i piedini OSC1/CLKIN e OSC2. Le frequenze supportate dipendono dal quarzo stesso nel range di valori da 100KHz e 20MHz. Questo tipo di oscillatore e' estremamente preciso ed affidabile e quindi quello piu' utilizzato.



  • RC
E' un'oscillatore molto semplice, composto da una restistenza ed un condensatore, da collegare al piedino OSC1/CLKIN. Il piedino OSC2 puo' essere lasciato scollegato, oppure puo' essere utilizzato per prelevare un segnale ad onda quadra di frequenza pari alla quarta parte di quella di clock, cioe' la frequenza di esecuzione delle istruzioni (una istruzione richiede 4 colpi di clock). Il consumo di corrente e' ridotto al minimo ma l'oscillatore e' poco preciso e tende a variare la frequenza in funzione della temperatura e tensione di alimentazione. Si raggiungono basse frequenze (da 80Hz fino a 625KHz): ad esempio, con una resistenza da 10K e un condensatore da 220pF si raggiungono gli 80KHz.
Per programmi che richiedono una esecuzione lenta conviene installare un oscillatore XT e poi aggiungere istruzioni di ritardo, piuttosto che abbassare la frequenza del PIC con un oscillatore RC.



  • LP e HS
Utilizzano un risonatore ceramico rispettivamente per basse ed alte frequenze di clock. Tutti e due i tipi sono abbastanza precisi, il primo tende a consumare poco mentre il secondo molto di piu', per via delle elevate frequenze raggiunte.

Durante la fase di programmazione del PIC andra' specificato quale dei 4 tipi di oscillatore e' stato utilizzato. In questo modo i piedini 15 e 16 del PIC (OSC1/CLKIN e OSC2/CLKOUT) si configureranno in modo opportuno per ricevere il segnale da quello specifico tipo di oscillatore.



Struttura interna



In figura viene riportata a grandi linee la struttura interna del PIC. In alto a sinistra e' la memoria delle istruzioni da 1024 posizioni. In alto al centro la RAM principale, chiamata anche RAM File Register da 68 byte (cioe' 68 registri). A destra di questa e' la memoria EEPROM da 64 byte.
La memoria delle istruzioni viene indirizzata da uno specifico puntatore detto Program Counter. Tale registro permette di recuperare in sequenza le istruzioni del programma e di portarle nell'Instruction register. Sebbene bastino 10 bit per indirizzare la memoria istruzioni (2^10 = 1024) il Program Counter e' a 13 bit perche' il modello 16F84 (come il 16F84A) fa parte di una famiglia di PIC piu' estesa che contempla anche memorie di dimensioni maggiori: i progettisti tendono a ridurre le differenze tra le varie versioni dei PIC per minimizzare i costi di produzione. L'istruzione viene poi inserita nell'Instruction register (di 14 bit) e poi decodificata ed eseguita. Il Program Counter viene incrementato di uno (oppure di una altra quantita' se e' previsto un salto).
Il microcontrollore possiede un solo registro esterno alla memoria RAM, il registro W (Work). Questo registro entra in gioco durante le operazioni booleane, aritmetiche o di movimentazione dei dati. Ad esempio, per copiare un byte da una posizione di memoria ad un altra occorrono due istruzioni macchina: la prima legge la posizione di memoria desiderata e ne trasferisce il contenuto (il byte) nel registro W, la seconda trasferisce il contenuto di W nella posizione di memoria di destinazione.
Le operazioni booleane o aritmetiche prevedono sempre e solo due operandi, il primo e' W, il secondo e' un locazione di memoria RAM (cioe' un registro del File Register); si puo' scegliere se piazzare il risultato dell'operazione in W (e quindi sovrascrivere il primo operando), o nella stessa locazione di memoria (sovrascrivendo il secondo operando).
Le porte di I/O (porta A e porta B) sono mappate in RAM, cio' significa che si puo' leggere e scrivere nelle porte semplicemente leggendo e scrivendo nelle relative locazioni in RAM. Ad esempio, una scrittura di un byte nella locazione di memoria collegata alla porta B causa la configurazione opportuna dei segnali di tensione nei piedini della porta B (RB0,RB1,RB2 ... RB7), viceversa una lettura traduce in un byte la configurazione attuale delle tensioni applicate sui piedini di tale porta. Ovviamente un piedino di I/O non puo' essere simultaneamente di input e di putput: occorre decidere all'inizio la "direzione" dei piedini per tutte e 13 le linee e cio' si risolve ancora una volta scrivendo in determinate posizioni di memoria RAM.
Piu' avanti si chiariranno tutti questi meccanismi con esempi in assembler.