Sei sulla pagina 1di 6

TEORIA MHZ RISORSE SPECIALE PRATICA

Quinta parte
n° 257 - Novembre 2006

MikroC
Realizzazione di un timer
digitale programmabile

Sesta parte
n° 258 - Dicembre 2006
Uso delle interfacce seriali

Settima parte
n° 259 - Gennaio 2007
by Example
Interfacce SPI, I2C e 1-Wire

molto semplice per collegare un microcontrol-


U no dei metodi più utilizzati e
versatili per collegare sistemi
embedded a computer host
lore ad un PC al fine di scambiare dati e coman-
di. Questa possibilità è utile nei casi in cui il
microcontrollore è collocato in una posizione
remota (e quindi può eseguire delle operazioni
consiste nell’utilizzo
in un luogo distante dal PC), oppure per esegui-
dell’interfaccia RS-232. L’utilizzo re parte delle elaborazioni sul PC e scambiare i
di questo collegamento seriale, risultati o dei comandi.
84
Negli esempi che verranno presentati di seguito
per scambiare dati e comandi in
Teoria

sarà utilizzato lo schema riportato in Figura 1.


maniera molto semplice e robusta, Come si può vedere è stato utilizzato un
PIC16F876 ed un MAX232, un classico compo-
sarà l’oggetto di questa puntata. nente che svolge la funzione di traslare i livelli
Verranno presentati diversi da quelli compresi tra 0 e 5V del PIC a quelli
previsti dallo standard RS-232, che sono ben più
esempi e mostrato come
alti. In alcuni degli esempi presentati i pin della
implementare un semplice porta B saranno utilizzati come semplici I/O
collegamento tra un PIC e un PC digitali, in altri sarà collegato ad essi un display
LCD intelligente 16x2 .
utilizzando le librerie del MikroC.
SEGNALAZIONE DI EVENTI
Il primo esempio mostra come instaurare una
semplice comunicazione seriale tra il PIC ed il
L’interfaccia seriale RS-232 è uno standard estre- PC. In particolare il programma mostrato nel
mamente diffuso. Nonostante le basse velocità listato 1 invia al PC lo stato della porta B (in cui
gestibili, essa infatti risulta adeguata alla mag- tutti i pin sono configurati come ingressi) ogni
gior parte delle esigenze tipiche dell’automazio- volta che rivela una variazione:
ne e del controllo industriale, o del debug o
Listato 1
programmazione dei sistemi embedded. Essa
void main() {
ha inoltre il vantaggio di essere molto semplice
char pb, mpb;
ed economica e di garantire un’ottima immuni-
tà al rumore ed ai disturbi, grazie all’impiego di
FARE ELETTRONICA - DICEMBRE 2006

PORTB=0;
tensioni di segnalazione piuttosto alte (circa
TRISB=0xFF; // PORTB[0-7]: ingressi
12V). Nella versione più semplice, l’interfaccia è
costituita da soli tre fili: TX (trasmissione), RX
// Inizializzazione
(ricezione) e massa. I dati sono trasmessi serial-
Usart_Init(2400);
mente in maniera asincrona, cioè senza l’uso di
pb=0;
un clock. Per rendere possibile questo è neces-
mpb=0;
sario che il ricevitore ed il trasmettitore utilizzi-
while(1) {
no lo stesso formato di dati (velocità di trasmis-
pb=PORTB;
sione, numero e tipologia di bit).
if (pb!=mpb)
L’interfaccia RS-232 costituisce un metodo
Uso
dell’interfaccia
seriale di Antonio Di Stefano

85

Teoria
Figura 1 Schema utilizzato negli esempi

Usart_Write(pb); Va notato che le funzioni della libreria USART,


Delay_ms(10); come suggerisce il nome, utilizzano la periferica
mpb=pb; USART presente in alcuni modelli di PIC per
} gestire la ricezione e la trasmissione seriale full
} duplex. Questo implica che i pin destinati alla
comunicazione seriale sono quelli predisposti
Come si può vedere, grazie alle librerie del per tale funzione (RC6 ed RC7 sul PIC utilizzato),
MikroC la gestione dell’interfaccia è estrema- e che non è possibile utilizzare PIC privi di que-
mente semplice. È stata utilizzata la funzione sta periferica con queste funzioni. Questa limita-
Usart_Init() per inizializzare la porta, specifican- zione può essere superata comunque, come
FARE ELETTRONICA - DICEMBRE 2006

