Gestione di una connessione RS232Data di pubblicazione: 17-10-2003 | Versione Italiana | (No English Version) Parole chiave: - PIC - |
Analizzando in questa lezione come sia possibile dotare il PIC16F84A di una interfaccia RS232 per
collegarlo alla porta seriale del nostro PC.
L'applicazione d'esempio che andremo a realizzare utilizza il circuito per la gestione di
un display LCD presentato nella lezione 8 a cui aggiungeremo la sezione RS232 per realizzare
una sorta di miniterminale RS232.
In pratica con il nostro circuito d'esempio potremo visualizzare su display LCD i caratteri ASCII
trasmessi dal nostro PC su una qualsiasi porta seriale tramite un normale emulatore di terminale
tipo Hyperterminal (su Windows 95/98/ME/2000/XP), Telix (su MS/DOS) o Minicom (su Linux).
Vediamo subito lo schema elettrico riportato nella figura seguente:
Come potete vedere la base del circuito che andremo a realizzare � identica a quella del passo
precedente con la sola aggiunta del circuito integrato U3, del connettore a vaschetta DB9 per
il collegamento alla porta seriale del PC ed una manciata di componenti accessori.
L'integrato U3, un MAX232 prodotto dalla Maxim (vedi datasheet su http://www.maxim-ic.com), si occupa
di convertire i segnali RS232 dai +/-12 volt necessari per trasmettere e ricevere dati sulla porta
seriale ai 0/5 volt TTL gestibili direttamente dalle porte del PIC.
Ma vediamo in dettaglio come funziona la comunicazione seriale in RS232.
Cos'� e a cosa serve l'RS232
Lo standard RS232 definisce una serie di specifiche per la trasmissione seriale di dati tra
due dispositivi denominati DTE (Data Terminal Equipment) e DCE (Data Communication Equipment).
Come si pu� vagamente intuire dal nome, il Data Communication Equipment � un dispositivo
che si occupa di gestire una comunicazione dati mentre il Data Terminal Equipment � un
dispositivo che si occupa di generare o ricevere dati.
In pratica l'RS232 � stata creata per connettere tra loro un terminale dati
(nel nostro caso un computer) con un modem per la trasmissione a distanza dei dati generati.
Per avere una connessione tra due computer � quindi necessario disporre di quattro dispositivi
come visibile in figura: un computer (DTE) collegato al suo modem (DCE) ed un altro modem (DCE)
collegato al suo computer (DTE). In questo modo qualsiasi dato generato dal primo computer e
trasmesso tramite RS232 al relativo modem verr� trasmesso da questo al modem remoto che a sua
volta provveder� ad inviarlo al suo computer tramite RS232. Lo stesso vale per il percorso a ritroso.
Per usare la RS232 per collegare tra loro due computer vicini senza interporre tra loro alcun
modem dobbiamo simulare in qualche modo le connessioni intermedie realizzando un cavo NULL MODEM o
cavo invertente, ovvero un cavo in grado di far scambiare direttamente tra loro i segnali dai due
DTE come se tra loro ci fossero effettivamente i DCE.
Per connettere il PC al nostro circuito simuleremo invece direttamente un DCE facendo
credere al PC di essere collegato ad un modem. Prima di fare questo diamo uno sguardo in
dettaglio al principio di funzionamento di una comunicazione seriale.
La comunicazione seriale asincrona
Per consentire la trasmissione di dati tra il PC ed il modem, lo standard RS232 definisce una serie
di specifiche elettriche e meccaniche. Una di queste riguarda il tipo di comunicazione seriale che
si vuole implementare che pu� essere sincrona o asincrona.
Nel nostro caso analizzeremo solo la comunicazione seriale asincrona ignorando completamente
quella sincrona in quanto pi� complessa e non disponibile sui normali PC.
Una comunicazione seriale consiste in genere nella trasmissione e ricezione di dati da un
punto ad un altro usando una sola linea elettrica. In pratica se desideriamo trasmettere un
intero byte dobbiamo prendere ogni singolo bit in esso contenuto ed inviarlo in sequenza sulla
stessa linea elettrica, un p� come avviene per la trasmissione in codice morse. La differenza
sostanziale st� nel fatto che a generare e ricevere dati non c'� il telegrafista ma un computer
per cui le velocit� di trasmissione raggiungibili sono molto superiori.
Facciamo subito un esempio pratico e vediamo come fa un PC a trasmettere, ad esempio,
il carattere A usando la RS232.
Non � necessario ovviamente realizzare gli esempi riportati di seguito in quanto
presuppongono l'uso di una coppia di PC ed un oscilloscopio non sempre disponibili nei
nostri mini-laboratori da hobbysta. Per comprendere il funzionamento di quanto esposto
� sufficiente fare riferimento alle figure a corredo.
Se prendiamo una coppia di fili e colleghiamo tra loro le porte seriali di due PC
(che denomineremo PC trasmittente e PC ricevente) secondo lo schema riportato in figura:
otterremo la pi� semplice delle connessioni in RS232.
La linea Transmit Data (TXD) presente sul pin 3 del connettore DB9 maschio di cui il
vostro PC � dotato � connessa alla linea Receive Data (RXD) presente sul pin 2 del secondo PC.
Le masse (GND) presenti sul pin 5 di entrambe i PC sono connesse tra loro.
Per osservare i segnali generati dal PC trasmittente durante la trasmissione seriale
colleghiamo tra la linea TXD e la linea GND un oscilloscopio e lanciamo in esecuzione
su entrambe i PC un programma di emulazione terminale (tipo Hyperterminal o simili).
Configuriamo le porte seriali di entrambe i PC a 9600 baud, 8 data bit, 1 stop bit,
no parity e disabilitiamo il controllo di flusso (handshake) sia hardware che xon/xoff.
In questo stato qualsiasi cosa digiteremo sul PC trasmittente verr� inviata immediatamente
sulla porta seriale. Assicuriamoci inoltre che il programma di emulazione terminale scelto
sia opportunamente configurato per usare la porta seriale su cui siamo connessi (COM1 o COM2).
Proviamo a digitare la lettera A maiuscola e verifichiamo se � stata correttamente ricevuta
sul PC ricevente. Fatto questo controllo andiamo a vedere sull'oscilloscopio che tipo di
segnali sono stati generati per effettuare la trasmissione.
Quando non c'� nessuna trasmissione in corso la tensione sulla linea TXD � di -12 volt
corrispondente alla condizione logica 1. Per indicare al PC ricevente che la trasmissione
ha inizio, il PC trasmittente porta a +12 volt la linea TXD per un tempo pari all'inverso
della frequenza di trasmissione ovvero al tempo di trasmissione di un singolo bit.
Nel nostro caso, avendo scelto di trasmettere a 9600 bit per secondo, la tensione di
alimentazione rimar� a +12 volt per: 1/9600=0.104 mS.
Questo segnale viene denominato START BIT ed � sempre presente all'inizio di
trasmissione di ogni singolo byte. Dopo lo start bit vengono trasmessi in sequenza
gli otto bit componenti il codice ASCII del carattere trasmesso partendo dal bit
meno significativo. Nel nostro caso la lettera A maiuscola corrisponde al valore
binario 01000001 per cui la sequenza di trasmissione sar� la seguente:
Una volta trasmesso l'ottavo bit (bit 7), il PC aggiunge automaticamente un ultimo
bit a 1 denominato STOP BIT ad indicare l'avvenuta trasmissione dell'intero byte.
La stessa sequenza viene ripetuta per ogni byte trasmesso sulla linea.
Aggiungendo al nostro cavo seriale una connessione tra il pin TXD (pin 3) del PC
ricevente con il pin RXD (pin 2) del PC trasmittente, potremo effettuare una
trasmissione RS232 bidirezionale. Il cavo che abbiamo ottenuto � il pi� semplice
cavo NULL MODEM in grado di mettere in collegamento tra loro due DTE.
Come collegare il nostro circuito d'esempio
Come accennato prima il nostro circuito d'esempio simula un dispositivo DCE.
Questo significa che il cavo che dovremo realizzare non dovr� essere di tipo
NULL MODEM o INVERTENTE ma DRITTO ovvero con i pin numerati allo stesso modo
connessi tra loro. Questo tipo di cavo � identico a quelli che vengono usati
per connettere al PC un modem esterno.
Dato che i dispositivi DTE sono sempre dotati di connettore DB9 maschio, il
nostro circuito, essendo un DCE, avr� un connettore DB9 femmina la cui piedinature
� riportata nella seguente tabella:
In alcuni casi i PC sono dotati di vecchi connettori DB25 anzich� DB9 per cui
occorre far riferimento alla seguente tabella per ricavare le corrette equivalenze:
Il cavo di collegamento tra il PC ed il nostro circuito dovr� essere intestato
a sua volta con un connettore femmina da un lato per poter essere inserito nella
seriale del PC ed un connettore maschio dall'altro per poter essere inserito nel
connettore del nostro circuito di prova. I collegamenti interni al cavo da usare
sono riportati nella seguente figura.
Funzionamento del MAX232
Come accennato prima, nel nostro circuito d'esempio useremo un driver RS232, ovvero un integrato
in grado di convertire i segnali a +/- 12 volt tipici della RS232 in segnali a 0/5 volt gestibili
dalle porte del PIC.
Seguendo lo schema elettrico del nostro circuito d'esempio vediamo che il segnale di trasmissione
proveniente dal PC entra dal pin 3 del connettore DB9 femmina sul pin 13 di U3. Sul pin 12 di U3
sar� presente un segnale a 0 volt quando sul pin 13 ci saranno +12 volt e 5 volt quando sul
pin 13 ci saranno -12 volt. Il segnale presente sul pin 12 di U3 viene quindi inviato alla
linea RA1 della porta A del PIC che in questo caso far� da linea di ricezione.
Sul pin 18 del PIC (RA1) avremo quindi la seguente corrispondenza di segnali con la linea TXD del PC.
Viceversa sul pin 17 (RA0) il PIC genera i segnali da inviare al PC a livello TTL
che vengono convertiti in segnali RS232 da U3 tramine i pin 11 (ingresso TTL) e 14
(uscita RS232) e quindi inviati al PC tramite il pin 2 del connettore J2.
Applicazione d'esempio
Mettiamo finamente mano al source della nostra applicazione d'esempio e vediamo come ricevere e
trasmettere dati dal nostro PIC.
Nel file LCDTERM.ASM troverete il source completo del nostro terminale d'esempio.
Una volta montato il nostro circuito d'esempio e programmato correttamente il PIC16F84
possiamo collegare al nostro PC il circuito e fornire alimentazione. Sul display apparir�
il cursore lampeggiante in alto a sinistra.
A questo punto lanciamo in esecuzione un programma qualsiasi di emulazione terminale e
configuriamolo per usare la porta seriale a cui � collegato il circuito a 9600 baud,
8 data bit, 1 stop bit e no parity. Assicuriamoci inoltre che non sia abilitato alcun
controllo di flusso dei dati sulla seriale sia esso hardware che xon/xoff.
Proviamo ora a premere qualche tasto sulla tastiera del PC ed osserviamo come i caratteri
digitati vengano visualizzati anche sul display LCD del nostro circuito. Premendo i tasti
CTRL-L potremo pulire lo schermo dell'LCD e visualizzare nuove scritte.
Analizziamo il sorgente
Andiamo ad analizzare ora il sorgente LCDTERM.ASM del firmware della nostra applicazione d'esempio.
Partiamo dall linea 24 dove troviamo le seguenti direttive:
TX equ 0 ;Tx data
RX equ 1 ;Rx data
in cui vengono assegnate alle costanti TX e RX rispettivamente le linee di trasmissione
(TX) e ricezione (RX) del PIC. In questa applicazione in realt� non viene ancora usata
la linea di trasmissione in quanto il nostro miniterminale � in grado per ora solo di ricevere caratteri.
Queste due costanti vengono utilizzate rispettivamente dalle subroutine di trasmissione e
ricezione di caratteri via RS232: TxChar (vedi linea 421) ed RxChar (vedi linea 483).
Queste due subroutine consentono in pratica di trasmette e ricevere byte in modalit�
seriale asincrona a 9600 bps, 8 bit dati, 1 stop bit e nessuna parit�
Per trasmettere un carattere sulla linea TX basta inserire nel registro W il valore da
trasmettere ed effettuare una chiamata alla subroutine TxChar. Ipotizzando di voler
trasmettere il carattere 'A' al PC dovremo inserire il seguente codice:
movlw 'A'
call TxChar
Per ricevere caratteri l'operazione � leggermente pi� complessa. Prendiamo in esame
il nostro esempio a partire dalla linea 129:
MainLoop
btfsc PORTA,RX
goto MainLoop
call RxChar
In pratica il nostro programma esegue un loop infinito finch� non rileva uno stato
logico 0 sulla linea RX. Quando questo avviene significa che molto probabilmente �
arrivato lo START BIT dal PC e che, secondo quanto detto sopra, arriveranno in sequenza
i bit apparteneti al dato trasmesso dal PC.
In questo caso viene chiamata la RxChar che si occuper� di leggere ogni singolo bit
ricevuto, compattarli in un unico byte e restituire il valore del byte cos� ricevuto nel registro ShiftReg.
Una volta lanciata la RxChar azzera il registro ShiftReg in cui verranno memorizzati
i bit man mano che vengono ricevuti
RxChar
clrf ShiftReg
quindi mette a 8 il registro BitCount usato per il conteggio del numero di bit in arrivo
movlw 8
movwf BitCount
a questo punto attende un periodo pari a circa 1 bit e mezzo in modo da far scorrere il
tempo necessario alla trasmissione dello start bit e campionare il valore del BIT 0
circa a met� del tempo di durata.
DELAY BIT_DELAY+BIT_DELAY/2 ;Wait 1.5 bit
a questo punto legge lo stato della linea RX ed inserisce il valore letto nel flag di
CARRY (C) del registro STATUS e quindi effettua una istruzione di ROTATE RIGHT F TROUGHT CARRY (RRF)
con il registro ShiftReg in modo da spostare verso destra tutti i bit del registro ShiftReg ed
inserire nel bit pi� significativo il valore appena letto dalla linea RX come riportato nella seguente figura:
questa lettura avviene per otto volte ad intervalli di tempo pari alla durata di un bit
in modo da campionare il valore della linea RX sempre al centro del bit in ricezione.
wDB
btfss PORTA,RX
goto RxBitL
RxBitH
nop
bsf STATUS,C
goto RxShift
RxBitL
bcf STATUS,C
goto RxShift
RxShift
nop
rrf ShiftReg,F
attende per un periodo di tempo pari ad 1 bit
DELAY BIT_DELAY
continua a campionare se non ha ancora letto tutti ed otto i bit
decfsz BitCount,F
goto wDB
esce da RxChar dopo aver letto l'ultimo bit
return
a questo punto nel registri ShiftReg dovrebbe esserci il byte trasmesso dal PC
Una volta letto il byte proveniente dal PC il nostro programma d'esempio controlla se
il byte ricevuto � un carattere di controllo oppure un normale carattere da visualizzare su LCD.
L'unico carattere di controllo implementato dal nostro miniterminale � il Form Feed (FF)
corrispondente al codice ASCII decimale 12. La trasmissione di questo carattere verso una
stampante determina l'avanzamento di un foglio di carta. Nel nostro caso pulisce il contenuto dell'LCD.
Il form feed pu� essere trasmesso dal nostro simulatore di terminale su PC premendo il tasto CTRL
seguito dalla lettera L.
Questa � la parte di codice che gestisce la ricezione di un Form Feed:
CheckFormFeed
movlw 12
xorwf ShiftReg,W
btfss STATUS,Z
goto _CheckFormFeed
clrf xCurPos
clrf yCurPos
call LcdClear
goto MainLoop
_CheckFormFeed
in pratica viene controllato se il valore ricevuto dalla subroutine RxChar � pari a 12.
In caso affermativo vengono azzerati i registri xCurPos e yCurPos che mantengono il valore X,Y
del cursore carattere su display. Quindi viene chiamata la subroutine LcdClear che si occupa di
inviare i comandi corretti al display LCD per azzerarne il contenuto.
Nel caso non sia stato trasmetto un FF dal PC, il carattere ricevuto viene inviato nudo e
crudo al display con il seguente codice:
movf ShiftReg,W
call putchar
e quindi si ritorna ad attendere lo START BIT del prossimo carattere con la seguente istruzione:
goto MainLoop
La subroutine putchar in pratica invia il valore contenuto nel registro W al display LCD
nella posizione in cui si trova il cursore carattere (xCurPos e yCurPos), quindi si occupa
di mandare a capo il cursore se si � raggiunto il fine riga o di riportarlo alla prima riga
se si � raggiunto il fine display, In tutti i casi i registri xCurPos ed yCurPos vengono
aggiornati alla prossima posizione in cui poter scrivere il successivo carattere ricevuto dal PC.
LCDPRINT un programma d'esempio per l'utilizzo del nostro miniterminale
lcdprint.zip
Da questo link potrere scaricare un semplice programma d'esempio per l'uso del nostro
miniterminale RS232. Il programma di chiama LCDPRINT e funziona in ambiente MS/DOS o prompt MS/DOS
sotto Windows 95/98/ME. Non � assolutamente in grado di funzionare sotto Windows NT/2000/XP.
LCDPRINT permette di visualizzare messaggi sul nostro miniterminali nel modo pi� semplice.
Basta digitare dal prompt di MS/DOS il comando LCDPRINT seguito dal numero di porta seriale a
cui � connesso il nostro miniterminale e la stringa da visualizzare tra doppi apici.
Se vogliamo visualizzare ad esempio la scritta "Ciao a tutti" sul miniterminale connesso
alla porta COM2 dovremo digitare:
LCDPRINT /COM2 "Ciao a tutti !"
Le applicazioni possibili per questo semplice programma sono molte. Lo potremmo usare ad
esempio per visualizzare dei messaggi durante boot di Windows 95 inserendo il comando
all'interno del file AUTOEXEC.BAT.
Spunti per un p� di esercitazioni
La nostra applicazione d'esempio � stata sviluppata nel modo pi� semplice possibile
per permettere a chiunque di capirne il funzionamento senza perdersi in centinaia di linee
di codice. Questo comporta ovviamente una serie di limitazioni nelle funzionalit� che questo
miniterminale � in grado di dare.
Chi volesse fare un p� di esercizio pu� tentare di ampliare il numero di caratteri di controllo
riconosciuto dal miniterminale quali ad esempio il Carriage Return, il New Line o il Backspace.
Chiunque abbia voglia di realizzare questi esercizi pu� inviare direttamente all'autore
all'indirizzo [email protected] il proprio lavoro per una eventuale pubblicazione tra gli esempi del corso.
Un altro esempio con l'interfaccia RS232
Vediamo ora un altro esempio di utilizzo della RS232. In questo caso realizzeremo un circuito che
sfrutta anche le capacit� trasmissive messe a disposizione dalla subroutine TxChar.
Si tratta in pratica di una evoluzione del circuito gi� presentato in una delle lezioni precedenti
con 4 led e 4 switch a cui abbiamo aggiunto ora una interfaccia RS232 per poter comandare i quattro led
e leggere da PC lo stato dei quattro switch.
Nella figura seguente viene riportato lo schema elettrico completo:
Dai seguenti link potete scaricare il sorgente del firmware per il PICmicro
ed il semplice programma per MS/DOS RS232IO con cui � possibile inviare dal PC i comandi di
accensione dei singoli led e leggere lo stato corrente dei quattro switch.
rs232io.asm
rs232io.zip
Protocollo di comunicazione con il PC
Come gi� detto il nostro circuito � dotato di quattro LED denominati LED1, LED2, LED3 e LED4
e quattro pulsanti denominato SWITCH1, SWITCH2, SWITCH3 e SWITCH4.
Tramite un semplice protocollo possiamo decidere quale dei quattro led accendere oppure
leggere lo stato di uno qualsiasi dei quattro pulsanti.
Il protocollo consiste in una serie di codici di controllo che il PC pu� trasmettere al
nostro circuito tramite la seriale. La velocit� di trasferimento � la solita 9600 baud,
8 data bit, 1 stop bit, no parity.
Comandi di accensione LED
Possiamo accendere ogni singolo LED inviando dal PC i seguenti comandi:
Comandi di spegnimento LED
Possiamo spegnere ogni singolo LED inviando dal PC i seguenti comandi:
Lettura stato pulsanti
Per leggere lo stato di tutti e quattro i pulsanti basta inviare un unico comando:
Quando il PIC riceve questo comando dalla RS232 legge lo stato dei bit RB4, RB5, RB6 ed RB7
ed invia un unico codice al PC che riflette lo stato dei quattro pulsanti. Di questo
codice solo i bit 0,1,2,3 indicano lo stato dei pulsanti secondo la seguente tabella.
Per cui se ad esempio solo lo SWITCH 1 risulta premuto il codice di risposta
sar� 01h (00000001 binario). Se risultano premuti sia lo SWITCH 2 che il 4 il
codice di risposta 0Ah (00001010 binario).
Programma di prova
Il programma di prova RS232IO.EXE consente di provare il circuito immediatamente.
Il programma funziona in ambiente MS/DOS o prompt MS/DOS sotto Win 95/98.
Ipotizziando di aver collegato alla COM2 il nostro circuito, per accendere il LED 1 sar� sufficiente digitare:
RS232IO /COM2 /LED1=ON
Se ora vogliamo spegnere il LED 1 ed accendere il LED 4 potremo digitare:
RS232IO /COM2 /LED1=OFF /LED4=ON
Se ora vogliamo accendere solo il LED 3 senza modificare lo stato degli altri led:
RS232IO /COM2 /LED3=ON
Possiamo anche richiedere lo stato corrente dei singoli switch con un unico comando:
RS232IO /COM2 /SWITCH
Il programma risponder� con qualcosa del genere:
Switch 1: off
Switch 2: off
Switch 3: ---> Active
Switch 4: off
Ad indicare che solo lo SWITCH 3 risulta premuto.
Segnala questo articolo:
Parole chiave: - PIC -
|