# PIC (microcontrollore)

PIC è una famiglia di circuiti integrati a semiconduttore con funzioni di microcontrollore prodotto dalla Microchip Technology. Il termine PIC non è usato come un acronimo: il suo nome aziendale è "PICmicro". Anche se generalmente sta per "Programmable Interface Controller", il suo primo produttore (la "General Instrument") usava l'acronimo per "Programmable Intelligent Computer".
Inizialmente sviluppato nel 1975, è in grado di svolgere un set di istruzioni ridotto (RISC): la versione più piccola ha 33 istruzioni assembly. I dispositivo programmatore ufficiale per i microcontrollori PIC è il Pickit.
Ad oggi, sono disponibili microcontroller PIC a 8 bit (serie PIC10, PIC12, PIC16 e PIC18), a 16 bit (serie PIC24 e dsPIC) e a 32 bit (PIC32), quest'ultimi di architettura radicalmente diversa, poiché basati su un core MIPS32 M4K.

## Versioni a 8 bit

Nell'arco del tempo, ne è stata resa disponibile una ampia varietà di versioni dei PIC a 8 bit, diverse per tecnologia costruttiva, forma fisica (numero di piedini), quantità o tipo di memoria, oltre alle funzioni di ingresso e uscita.
Per quanto riguarda la memoria di programma, ne esistono versioni con programma su ROM mascherata, quindi non riprogrammabili, versioni CMOS programmabili una sola volta OTP, versioni EPROM con finestra per cancellazione tramite raggi UV e versioni con memoria flash.
Le versioni CMOS hanno all'interno del nome del componente una C (es. PIC16C505), le versioni ROM hanno CR (es. PIC16CR57A) e le versioni flash hanno una F (es. PIC18F452). Si noti che la serie C è ormai obsoleta, per cui le versioni più usate sono quelle con memoria di tipo FLASH, che si possono programmare tantissime volte in breve tempo per mezzo di un programmatore ICSP (In-Circuit Serial Programming).
Il PIC più conosciuto è il PIC16F84: ormai è stato soppiantato dal più completo PIC16F88, con il quale è quasi completamente compatibile (occorre solo cambiare l'inizializzazione delle periferiche e ricompilare il codice per la corretta mappatura dei registri). Il 16F88 al suo interno ospita numerose periferiche come l'USART, 3 temporizzatori, 2 comparatori e un A/D a 7 canali. Ha anche un oscillatore interno e quindi le porte OSC1 e OSC2 possono essere usate come ingressi o uscite (RA6, RA7); la porta di reset/programmazione (MCLR), se non serve può essere utilizzata come ingresso generico (RA5), ma non come uscita. Inoltre si può leggere e scrivere la memoria di programma (e non solo la EEPROM dati) direttamente da codice.
Con la stessa piedinatura del 16F84, oltre al già citato 88 (e 87, uguale all'88 ma senza A/D), ci sono i 627/628/648A, 716 e 818/819. Esistono poi altre versioni simili, ma con maggiori piedini di ingresso e di uscita (ad esempio le versioni 16F876 e 16F877). Quest'ultima serie garantisce un set di periferiche molto più esteso, consumi minori e soprattutto costi minori. Il diretto equivalente del 16F84 è il 18F1220, che comprende anche una USART, una MSSP, ingressi analogici ed altro.
La serie speciale 18FJ, non disponendo di EEPROM a bordo, è la serie più economica prodotta da Microchip. Utilizzando infatti microcontrollori con più memoria di programma rispetto a quanta effettivamente necessaria, è possibile scrivere su quest'ultima riservandosi una zona ad uso simil-EEPROM.
Vi sono poi microcontroller PIC che spiccano per l'impiego in una specifica applicazione: ad esempio, i 16F1455 e i 18F2550 hanno supporto hardware allo stack USB 2.0, così come i PIC18F67J60 integrano un controller Ethernet mentre i 16F1933 sono spesso utilizzati nel controllo di display fino a 60 segmenti grazie ad un driver integrato.
Le serie più recenti, le cosiddette "Enhanced" e "Enhanced Mid-Range" (12F1xxx, 16F1xxx, 18F1xxx) aumentano ancor di più il numero di periferiche a disposizione: il PIC 16F1769, ad esempio, aggiunge DAC, celle logiche programmabili, amplificatori operazionali integrati sul die, rivelatori di zero-crossing e capacità di erogare maggior corrente sugli I/O, tutto al fine di ridurre il part count e quindi il costo totale del progetto.

## Istruzioni

Il set di istruzioni del PIC ne comprende 33 nelle versioni di bassa potenza e fino a 77 in quelli con prestazioni più elevate. Per essere eseguita, ogni istruzione impiega 4 cicli di clock, tranne le istruzioni che comportano un salto all'interno della memoria (GOTO, CALL, RETLW), che impiegano 8 cicli; nelle versioni recenti vi sono altre istruzioni che impiegano 8 cicli, come quelle di trasferimento di dati tra memoria e memoria (MOVFF).

## Architettura interna

L'architettura è di tipo Harvard a bus separati; i bus dati e controllo sono a 8 bit, mentre le istruzioni hanno un formato a 12, 14, 16 o 32 bit.
Nelle ultime versioni è stata implementata un'architettura a 16 bit o 32 bit. Esiste anche il bus dello stack a partire da 9 bit in su.

## Memorie

A causa dell'architettura RISC, dove nell'istruzione oltre al significato è compreso anche l'indirizzo di memorizzazione o di salto, la memoria viene segmentata. Per cambiare segmento in uso occorre agire su appositi registri, fatto che complica la programmazione dei PIC tramite linguaggio assembly, ma non quella con linguaggi di alto livello.

### RAM

La RAM ha una larghezza di 8 bit e una profondità che varia da pochi byte (25 nei PIC16C5x) fino a qualche kilobyte.

### Di programma

La larghezza della parola di programma varia da 12 bit (ad esempio, nel PIC16C54) a 14 bit (ad esempio, nel PIC16F628) a 16 bit (ad esempio, nel PIC18F4520). La sua profondità varia da 512 byte a 128 kibibyte (KiB).

### Stack

Lo stack è un tipo di memoria, separata da quella principale, caratterizzata da un particolare metodo di accesso (LIFO). È dotato di un suo bus la cui profondità va da 2 posizioni a 8 posizioni e giunge alle 31 nei PIC della serie 18. La sua larghezza parte da 9 bit.

### EEPROM

Nelle versioni con memoria flash può essere presente una memoria interna di tipo EEPROM accessibile come se fosse una periferica per potervi memorizzare dei dati che, se non esplicitamente cancellati, si conservano per almeno 40 anni. La sua capienza varia da 64 a 1024 byte.

## Periferiche

La presenza di periferiche a bordo del chip è uno degli aspetti che fanno la differenza tra un microprocessore ed un microcontrollore. Nei PIC si parte da dei semplici I/O digitali per arrivare a funzioni complesse passando attraverso una notevole varietà di altre funzioni.

### I/O paralleli

La funzione di ingresso e uscita di dati digitali è stata la prima funzione implementata. Nei PIC è divisa in porte da 8 o meno bit ognuna. È possibile programmare ogni bit come ingresso o come uscita singolarmente.
In alcuni casi è possibile attivare dei resistori interni (weak pull-up) per facilitare il collegamento con pulsanti ed interruttori.
I PIC più recenti dispongono inoltre di celle logiche programmabili alla stregua di un CPLD di dimensioni ridotte.

### I/O seriali

Può essere presente una grande varietà di porte seriali: I²C, USART, SPI, CAN/LIN, USB ed Ethernet.

### I/O analogici

Vi sono PIC con comparatori, ADC, DAC, generatori di rampa (PRG), rivelatori di zero-crossing (ZCD), generatori di forma d'onda complementare (CWG/COG), amplificatori operazionali integrati e altro ancora.

### PWM

Vi possono essere multipli canali PWM solitamente a 10 o 12 bit.

### Timer

Su tutte le versioni è implementato almeno un temporizzatore da 8 bit. Si arriva fino a 5 temporizzatori con larghezze a 8 o 16 bit. Su tutte è inoltre implementato un temporizzatore speciale chiamato WDT (Watch Dog Timer), che serve (se utilizzato) a far ripartire il microcontrollore in caso di blocco del programma. Il timer funziona in base alla frequenza di lavoro del PIC e/o può utilizzarne, tramite un apposito piedino, una diversa da quella di lavoro tramite un oscillatore esterno. Ad ogni timer, inoltre, può essere associato un divisore di frequenza integrato chiamato prescaler, che divide la frequenza di lavoro di: 2, 4, 8, 16, 32, 64, 128, 256 volte.

## Particolarità dell'architettura

La RAM è trattata totalmente come fosse un registro ed ogni suo membro è chiamato file register o più semplicemente file.
Non esiste un accumulatore vero e proprio ma un registro chiamato W (Working register) e i risultati di tutte le operazioni logico aritmetiche possono essere messi indifferentemente nel file operando o in W.

## Compilatori con linguaggi evoluti

I PIC vengono programmati generalmente in C o in Assembly, quest'ultimo comune soprattutto con i PIC di vecchia generazione o, più in generale, con versioni aventi una ridotta memoria o profondità di stack.
Microchip offre compilatori ufficiali per entrambi i linguaggi: MPASM, XC8, XC16, XC32, integrati con l'IDE MPLAB X. L'ambiente di sviluppo, i compilatori e i driver dei programmatori sono oggi disponibili per Windows, MacOS e Linux.
In ogni caso, PIC ha una lunga tradizione di compilatori di terze parti sia per il C (MikroElektronica, CCS) sia per linguaggi meno "canonici" dal punto di vista della programmazione embedded, quali BASIC o Pascal.
Esistono anche compilatori open source: SDCC e Jal, oltre allo stesso XC32 di Microchip.