do la velocità desiderata in baud. In questo caso verrà mostrato di seguito.


la velocità scelta è di 2400 bit al secondo (con 8 Per ricevere e trasmettere i dati seriali sul PC è
bit di dati 1 bit di start, 1 bit di stop e nessuna necessario utilizzare un programma “terminale”
parità). Queste stesse impostazioni dovranno apposito. Tra i tanti disponibili (tra cui anche
essere utilizzate per la porta del PC. La funzione l’HyperTerminal di Windows) risulta molto
Usart_Write() è utilizzata per trasmettere un comodo L’USART Terminal incluso nell’ambiente
byte. In pratica il ciclo principale controlla se ci di sviluppo del MikroC, attivabile dal menu
sono cambiamenti dello stato della porta B, ed Tools. In Figura 2 è visibile la finestra del pro-
in tal caso invia il nuovo valore al PC sotto forma gramma con le impostazioni da utilizzare.
di byte. La frequenza del ciclo è di circa 10ms. Come si può vedere, oltre ai parametri di
TEORIA MHZ RISORSE SPECIALE PRATICA

Sesta parte MikroC by Example: Uso dell’interfaccia seriale

connessione, nella finestra sono presenti altre e lo memorizza in un buffer interno). Quando
opzioni, tra cui quella che permette di selezionare è stato ricevuto un carattere la funzione resti-
la modalità di visualizzazione dei dati ricevuti. In tuisce un valore diverso da zero (che equivale
questo caso l’impostazione scelta è Hex, in modo ad una condizione vera). Una volta letto il
da potere leggere il valore binario inviato. Negli carattere (con la funzione Usart_Read), que-
altri esempi sarà utilizzata la modalità ASCII, dal sto viene elaborato secondo l’algoritmo
momento che sarà scambiato del testo. descritto prima (controllando che si tratti
effettivamente di una lettera dell’alfabeto
CIFRATURA REMOTA maiuscola o minuscola, grazie alle funzione
Per mostrare come la comunicazione possa isupper e islower della libreria standard
avvenire anche nell’altra direzione, e si possa istau- ctype.h), ed inviato di nuovo al PC. Il risulta-
rare un primo esempio di colloquio tra il PC ed il to sarà che se inviamo la parola “Ciao”, otter-
PIC, è riportato nel listato 2 il codice di un pro- remo come risposta “Pvnb”. Se re-inviamo
gramma che riceve un testo dal PC e lo cifra secon- quest’ultima otterremo di nuovo la versione
do il codice ROT13, utilizzato spesso su Internet in chiaro. Come si può notare già da questo
come semplice forma di cifratura del testo. Il codi- esempio, la comunicazione tramite RS-232 è
86
ce consiste in pratica nel ruotare l’alfabeto anglo- orientata e ordinata a singoli byte. Per scambia-
sassone (26 lettere) di 13 posti, in questo modo A
Teoria

re messaggi più complessi è necessario ideare


