\section{\bf L'architettura del PIC16F877}


Il circuito integrato PIC16F877~\cite{ManualePIC}, 
fa parte della famiglia PIC16F87X, 
composta da 
quattro microcontrollori a memoria FLASH (la lettera F nel nome indica
proprio la presenza della memoria di tipo FLASH).
Tali microcontrollori sono prodotti dalla ditta {\it Microchip}. La sigla PIC,
utilizzata per la prima volta dalla ditta {\it General Instruments},
\`e l'abbreviazione di ``Programmable Intelligent Computer'', attualmente
tuttavia si tende ad interpretare questa sigla come ``Peripheral Interface
Controller''. 
I microcontrollori
che appartengono a questa famiglia offrono funzionalit\'a molto simili,
differenziandosi tra loro essenzialmente per 
la dimensione delle varie memorie 
e il numero di pin di input/output a disposizione.
Essendo piuttosto facili da programmare
sono stati utilizzati in una grande variet\'a di applicazioni. 
\begin{figure}[h!]
\begin{center}\mbox{\epsfig{file=PIC16F877/ChipPIC16F877.eps,width=0.5\textwidth}}\end{center}
\caption{\it{Fotografia dell'integrato della Microchip PIC16F877.}}
\protect\label{Chip}
\end{figure}
%Il Picpro77 che utilizzeremo non \`e altro che un microcontrollore 16F877 
%preprogrammato per ricevere del codice compilato a partire dalla 
%versione gratuita del compilatore ``CCS Pic C Compiler''. Quindi il Picpro 77 \`e
%praticamente un 16F877 'nature' ma molto facilmente programmabile.

Il microcontrollore \`e composto dal microprocessore, vero e 
proprio cuore del sistema, che si occupa di eseguire le operazioni 
matematiche e 
di gestire l'esecuzione dei programmi, e da vari dispositivi interni 
dedicati a compiti specifici detti periferiche interne o moduli. 
Una caratteristica peculiare dei PIC16F87X \`e l'adozione di
un'architettura di tipo ``Harvard'', che permette alla CPU di gestire
istruzioni e dati attraverso memorie e bus separati. Questo tipo
di architettura permette alla CPU di effettuare contemporaneamente un accesso
alla memoria programmi ed uno alla memoria dati. 
La velocit\`a di esecuzione
di una istruzione risulta quindi maggiore rispetto a quella ottenuta 
con architettura tradizionale (detta di ``Von Neuman''), nella quale
dati e programmi vengono prelevati attraverso il medesimo bus. 

Il microcontrollore \`e realizzato in un circuito integrato contenuto in un 
involucro detto DIL40
che presenta 40 pin, 20 da ciascun lato (vedi figura~\ref{Chip}). I pin sono virtualmente numerati da 1 a 40 come mostrato in figura~\ref{Integrato}. 
\begin{figure}[h!]
\begin{center}\mbox{\epsfig{file=PIC16F877/PIC16F877.eps,width=9.0 cm,height=9.5 cm}}\end{center}
\caption{\it{Schema del circuito integrato PIC16F877. Accanto ad ogni piedino \`e riportata la numerazione e le sigle che indicano le funzioni ad esso associate.}}
\protect\label{Integrato}
\end{figure}
Come per tutti i 
circuiti integrati ognuno dei pin \`e utilizzato per una o pi\`u funzioni,
indicate da una apposita sigla. 
%In tabella~\ref{FunzioniDeiPin} sono elencate
%brevemente le funzioni associate a ciascun pin e la sigla ad esse associata.
L'architettura generale di un microcontrollore ed il suo funzionamento
sono stati discussi nella sezione~\ref{Microprocessori,MicrocontrollorieMicrocomputer}. In questa sezione vengono descritte
le caratteristiche specifiche del microcontrollore PIC16F877.

L'architettura del PIC16F877 \`e schematizzata nel diagramma a blocchi 
mostrato in figura~\ref{DiagrammaABlocchi}. In questa figura sono riportati
tutti i componenti che saranno descritti nella prossime sezioni.
\begin{figure}[h!]
%\includegraphics*[bb=142 150 500 545, width=1.0\textwidth]{Dia.eps}
\begin{center}\mbox{\epsfig{file=PIC16F877/DiagrammaABlocchi.eps,width=1.0\textwidth}}\end{center}
\caption{\it{Diagramma a blocchi dell'architettura del microcontrollore PIC16F877~\cite{ManualePIC}.}}
\protect\label{DiagrammaABlocchi}
\end{figure}
\subsection{Pin per le funzioni di base}
Iniziamo la descrizione delle funzioni associate ai vari pin, a partire da
quelli che assicurano le funzioni basilari del microcontrollore:
alimentazione, clock ed inizializzazione. Questi pin devono essere
sempre connessi.
\begin{itemize}
\item{Alimentazione}: la tensione di riferimento per il
livello logico $0$ ($0~V$) \`e collegata ai pin 12 e 31, indicati 
con $V_{ss}$, 
mentre i pin 11 e 32, indicati con $V_{dd}$ vengono collegati
alla tensione di riferimento per il livello logico $1$ ($5~V$).
\item{Clock}: come per tutti i microprocessori \`e necessario avere un 
segnale di riferimento per mantenere la sincronia nell'esecuzione delle
operazioni. 
Nel caso del 16F877 \`e possibile derivare il segnale di clock da circuiti
costituiti da cristalli o da circuiti oscillanti a feedback basati
su resistenze, condensatore ed elementi attivi. Il clock pu\`o
avere varie frequenze di oscillazione fino ad un massimo di $20~MHz$.
Usualmente si realizza il circuito di clock utilizzando 
un quarzo che permette di ottenere una 
elevata stabilit\`a sia temporale che al variare della temperatura
ed alla stesso tempo offre una frequenza di oscillazione molto precisa. 
Il segnale generato dal quarzo  
viene connesso ai pin 13 e 14 (OSC1 ed OSC2) utilizzando il circuito
mostrato in figura~\ref{CircuitoClock}. 
\begin{figure}[h!]
\begin{center}\mbox{\epsfig{file=PIC16F877/Clock.eps,width=0.6\textwidth}}\end{center}
\caption{\it{Schema del circuito di clock del PIC16F877 realizzato con un cristallo (XTAL). In figura sono indicati i piedini OSC1 ed OSC2 a cui il circuito esterno \`e collegato~\cite{ManualePIC}.}}
\protect\label{CircuitoClock}
\end{figure}

Il tempo che intercorre tra due impulsi di clock successivi \`e
detto ciclo del clock. 
Il PIC16F877 esegue un'istruzione elementare, cio\`e un 
ciclo macchina, ogni quattro
cicli di clock e quindi, nell'ipotesi di utilizzare la massima frequenza
di clock, pu\`o eseguire un'istruzione elementare 
ogni $200~ns$. Questo microprocessore \`e quindi
capace di eseguire 5 milioni di operazioni elementari al secondo. Questo 
numero che sembra molto grande \`e in effetti piccolo rispetto 
alle prestazioni di un normale PC attuale che funziona a $2~GHz$ corrispondente
a 2 miliardi di cicli di clock al secondo.
% ma se l'oscillatore e' interno perche' deve essere collegato ?
% esistono microprocessori senza clock ? pag. 134 dice gran parte...
\item{Inizializzazione}: il pin 1 denominato $MCLR$ \`e utilizzato per 
inizializzare il microprocessore. Se questo pin viene connesso a massa il
microprocessore arresta l'esecuzione del programma ed esegue 
la routine di reset. Questa routine usualmente carica in tutti i 
registri i valori iniziali ed inizia ad eseguire il programma in memoria 
a partire dalla prima istruzione. Affinch\`e il microprocessore funzioni 
correttamente
questo pin deve quindi essere collegato a $5~V$. Esso \`e 
spesso collegato ad un pulsante di RESET che permette di mettere a massa 
temporaneamente il pin 1 provocando
una riinizializzazione del microcontrollore.
\end{itemize}
\subsection{Le porte del PIC16F877}\label{SezionePorte}
Con l'eccezione dei pin che 
assicurano le funzioni di base discusse nel paragrafo
precedente, tutti gli altri pin del microprocessore corrispondono 
ad ingressi o uscite digitali. Molti di essi hanno anche altri ruoli ma
questi saranno discussi pi\`u avanti. Tutti i pin di ingresso ed uscita 
del PIC16F877 
sono suddivisi in gruppi detti {\em porte}, 
in totale si hanno 5 porte indicate
oguna con una lettera: A, B, C, D ed E. La porta A comprende 6 pin, 
le porte B, C e D ne comprendono 8 mentre la porta E ne comprende 3. 
I pin appartenenti ad ogni 
porta sono numerati da 0 ad $n$ e quindi ogni pin viene indicato con una 
sigla che indica la porta ed il numero del pin in quella porta, ad esempio:
$RA3$ indica il pin 4 (la numerazione parte da 0) della porta A. 
\`E possibile individuare in 
figura~\ref{Integrato} i pin appartenenti alle varie porte ed in 
figura~\ref{DiagrammaABlocchi} 
la loro posizione nello schema a blocchi. 
Le sigle indicate
a fianco del nome del pin delle varie porte indicano le eventuali altre
funzioni associate al pin. In totale sono disponibili 33 pin di input/output.
Il grande numero di pin disponibili per ingressi ed uscite sono uno dei
punti di forza di questo particolare microcontrollore.
In effetti essi non sono sempre tutti disponibili poich\`e alcuni 
possono essere utilizzati per funzioni particolari associate ai moduli
interni del microprocessore oppure possono essere dedicati a connessioni 
con periferiche esterne, come ad esempio lo schermo o la tastiera
%. Ad esempio  Pic pro  
%i due pin dedicati al collegamento con la tastiera e lo schermo sono $PC6$ e 
%$PC7$. 

Tutti i pin delle porte sono configurabili come ingressi o uscite del 
microprocessore. 
%I dati in entrata o in uscita sono trasmessi in forma
%binaria come livelli di tensione corrispondenti ai livelli logici 
%1 o 0.
% inserire la descrizione del modello circuitale di una porta configurata
% inpu o in output
%Le caratteristiche elettriche dei pin delle porte sono riportate nelle
%specifiche del microprocessore. 
La struttura generale delle 5 porte \`e grosso modo la stessa. Ogni porta
\`e configurata utilizzando il {registro di direzione} dei dati. Questo
registro fa parte dei registri di stato discussi nella sezione~\ref{I/Oprogrammato:registridistato,interruptseDMA} di questo capitolo. Esso \`e indicato 
come  TRIS seguito dalla lettera che individua la porta. Ad esempio
TRISA \`e il registro di direzione dei dati che corrisponde alla porta A. 
Ogni bit di questo registro corrisponde ad un pin della porta, 
bit 0 al pin 0 e cos\`i via. 
Il valore di ogni bit del registro determina se il pin ad esso
corrispondente \`e utilizzato come ingresso o come uscita. Il valore 1 
configura il pin come ingresso ed il valore 0 lo configura come uscita.
Ad esempio se si assegna il valore 00000100
al registro TRISB il terzo pin della porta B (RB2) \`e 
configurato come ingresso mentre tutti gli altri come uscite.
Un pin che \`e configurato come ingresso \`e collegato
a massa tramite un circuito di alta impedenza, mentre quando \`e configurato
come uscita \`e collegato ad un circuito di latch. 

Ad ogni porta \`e associato anche un registro dati indicato con PORT seguito
dalla lettera che indica la porta, ad esempio PORTA \`e il registro
dati della porta A. Per ogni pin configurato 
come uscita il valore del bit del registro corrispondente determina il valore
inviato al pin. Viceversa per i pin configurati come ingressi
i valori dei bit corrispondenti sono uguali al valore alto o basso rivelato
sul pin. 

Cinque dei pin della porta A e tre dei pin della porta E sono configurabili
anche come ingressi analogici. Il registro denominato ADCCON1 permette
di definire quali dei sette pin sono utilizzati come ingressi analogici. 
I registri TRISA e TRISE controllano anche in modo analogico la configurazione
di input o output dei pin. Quindi, quando si utilizzano alcuni dei pin 
come ingressi analogici, \`e necessario impostare correttamente il valore di 
questi registri. Come vedremo in seguito gli ingressi analogici sono collegati
ad un convertitore analogico-digitale interno al microcontrollore, che 
sar\`a discusso in seguito.
% Descrizione dello schema circuitale di input/output della porta
\subsection{Le memorie}
Il microprocessore contiene tre tipi di memoria:
la memoria di programma di tipo FLASH, la memoria di dati volatile di tipo
RAM ed una seconda memoria di dati non volatile di tipo EEPROM.
Queste memorie utilizzano bus separati denominati Data Bus e Program
Bus rispettivamente mostrati in figura~\ref{DiagrammaABlocchi}. 
Le caratteristiche particolari 
di ogni memoria, descritte qui di seguito, sono determinate dal particolare 
tipo di funzione che essa svolge.
\begin{itemize}
\item{La memoria di programma}
\\
Il
``Program Counter'', il cui ruolo \`e descritto in sezione~\ref{Strutturainternadiunasemplicemacchina}, nel PIC16F877 
ha una profondit\`a pari a 13 bit. Esso \`e quindi
in grado di indirizzare $8000$ diversi indirizzi (per la precisione 8191).
La memoria di programma del 
PIC16F877, costituita da una memoria di tipo FLASH, 
ha quindi una dimensione pari a $8000$ parole di 14 bit, 
14 bit \`e anche la larghezza del bus di programma 
(in figura~\ref{DiagrammaABlocchi} si pu\`o vedere la connessione tra la memoria FLASH, il program counter e l'instruction register).
La memoria FLASH \`e una memoria non volatile ed elettricamente cancellabile.
L'organizzazione della memoria di programma \`e mostrata in 
figura~\ref{MemoriaFLASH}. Le locazioni di memoria da 0005h (``h'' indica
la notazione esadecimale) in poi
sono divise in quattro banchi di 2000 parole ciascuno. Questa struttura
viene sfruttata nella procedura di indirizzamento. 

Le locazioni di memoria 0000h (``reset vector'') e 
0004h (``interrupt vector'') contengono rispettivamente 
i puntatori alle routine 
che vengono eseguite al reset del microprocessore ed
alla ricezione di un interrupt.
\begin{figure}[h!]
\begin{center}\mbox{\epsfig{file=PIC16F877/MemoriaFLASH.eps,width=0.6\textwidth}}\end{center}
\caption{\it{Schema della memoria FLASH di programma~\cite{ManualePIC}.}}
\protect\label{MemoriaFLASH}
\end{figure}
Il programma che si vuole implementare 
viene normalmente scritto in assembler, C o Basic e viene quindi
tradotto in linguaggio macchina dai compilatori
appropriati. Il programma compilato deve poi essere scritto nella
memoria di programma. Tale operazione viene normalmente eseguita
utilizzando un dispositivo, detto ``programmer'', che permette di 
interfacciare un normale computer al microcontrollore. Esso 
\`e costituito da un circuiro dove il microcontrollore deve essere inserito 
e dal codice necessario a scrivere nella memoria FLASH. Questa procedura, che 
deve essere fatta ogni volta che si vuole caricare un nuovo programma, risulta
tuttavia piuttosto lenta. I microcontrollori della famiglia 
PIC16F87x permettono di velocizzare molto il caricamento del programma 
sfruttando la possibilit\`a che essi hanno
di autoprogrammarsi (cio\`e di scrivere in locazioni 
della medesima memoria di programma).
Con questi microcontrollori si pu\'o utilizzare un programma,
detto ``bootloader'', che risiede nella memoria di programma ed \`e capace di 
scriverla. Esso riceve le istruzioni di programma da un normale computer 
attraverso uno specifico pin di ingresso, le copia
nella memoria FLASH, ed inizia ad eseguire il programma stesso. 
Il bootloader parte ad ogni reset del microcontrollore e quindi
attende un determinato set di segnali sul pin dedicato alla comunicazione.
Se questi vengono ricevuti, il bootloader carica un nuovo programma, altrimenti
inizia ad eseguire il programma precedentemente caricato.

La programmazione fatta in questo modo risulta molto semplice e veloce e 
permette di non dovere spostare il microcontrollore dalla sua sede.
Si deve per\`o tenere conto del fatto 
che per poter utilizzare il ``bootloader'' 
\`e necessario per prima cosa caricarlo nella memoria
di programma. Tale operazione viene eseguita tuttavia una sola volta
utilizzando il ``programmer''. 
\begin{figure}[h!]
\begin{center}\mbox{\epsfig{file=PIC16F877/MemoriaRAM.eps,width=0.9\textwidth}}\end{center}
\caption{\it{Schema della memoria RAM. In figura si pu\'o notare la suddivisione in quattro banche di dimensione 128 byte ciascuna (ogni casella indica 1 byte). Le locazioni di memoria pi\'u basse di ogni banca sono dedicate ai registri speciali indicati in figura dalle varie sigle. Le locazioni di memoria pi\'u alte sono dedicate ai registri generici (indicati in figura come General purpose register). I numeri indicati in esadecimale accanto alle locazioni di memoria indicano il relativo indirizzo~\cite{ManualePIC}.}}
\protect\label{RegisterMap}
\end{figure}
Un piccolo effetto collaterale nell'utilizzo del ``bootloader'' \`e che 
una parte della memoria
FLASH corrispondente a 512 byte viene utilizzata dal bootloader e quindi
la dimensione dei programmi scrivibili nella memoria FLASH 
\`e corrispondentemente ridotta.
\item{La memoria RAM}
\\
Questa memoria, 
descritta in dettaglio in sezione~\ref{Memorieadaccessocasuale},
\`e utilizzata dalla CPU, dalle periferiche e dall'utente 
per le variabili di programma. Questo tipo di memoria \`e 
caratterizzata da una scrittura molto rapida ($\simeq~100~ns$) 
tuttavia le informazioni
in essa immagazzinate non vengono mantenute quando il microcontrollore
non \`e alimentato, cio\`e la memoria \`e volatile. 
Essa \`e suddivisa in quattro sezioni dette {\em banche} 
ognuna composta
da $128$ byte (ad esempio gli indirizzi della prima banca vanno da
00h a 7Fh). Le locazioni di memoria pi\`u basse di ogni banca 
sono riservate ai registri per le funzioni speciali che servono a definire
la configurazione del microcontrollore o ad istruirlo ad eseguire
determinate operazioni. Viceversa le locazioni di memoria
pi\`u alte sono a completa disposizione dell'utente.
In figura~\ref{RegisterMap} \`e mostrato
lo schema di organizzazione della memoria RAM in quattro banche e sono
indicati i registri dedicati ad uso speciale, a cui \`e assegnato un nome
mnemonico che aiuti a ricordarne la funzione, ed i registri ad uso generale.
Si possono ad esempio individuare i registri speciali TRISA o ADCCON1 
le cui funzioni sono state precedentemente discusse.
%Un esempio di un registro dedicato ad una funzione specifica \`e quello
%indicato con ADCCON0, scrivere il dato 0x4 in questo registro 
%indica al convertitore analogico digitale interno
%al microprocessore di iniziare la conversione.
Quando si programma in 
un linguaggio diverso dal linguaggio macchina \`e il compilatore che si 
occupa della gestione della memoria RAM.
\item{La memoria EEPROM}
\\
Il microprocessore contiene un blocco di 256 byte di memoria di tipo EEPROM.
Questa \`e elettricamente cancellabile, riscrivibile e non volatile 
quindi verr\`a utilizzata per tutti i dati che non devono essere persi
quando il microcontrollore viene spento.
La richiesta di scrittura di un byte in questa memoria procede attraverso 
l'operazione di cancellazione e quindi riscrittura del byte. 
Un ciclo di scrittura viene eseguito in circa $4~ms$.
% velocita' di scrittura/lettura pg 41 specifiche D122 ?
\end{itemize}
\subsection{Le periferiche interne}
In questa sezione sono brevemente descritte le funzionalit\`a offerte
dalle periferiche interne del microprocessore ed il modo per utilizzarle. 
La descrizione non \`e esaustiva ma si propone soltanto di dare un'idea 
delle potenzialit\`a del microprocessore.
Le periferiche sono:
\begin{itemize}
\item tre contatori indicati come, timer 0 1 e 2;
\item un convertitore analogico-digitale (CAN) a 10 bits;
\item un modulo per la generazione di impulsi di periodo regolabile (PWM);
\item un modulo per la comunicazione seriale sincrona;
\item un modulo USTART;
\item un modulo di comunicazione parallela;
\end{itemize}
Se si analizza lo schema dell'architettura del microprocessore PIC16F877 mostrato
in figura\ref{DiagrammaABlocchi} si possono facilmente individuare le varie
periferiche nella parte inferiore del disegno connesse al bus dei
dati. Le caratteristiche principali di queste periferiche vengono
descritte qui di seguito. 
\begin{itemize}
\item{I contatori}
\\
I tre contatori (o timer), indicati in figura come TIMER0, TIMER1, TIMER2,
possono essere incrementati ogni volta che 
viene generato un determinato numero di cicli dal segnale di clock 
del microprocessore. Il numero di cicli 
necessari per incrementare di una unit\`a i contatori pu\`o essere
definito attraverso un opportuno registro.
Considerando che un ciclo di clock pu\`o corrispondere fino ad un 
minimo di $50~ns$, si capisce che i contatori possono essere utilizzati
per eseguire misure di tempo piuttosto precise.

I timer 0 e 2 sono contatori a 8 bit mentre il timer 1 \`e a 16 bit.
Questo significa che i primi due possono contare fino ad un massimo di 255 
conteggi mentre l'ultimo fino ad un massimo di 65535 conteggi.
I timer 0 ed 1 possono essere incrementati
anche attraverso un segnale esterno collegato
al pin RA4. Tre registri denominati OPTION\_REG, T1CON e T2CON permettono
di configurare tutte le opzioni dei tre contatori. 

Ogni volta che uno dei contatori passa dal massimo numero registrabile
a 0 pu\`o essere generato un segnale di interrupt. Questo segnale permette 
quindi di contare quante volte il contatore ha ricominciato a contare 
da 0. Utilizzando, ad esempio, una variabile che viene incrementata ogni 
volta che l'interrupt \`e generato, si pu\`o estendere l'intervallo
di conteggi eseguibili e quindi gli intervalli di tempo misurabili.

%Il TIMER2 \`e un contatore speciale perch\`e collegato al modulo CCP ...
\item{Il convertitore analogico-digitale}
\\
Il convertitore analogico-digitale (ADC) permette di convertire una 
tensione analogica in un valore numerico binario. La tensione in
ingresso all'ADC viene letta da uno degli otto input analogici descritti
nella sezione~\ref{SezionePorte}. Tre bit del registro ADCON0 permettono
di selezionare quale di questi input \`e collegato all'ADC, in questo
modo \`e possibile 
misurare fino ad otto diverse grandezze fisiche con un solo 
ADC. Lo schema del circuito di ingresso del convertitore 
analogico digitale \`e mostrato in figura~\ref{ADC}.
\begin{figure}[h]
\begin{center}\mbox{\epsfig{file=PIC16F877/ADC.eps,width=0.6\textwidth}}\end{center}
\caption{\it{Schema del circuito di ingresso dell'ADC. In figura sono indicati gli otto possibili ingressi dell'ADC ed il circuito che permette di definire gli estremi dell'intervallo di tensioni convertibili~\cite{ManualePIC}.}}
\protect\label{ADC}
\end{figure}
L'ingresso analogico selezionato \`e collegato al
condensatore di un circuito di sample-and-hold. Questo circuito 
permette di caricare il condensatore al valore della tensione
in ingresso e di mantenere il valore di tensione pressoch\`e costante
durante il tempo necessario ad eseguire la conversione. L'uscita
del circuito di sample-and-hold \`e collegata all'ingresso del convertitore 
che fornisce in uscita il valore digitale
attraverso una serie di approssimazioni 
successive. La tensione \`e cos\`i convertita in un numero a 10 bit.

Per fare in modo che il convertitore funzioni correttamente 
\`e necessario che il condensatore di ingresso abbia il 
tempo necessario per caricarsi al valore di tensione applicata e che 
in seguito il convertitore abbia il tempo necessario ad effettuare la 
conversione.
Il tempo necessario affinch\`e queste due operazioni siano eseguite \`e 
pari a qualche centinaia di microsecondi.
% aggiungere considerazioni riguardo ai tempi di conversione vedi specifiche
La risoluzione dell'ADC, pari a 10
bit, permette di raggiungere, su un intervallo $0-5~V$, una precisione di
$5~mV$. I valori di riferimento per le tensioni minima e massima (gli
estremi dell'intervallo di conversione) sono programmabili.
\item{Il modulo CCP}
\\
Il modulo CCP offre tre tipi di funzionalit\`a: Capture, Compare o PWM
(Pulse Width Modulation).
Quando il modulo funziona in modo ``Capture'' il valore del timer1 viene
letto ogni volta che un determinato evento, definito dall'utente, si realizza.
Il tipo di evento pu\`o essere il fronte di discesa o di salita 
di un segnale o l'occorrenza di un predeterminato numero di fronti di salita. Il tipo di evento 
\`e selezionato attraverso il valore di un registro dedicato. 
Il funzionamento nel modo ``Compare'' permette di confrontare continuamente 
il valore dei registri CCPR1H e CCPR1L 
con il valore del contatore 1 memorizzato
nei registri TMR1L e TMR1H (vedi figura~\ref{RegisterMap}). 
Ogni volta che i valori sono uguali 
il pin RC2/CCP1 viene portato ad un valore definito dall'utente. 
L'utente pu\`o scegliere di portare il pin ad un valore alto, basso o di
lasciarlo invariato. Anche in questo caso la scelta dell'azione da eseguire
viene definita dal valore di un apposito registro.
L'ultima modalit\`a di funzionamento \`e quella come generatore di impulsi 
(PWM) di periodo e duty-cycle programmabili con una risoluzione fino a 10 bit. 
Questo modulo \`e realizzato in modo tale da permettere
di generare treni di impulsi in modo molto semplice senza sovraccaricare il
microprocessore.
\item{I moduli per la comunicazione}
\\
Esistono tre moduli dedicati alla comunicazione tra il microprocessore 
ed il mondo esterno. 
Due di questi moduli utilizzano la comunicazione seriale, trasmettono cio\`e 
i dati su una sola linea, e sono il modulo MSSP (Master
Synchronous Serial Port) ed il modulo USART  (addressable Universal 
Synchronous Asynchronous Receiver Transmitter). 
Queste periferiche permettono di comunicare con 
altri microcontrollori o con periferiche esterne quali 
shift registers, driver per schermi, convertitori A/D o D/A. 
Il modulo USART pu\`o essere configurato sia per 
utilizzare un protocollo di comunicazione ``full duplex asincrono'' sia 
``half duplex sincrono''. 
Esiste poi un terzo modulo che permette di utilizzare la porta D come una
porta parallela che pu\`o essere letta e scritta in modo asincrono. La porta
D utilizzata in questo modo pu\`o essere direttamente interfacciata ad un 
bus a 8 bit di un microprocessore esterno.
\end{itemize}
\subsection{Gli interrupt}
Nella sezione 3.3.4 \`e stata discussa 
la procedura generale che porta alla generazione di un interrupt.
Il microcontrollore PIC16F877 \`e capace di generare interrupts innescati
da 14 possibili sorgenti. Ogni volta che si verifica un interrupt il
PIC interrompe l'esecuzione del programma e salta 
alla locazione di memoria 0x04 nella memoria di programma a partire
dalla quale si trova l'Interrupt Service Routine (ISR). Il tempo 
che trascorre tra il verificarsi dell'evento collegato all'interrupt 
e l'istante in cui inizia l'esecuzione dell'istruzione alla locazione 0x04
\`e detto ``latenza di interrupt''. Nel PIC16F877 questa \`e pari a 
3-4 cicli macchina a seconda del tipo di interrupt e del punto di
esecuzione del programma al momento della ricezione dell'interrupt.

Tra tutte le possibili sorgenti di interrupt quelle che sono utilizzate pi\`u 
frequentemente sono generate da:
\begin{itemize}
\item timer 0 e timer 1 quando si ha la transizione dal massimo 
conteggio raggiungibile, 255 per il timer 0, 65535 per il timer 1,  allo zero. 
Questo interrupt \`e, ad esempio, utilizzato per realizzare orologi che 
misurino intervalli di tempo 
maggiori di quelli ottenibili da un contatore semplice;
\item un fronte di salita o discesa di un segnale collegato al pin RB0.
Questo interrupt pu\`o ad esempio permettere di rendere sensibile il
microprocessore ad un'azione su di un modulo esterno come una tastiera o 
un pulsanteò
\item la fine della conversione eseguita dal convertitore analogico 
digitale;
\item la presenza di un segnale sulla porta di comunicazione seriale o su quella parallela.
\end{itemize}
Ogni sorgente di interrupt pu\`o essere singolarmente abilitata o disabilitata.