diventa N, la Z la M e così via. L’algoritmo è rever- o usare dei protocolli che definiscano la strut-
sibile, e quindi quando viene applicato ad un testo tura dei messaggi, come mostrato di seguito.
già cifrato, lo riporta in chiaro.
CONTROLLO DI UN DISPLAY DA PC
Listato 2 Supponiamo di volere inviare da PC il testo da
/* ROT13 remoto */ visualizzare su un display LCD. Il testo potrebbe
essere generato da un apposito software
void main() { oppure essere utilizzato soltanto come mes-
unsigned short i; saggio remoto. L’utilizzo della porta RS-232
costituisce una buona soluzione. Utilizzando
Usart_Init(2400); lo schema di Figura 1, ed il programma
while (1) { mostrato nel listato 3 è possibile ottenere in
// Se riceve un carattere maniera molto semplice quanto detto. In pra-
if (Usart_Data_Ready()) { tica il programma consente di inviare dei
// Legge il dato ricevuto comandi e delle stringhe al display in modo
i = Usart_Read(); da controllare il testo visualizzato. Inviando la
// Rotazione maiuscole stringa “C” è possibile cancellare il testo visua-
if (isupper(i)) lizzato, inviando la stringa “T x Abcd” è possi-
i=((i-’A’)+13)%26+’A’; bile scrivere la stringa “Abcd” nella riga x (che
// Rotazione minuscole
if (islower(i))
i=((i-’a’)+13)%26+’a’;
FARE ELETTRONICA - DICEMBRE 2006

// Invio risultato
Usart_Write(i);
}
}
}

A differenza di prima è stata utilizzata la fun-


zione Usart_Data_Ready() per controllare se è
stato ricevuto un carattere (la periferica USART
Figura 2 L’USART Terminal del MikroC con i parametri di collegamento
lo riceve indipendentemente dal programma,
può essere 1 o 2). Inviando la stringa “S x” è Lcd_Init(&PORTB);
possibile spegnere o accendere il cursore e
cambiarne la forma (0=spento, 1=linea, // Init. variabili
2=quadratino lampeggiante). Ogni stringa stringa=0;
deve terminare con un “a capo” (codici ASCII i=0;
0x0D e 0x0A). Questo serve al programma for(j=0; j<32; j++)
per individuare la fine della stringa e per ini- buf[0];
ziarne l’elaborazione (ricordarsi di abilitare le
opzioni Append CR ed LF nel Terminal). while(1) {

Listato 3 // Attesa ricezione stringa


/* Controllo display remoto if ((Usart_Data_Ready())&&(!stringa)) {
via seriale */ buf[i] = Usart_Read();
void SendString(char *); if (buf[i]==’\n’) {
stringa=1;
void main() { }
i++;
87
char buf[32], i, j, stringa;

Teoria
}
PORTB=0;
TRISB=0; // Elaborazione stringa
if (stringa) {
Usart_Init(2400); switch(buf[0]) {

Scheda easyPIC4
La rivoluzionaria scheda
di sviluppo per PICmicro
✔ Programmatore USB2.0 on-board con ICD
✔ Tastiera a 32 tasti
✔ 32 LED per il monitoraggio degli I/O
✔ 4 cifre LED a 7 segmenti
✔ Predisposizione per moduli LCD alfanumerici
✔ Predisposizione per moduli LCD grafici
✔ Predisposizione per comunicazione RS232
FARE ELETTRONICA - DICEMBRE 2006

✔ Predisposizione per tastiera PS2


✔ Predisposizione per sensore di temperatura DS1820
✔ Supporto per tutte le famiglie PIC (anche PIC10F)*
✔ Predisposizione per comunicazione USB
✔ Alimentazione esterna o via USB
✔ Fornita con 16F877
Codice MIP 258087 ✔ Disponibile con o senza display

Ordinala subito su www.farelettronica.com oppure telefona allo 02.66504755


TEORIA MHZ RISORSE SPECIALE PRATICA

Sesta parte MikroC by Example: Uso dell’interfaccia seriale

case ‘C’: suo interno si possono distinguere due parti: una


Lcd_Cmd(LCD_CLEAR); destinata alla ricezione delle stringhe, e l’altra alla
SendString(“Ok\r\n”); loro elaborazione. La prima attende l’arrivo di
break; nuovi caratteri, li riceve e li accoda nel buffer
apposito del programma (buf[…]). Quando
case ‘T’: viene rilevato un carattere di “a capo” la stringa
buf[20]=’\0’; è completa, e per indicarlo viene portata a 1 la
buf[i-2]=’\0’; variabile “stringa”. In questa situazione verrà ese-
if (buf[2]==’1’) guita la seconda parte del programma, e non più
Lcd_Out(1, 1, (buf+4)); la prima. Qui viene controllato se il primo carat-
else tere è un comando valido (cioè una “C”, una “T”
Lcd_Out(2, 1, (buf+4)); o una “S”), ed eseguite le relative funzioni. Va
SendString(“Ok\r\n”); notato che il testo inviato si trova nell’array
break; buf[…], nell’ordine in cui è stato inviato, è possi-
bile quindi estrarne i vari campi ed utilizzarli.
case ‘S’: Ogni volte che viene eseguita una delle funzioni
88
if (buf[2]==’0’) previste viene inviato al PC un “Ok” come con-
ferma. Se non viene riconosciuto un comando
Teoria

Lcd_Cmd(LCD_CURSOR_OFF);
if (buf[2]==’1’) valido viene inviato un “?!?”. Per inviare queste
Lcd_Cmd(LCD_UNDERLINE_ON); stringhe è stata scritta una funzione apposita che
if (buf[2]==’2’) non fa altro che inviare sequenzialmente tutti i
Lcd_Cmd(LCD_BLINK_CURSOR_ON); byte che compongono la stringa, con la funzione
SendString(“Ok\r\n”); Usart_Write(). Notare che la scansione della strin-
break; ga si arresta in corrispondenza del terminatore,
cioè il valore binario 0x00.
default:
SendString(“?!?\r\n”); RICEZIONE CON INTERRUZIONI
} In molti casi può essere utile rendere la ricezione
delle stringhe seriali asincrona ed indipendente
for(j=0; j<32; j++) dal flusso principale del programma. Questo
buf[0]; soprattutto perché la comunicazione via RS-
stringa=0; 232 è per sua natura asincrona ed imprevedi-
i=0; bile, ed una gestione non immediata potrebbe
} portare alla perdita di dati. Si può ottenere
} quanto detto utilizzando le funzioni di libreria
} del MikroC, con qualche piccolo accorgimento.
Nel listato 4 è mostrato come svolgere la fun-
void SendString(char *str) zione di ricezione delle stringhe nella routine
{ d’interruzione.
int n;
FARE ELETTRONICA - DICEMBRE 2006

Listato 4
n=0; /* Controllo seriale remoto
while(str[n]) { UART HW con int. */
Usart_Write(str[n]); #define MAX_LEN 32
n++;
} char stringa, bpnt;
} char buf[MAX_LEN];

Dopo una prima inizializzazione della UART, del void SendString(char *);
display e delle variabili, inizia il loop principale. Al char Hex2Dec(char *);
void Dec2Hex(char, char *); funzioni disponibili sono quasi le stesse, anche
... il loro uso richiede una più accurata pianifica-
void main() { zione dei tempi del programma (che deve fer-
… marsi ad attendere l’arrivo dei caratteri, e non
Usart_Init(2400); può gestire la comunicazione in full duplex).
// Set RCIE Nel listato 5 è mostrato un esempio imple-
PIE1|=0x20; mentato in versione “software”:
// Set GIE e PEIE
INTCON|=0xC0; Listato 5
… /* ROT13 remoto con
while(1) { UART software */
void main() {
if (stringa) { unsigned short ro = 0, *recOK, i;

switch(buf[0]) { recOK = &ro;


case ‘W’: Soft_Uart_Init(PORTA, 0, 1, 2400, 0);
89
}

Teoria
} while(1) {
… do {
} i = Soft_Uart_Read(recOK);
} while (*recOK);
interrupt()
{ if (isupper(i))
if (!stringa) { i=((i-’A’)+13)%26+’A’;
buf[bpnt] = Usart_Read(); if (islower(i))
if ((buf[bpnt]==’\n’)|| i=((i-’a’)+13)%26+’a’;
(bpnt==MAX_LEN-1)) { Soft_Uart_Write(i);
stringa=1; }
} }
bpnt++;
} Notare che i piedini di comunicazione specifi-
} cati sono RA0 ed RA1 invece di RC6 ed RC7,
questo rende possibile riscrivere i programmi
In pratica il codice è rimasto quasi invariato, presentati prima anche per PIC privi di UART,
tranne per il fatto che sono state attivate le quale il 16F84.
interruzioni associate alla ricezione dei singoli
caratteri, e la funzione di ricezione stringhe è CONCLUSIONI
stata confinata nella routine d’interruzione. Si Va ricordato che le routine mostrate possono
può notare anche che la comunicazione tra le essere provate anche su PC privi di porta seria-
due routine avviene ancora tramite la variabile le, utilizzando un adattatore USB-RS232
FARE ELETTRONICA - DICEMBRE 2006

“stringa”, che questa volta però è stata dichia- (ricordarsi di settare il numero corretto di
rata come globale. porta COM). Nella prossima puntata si conti-
nuerà a parlare di protocolli seriali, in partico-
SOFTWARE UART lare di SPI, I2C e 1-Wire, utilizzati per comuni-
Se il PIC utilizzato non dispone di una UART care con dispositivi quali memorie EEPROM,
integrata è comunque possibile implementare timer, sensori di temperatura, e tanto altro.
una comunicazione seriale. Questo grazie alle Verrà mostrato come usare le routine di libre-
routine della libreria Software_Uart del ria e come comunicare con questi dispositivi.
MikroC, che emulano il dispositivo via softwa-
re utilizzando due qualsiasi piedini di I/O. Le Codice MIP 258084