home | area personale         schemi | tutorial | robotica | pic micro | recensioni         forum | chat irc         faq | contatti         store | Ordina PCB
username
password
cerca
 
LA PORTA PARALLELA tipo: livello:
tutorial presenta gli aspetti hardware e software che necessario conoscere per poterla usare nella modalit SPP.
 
 




La porta parallela

La porta parallela è, tra le interfacce disponibili sul personal computer, certamente la più popolare presso gli hobbisti elettronici grazie al fatto che presenta un discreto numero di ingressi ed uscite direttamente compatibili con gli usuali circuiti digitali e che il suo uso è particolarmente semplice. Essa è conosciuta anche LPT, porta stampante, printer port oppure interfaccia Centronics.

Questo tutorial presenta gli aspetti hardware e software che è necessario conoscere per poterla usare nella modalità SPP.


La porta parallela - Versione 2.1d - Luglio 2001
Copyright © 2001, Vincenzo Villa
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts and with no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".
(E' garantito il permesso di copiare,  distribuire e/o modificare questo documento seguendo i termini della GNU Free Documentation License, Versione 1.1 o ogni versione successiva pubblicata dalla Free Software Foundation)
Il contenuto di questi documenti è fornito "così come è" (AS IS), a solo titolo didattico e senza garanzia alcuna, implicita o esplicita. In particolare non ci si ritiene responsabili di alcun danno diretto o indiretto causato dall'uso di queste informazioni.
Tutti i nomi di ditte e prodotti citati sono proprietà dei legittimi proprietari.

Il comune PC possiede una sola porta stampante a cui possono essere connesse la stampante ed altri dispositivi "paralleli"(ZIP, scanner.). La porta parallela è facilmente riconoscibile guardando il computer all'esterno: appare come un connettore a 25 poli DB25 femmina (cioè con i fori), posto normalmente sul retro del PC. Non va confusa con la porta seriale che, nei vecchi PC, è costituita da un connettore DB25 maschio (cioè con gli "spilli"). Alcuni PC, particolarmente ricchi di periferiche e non particolarmente recenti, hanno anche altri connettori femmina a 25 poli, per esempio quello di alcune porte SCSI per scanner.

spp1.jpg - connettori della interfaccia seriale e parallela

Nella fotografia si vede in alto il connettore della porta parallela ed i connettori delle due porte seriali, un DB25 ed un DB9 (in basso).

Qualora si intendesse usare la LPT per circuiti autocostruiti è cosa quanto mai opportuna installare una seconda parallela. Questo evita da una parte la necessità di sconnettere la stampante ogni volta che si lavora e dall'altra, nel caso di errori, non si rischia la rottura dei chip montati sulla scheda madre.

Un altro consiglio è quello di procurarvi una cavo di uno o due metri con doppio connettore DB25 maschio e tutti i fili connessi uno a uno (cioè il pin uno di un connettore connesso all'uno dell'altro connettore, il due al due e così via), al fine di poter comodamente lavorare senza spostarsi continuamente sul retro del PC. Molto utile anche un gender changer femmina-femmina e, eventualmente, il meno necessario maschio-maschio.

Il connettore in genere installato sulle stampanti (centronics) è invece a 36 pin ed ha una diversa forma, pur avendo sostanzialmente la stessa funzione; in genere è scomodo da utilizzarsi in quanto ha troppi pin "inutili".

I tipi di porta parallela

Nel tempo la porta parallela montata nel PC si è evoluta anche se, con qualche eccezione, si è mantenuta la compatibilità con i primi modelli. Molti costruttori hanno in passato apportato modifiche e miglioramenti allo standard originario purtroppo con scarsa compatibilità tra modelli diversi: ciò ha reso di fatto inutilizzabili sulla generalità dei PC le caratteristiche avanzate disponibili solo per alcune porte parallele.

Le categorie che comprendono tutte le porte attuali sono sostanzialmente tre:

  • La Standard Parallel Port (SPP). È il modello originario di porta parallela, installato sul primo PC XT. Pensata originariamente solo per la connessione alle stampanti, con qualche accorgimento permette una certa flessibilità anche in altri usi. Tutti gli altri tipi di porta parallela sono compatibili con questo e quindi il software e l'hardware sviluppati per questa porta sono praticamente universali.
  • La Enhanced Parallel Port (EPP). Permette lo scambio bidirezionale dei dati fornendo un supporto hardware per l'hand shaking. E' possibile raggiungere alte velocità di trasferimento, circa 10 volte maggiori della SPP. Questa modalità è descritta in un tutorial presente sul mio sito
  • La Extended Capabilities Port (ECP). Permette la maggiore flessibilità di utilizzo, ha il supporto del DMA ed una grande varietà di modalità di funzionamento. Come contropartita è piuttosto difficile progettare hardware capace di usarla.

Tutti questi modi di funzionamento sono stati normati nello standard IEEE 1284 del 1994, accanto al Nibble Mode ed al Byte mode. In questo tutorial tratterò solo della SPP.

In seguito farò riferimento, più che alle norme, al comportamento reale delle porte installate nei PC attuali e passati. Nel caso di comportamenti differenti o legati a situazioni particolari evidenzierò la cosa al fine di mantenere la massima compatibilità anche a rischio di non ottimizzare le prestazioni, sconsigliando in particolare l'uso di alcune tecniche che rischierebbero di danneggiare il PC.

Configurare la porta parallela

Prima di procedere alla descrizione delle porte, mi sembra opportuno indicare come configurare la porta nei vari modi di funzionamento, quando la cosa è ovviamente possibile.

  • Se il PC è piuttosto vecchio (diciamo fino ad un 486 del 1994) e la porta parallela è installata su una scheda connessa al bus ISA o VL-bus, molto probabilmente la porta è una SPP e quindi non necessita di alcuna configurazione. In genere la stessa scheda che ospita il connettore stampante ha anche la funzione di controller per i dischi e le porte seriali o, in macchine molto vecchie, di scheda video.
  • Se la porta è costituita da un chip installato sulla scheda madre in genere è configurabile per alcuni o tutti i modi previsti dalla norma IEEE 1284. Per far ciò è necessario, prima della fase di boot, accedere al menu di configurazione dei parametri del BIOS (in genere premendo il tasto DEL o F1 durante la verifica della memoria) e cercare alla voce integrated peripherals o simili. Per gli scopi che si vogliono raggiungere con questo tutorial la porta va configurata come normal oppure centronics oppure default oppure ancora printer mode, tutti termini sostanzialmente equivalenti. Se previsto è anche possibile utilizzare il modo bi-directional. Prima di procedere, vi consiglio però di leggere l'avvertenza riguardante la sicurezza, riportata al termine del paragrafo.
  • Se la porta è installata su una schedina aggiuntiva, è spesso disponibile un jumper che permette di configurare la porta come SPP o EPP.

spp2.jpg - LPT aggiuntiva

Qui sopra, l'immagine della classica scheda parallela aggiuntiva su bus ISA, un investimento di una decina di euro di cui non ci si pentirà. Purtroppo molti PC recenti non dispongono di tale bus, sostituito dal più performante PCI. Sono comunque disponibili anche schede per PCI, in genere sono più costose e, a volte, più veloci.

La scheda va installata in uno slot libero, previa configurazione di alcuni jumper:

  • LPT1, LPT2 o, in alcuni casi, LPT3. Ovviamente occorre evitale la prima opzione se è già presente la porta parallela principale (cosa quasi sempre vera).
  • IR5 o IRQ7. Se non sapete cosa fare è opportune non selezionare nessuno questi jumper perché, in PC normalmente configurati vi è penuria di interrupt.
  • Modo SPP o EPP o ancora (più raramente) ECP, quando disponibili. Il modo EPP è più generale e quindi vi consiglio di attivarlo anche nel caso in cui vogliate realizzare circuiti basati sulle idee presentate in questo tutorial.

Da leggere per la sicurezza del PC

Nei PC moderni la porta parallela è gestita da un chip che controlla anche altre interfacce (seriali, dischi...). In caso di errori nell'uso dell'interfaccia si possono causare guasti che si ripercuotono sul funzionamento di tutto il PC, fino a causarne il blocco. Il chip non è in genere sostituibile e ciò causa la necessità di dover cambiare tutta la scheda madre, con costi e seccature facilmente immaginabili. Per questo vi consiglio vivamente di comprare una schedina parallela da installare su uno slot libero (anzi compratene due, perché in genere si rompono l'ultima domenica prima delle ferie estive.). Se possibile prendetene una che supporti anche la modalità EPP, certamente più flessibile e dallo stesso costo. L'unica difficoltà potrebbe essere quella di reperirla nel negozio sotto casa.

Ovviamente la sicurezza non è assoluta ma mi sembra un buon compromesso: io non ho mai perso una scheda madre in questo modo, e ne ho usate e fatte usare tante... Comunque non è una bella idea usare per esperimenti il P4 nuovo di zecca su cui gira la contabilità aziendale o altre applicazioni critiche.

L'attenzione è una cosa che comunque non deve mai mancare; gli americani dicono "check and double-check".

Quante porte parallele ?

Come già detto i PC hanno normalmente una sola porta parallela, indicata come LPT1 oppure PRN. Il BIOS permette però di estenderne il numero fino a tre (su alcune macchine, soprattutto vecchie, fino a quattro). Le porte aggiuntive sono indicate come LPT2 e LPT3. Se è indispensabile e a condizione di trovare schede adatte, il numero potrebbe essere ulteriormente elevato.

Ciascuna porta parallela è indirizzabile attraverso una serie di indirizzi nello spazio di I/O, occupando un minimo di quattro indirizzi consecutivi; il primo di questi indirizzi è chiamato indirizzo di base.

In genere LPT1 ha indirizzo di base 0x378 (usando la sintassi C, con 0x378 si intende il numero esadecimale 387, indicato con 378h oppure $378 se si usano altri linguaggi; in decimale l'indirizzo corrispondente è 888), LPT2 ha indirizzo 0x278 ed LPT3 0x3BC.

Gli indirizzi di tali porte non sono però fissi ma dipendono dall'hardware installato e da come il BIOS (o il sistema operativo) effettua la ricerca, causando spesso problemi nell'interpretazione corretta delle informazioni. Per esempio la porta con indirizzo 0x3BC è indicato sulle vecchie macchine come LPT1.

Due sono i modi per conoscere gli indirizzi effettivi:

  • Durante la fase di boot del PC occorre avere l'occhio sveglio e leggere sulla prima schermata gli indirizzi delle porte parallele che il BIOS individua, almeno nei PC che mostrano questa informazione.
  • Nei sistemi che utilizzano il BIOS del PC (per esempio i vari DOS e Windows), leggere il contenuto delle locazioni di memoria 0x408 e seguenti ed interpretare secondo la tabella seguente (gli indirizzi di memoria sono in esadecimale, nella sintassi segmento:offset):
Indirizzo di memoria Contenuto (2 byte)
0000:0408 Indirizzo di base di LPT1
0000:040A Indirizzo di base di LPT2
0000:040C Indirizzo di base di LPT3
0000:040E Indirizzo di base di LPT4

Su macchine moderne, in linea di massima successive agli IBM PS2 prima serie, l' indirizzo corrispondente alla LPT4 è usato per altri scopi e quindi ne sconsiglio l'uso e raccomando una particolare attenzione nell'interpretazione dei dati letti.

Di seguito un frammento di codice che legge l'indirizzo di LPT1 in Turbo C (c) in ambiente DOS.

unsigned int far *pAddr; // Puntatore ai vettori di indirizzo
unsigned int IOaddr;     // Indirizzo di LPT1
{
 	pAddr = (unsigned int far *) 0x408;
 	IOaddr = *pAddr;
 	printf("LPT1 base address is 0x%Xn", IOaddr);
}

In TurboPascal (c) l'indirizzo di LPT1 si ricava con il seguente codice.

Var addr:word; {Indirizzo di LPT1}
Begin
	addr := MemW[$0000:$0408];
	writeln("LPT1 base address is", addr);
End

Per le altre porte il codice è lo stesso, cambiando ovviamente l'area di memoria da cui leggere.

Il sistema operativo Linux (c) utilizza convenzioni diverse, assegnando il nome di lpt1, lpt2 ed lpt3 rispettivamente alle porte che individua agli indirizzi 0x378, 0x 278 e 0x3BC.

I registri e l'assegnazione dei pin

Complessivamente sono disponibili sul connettore della porta parallela 12 bit per l'output e 5 per l'input. Gli ingressi e le uscite sono TTL compatibili (alcuni possono essere a collettore aperto, in genere con resistore di pull-up integrato all'interno del PC) anche se le tensioni e le correnti effettivamente disponibili sono piuttosto variabili in funzione delle tecnologie impiegate per la costruzione della porta.

Su molti PC un uno logico appare come una tensione molto vicina ai 5V, uno zero come 0V (a vuoto). Le correnti disponibili sono in genere di almeno 5 mA sia di sink che di source ma spesso molto di più (anche 50 mA e più). Non si tratta però di una regola: in genere deve essere interpretato come uno logico qualunque tensione superiore ai 2V e come zero logico qualunque tensione inferiore a 0.8V. Inoltre si potrebbe ritenere che la corrente assorbita da un'uscita (Isink) sia maggiore, anche di molto, di quella erogata (Isource).

E' quindi buona norma progettare circuiti che riescano a gestire correttamente segnali che rappresentano l'uno logico sia con i 2V sia con i 5V (quali per esempio i TTL, gli HCT o gli HC con resistore di pull-up. E' anche opportuno evitare assorbimenti superiori a qualche mA.

La seguente tabella riporta l'assegnazione dei pin (sia sul connettore DB25 che su quello Centronics), il loro nome, la direzione (Out significa che il PC invia il bit alla periferica) ed il nome del registro utilizzato per controllarli.

Pin DB25
(lato PC)

Pin centronics
(lato stampante)

Nome

Direzione

Registro

1

1

Strobe

Out *

Control

2

2

Data 0

Out

Data

3

3

Data 1

Out

Data

4

4

Data 2

Out

Data

5

5

Data 3

Out

Data

6

6

Data 4

Out

Data

7

7

Data 5

Out

Data

8

8

Data 6

Out

Data

9

9

Data 7

Out

Data

10

10

Ack

In

Status

11

11

Busy

In

Status

12

12

Paper Out

In

Status

13

13

Select

In

Status

14

14

Linefeed

Out *

Control

15

32

Error

In

Status

16

31

Inizialize

Out *

Control

17

36

Select-in

Out *

Control

18-25

19-30, 33

Massa

-

-

-

18, 35

+ 5V (Rpu)

-

-

-

14, 34

Non usato

-

-

I pin di uscita evidenziati da un * sono utilizzabili anche come ingresso ma solo su alcune porte, come descritto più avanti. In questo caso si tratta di un'uscita a collettore aperto.

Alcuni dei pin del connettore Centronics a 36 pin non sono presenti sul connettore a 25 pin.

Realizzando un circuito connesso alla porta parallela è opportuno collegare tutti i fili di massa, sia per semplificare il layout del circuito stampato sia per diminuire gli eventuali disturbi.

L'immagine seguente evidenzia i pin di uscita con l'indicazione dei relativi registri, visti dal connettore del PC. I pin non indicati sono tutti connessi a massa.

spp3.jpg - I pin della SPP

Verificate con attenzione la corrispondenza dei pin leggendo sul connettore stesso la numerazione (è sempre presente, almeno per i 4 pin agli angoli), soprattutto se si usano prolunghe o simili.

Attenzione in particolare al fatto che, utilizzando un adattatore maschio la corrispondenza dei pin è, ovviamente, simmetrica, dato che deve incastrarsi in un connettore femmina. Analogamente se si guarda un connettore da dietro (cioè dal lato su cui si eseguono le saldature) i pin appaiono, ovviamente, simmetrici.

I registri di base

Ciascuna porta parallela configurata come SPP è controllabile attraverso tre registri consecutivi nello spazio di I/O del processore, chiamati data register, status register e control register, ciascuno di 8 bit.

Per scrivere un byte in questi registri è necessario eseguire una istruzione di output verso l'indirizzo interessato. Per leggere un byte è necessario effettuare una istruzione di input. Non è possibile leggere o scrivere un solo bit alla volta, indipendentemente dal linguaggio adottato; inoltre non è in genere possibile utilizzare le istruzioni corrispondenti alle SET dell'assembler. Infine non è possibile leggere un dato da un registro di sola scrittura o scrivere in una porta a sola lettura (l'operazione non genera nessun errore ma il dato letto o scritto è inconsistente).

Una precisazione: quanto detto vale solo in ambiente MS-DOS o derivati.

Usando il BorlandC o il TurboC la sintassi è la seguente (tale sintassi verrà adottata nel seguito del tutorial):

unsigned char dato;
unsigned int addr;
outportb (addr, dato);
dato = inportb (addr); 

dove dato è il byte da leggere o da scrivere (una variabile di otto bit, senza segno: normalmente di tipo unsigned char) e addr è l'indirizzo del registro (una variabile o una costante a 16 bit, senza segno).

Altri compilatori C usano una sintassi simile ma non è prevista nell'ANSI C la scrittura diretta su dispositivi hardware: occorre quindi verificare sul manuale del proprio compilatore.

Usando la sintassi TurboPascal le stesse istruzioni diventano:

Port[addr] := dato;
dato := Port[addr];

Dove Port è una matrice predefinita di 65k elementi il cui l'indice corrisponde all'indirizzo della porta da utilizzare.

Usando la sintassi GW-Basic o altri basic per DOS:

OUT addr,dato
dato = INP (addr)

Usando la sintassi assembler:

MOV DX,ADDR
MOV AL,DATO
OUT DX,AL
 
MOV DX,ADDR
IN AL,DX
MOV DATO,AL

Usando sistemi operativi diversi dal DOS le cose cambiano in quanto ai programmi utente è impedito l'accesso diretto alle risorse hardware. La descrizione approfondita va oltre lo scopo di questo tutorial e mi limiterò quindi ad un breve accenno.

Windows NT/ 2000/XP

Questo sistema operativo implementa due modalità operative: il ring0 ed il ring3. Le istruzioni di I/O sono possibili senza limitazioni solo nel ring 0, quello del kernel del sistema operativo. Nel ring3 (il livello delle normali applicazioni utente) sono in teoria possibili istruzioni di ingresso e uscita su particolari indirizzi attraverso la manipolazione della cosiddetta I/O permission table, purtroppo modificabile solo all'interno del ring0.

Eseguendo una applicazione DOS viene automaticamente generata da WindowsNT una macchina virtuale (la NTVDM: NT virtual dos machine) che emula le periferiche standard ed in particolare la parallela permettendo in qualche caso il corretto funzionamento dei programmi anche se con notevolissimi rallentamenti.

Nei compilatori nativi in ambiente Windows normalmente le istruzioni di IN e OUT non sono neppure implementate: ciò è vero in particolare per VisualBasic, BorlandC 5 e Delphi.

La soluzione a questi problemi è quella di scrivere un device driver che, essendo eseguito nel ring0, permette la gestione diretta dell'hardware; purtroppo l'uso della DDK (driver development kit) di Microsoft è tutt'altro che semplice... Forse potrebbe esservi utile WinDriver disponibile in versione demo su http://www.jungo.com/

In alternativa  è possibile usare driver generici che mettono a disposizione apposite funzioni contenute in DLL; spesso questi prodotti sono disponibili gratuitamente su internet: posso citare DriverLINX, per Win9x e WinNT e PortTalk (quest'ultimo disponibile sia come sorgente che come eseguibile su http://www.beyondlogic.com/)

Analoghe considerazioni valgono anche in Win95/98Me, anche se questi OS sono molto più laschi nella protezione dell'hardware.

Linux

Anche in ambiente Linux l'I/O diretto a livello di applicazione utente non è possibile. Chi volesse fare esperimenti con questo sistema operativo deve utilizzare la funzione C

ioperm(from, num, on_or_off)

Essa permette di rendere accessibile in lettura/scrittura una serie di registri ad una applicazione qualunque. Per usare un programma che invoca questa funzione occorre però essere l'utente root.

In alternativa occorre scrivere applicazioni in kernel mode; per questo potrebbe essere utile per esempio il pacchetto GPL short.

Il data register

Il data register è un registro di sola scrittura direttamente connesso agli otto pin di dato presenti sul connettore esterno della parallela. L'indirizzo è quello di base della porta.

Per impostare un pin alto o basso basta scrivere nel bit corrispondente di questo registro rispettivamente 1 oppure 0. Il bit meno significativo del registro corrisponde al pin Data0.

Se per esempio si vogliono impostare i pin in modo tale che i pin 2 (bit 0) e 7 (bit 5) siano alti ed i pin 3, 4, 5, 6, 8 e 9 bassi, occorre eseguire la seguente riga di codice (la costante DATA indica l'indirizzo del registro dei dati della porta interessata, per esempio 0x278):

#define DATA 0x278
outportb (DATA, 0x21); // 0x21 = 00100001 in binario

Occorre infine notare che una volta scritto il byte nel registro, i pin di uscita non cambiano più il loro valore fino alla scrittura successiva in quanto il circuito di uscita della porta è formato da otto flip-flop.

Lo status register

Questo registro è di sola lettura ed ha indirizzo BASE + 1.

Quando il processore effettua la lettura di questo registro vengono riportati i valori dei cinque pin in ingresso, secondo la tabella di seguito riportata.

Indirizzo Bit Nome Pin (DB25) Invertito
BASE +1 Status 7 Busy 11 Si
  Status 6 Ack 10 No
  Status 5 Paper Out 12 No
  Status 4 Select In 13 No
  Status 3 Error 15 No
  Status 2 IRQ -  
  Status 1 Riservato -  
  Status 0 Riservato -  

L'ultima colonna indica se è presente una porta not all'ingresso della porta parallela: nel caso ci sia un SI, vuol dire che un livello logico alto viene letto come 0 logico. Se invece si trova scritto NO, un livello logico alto viene letto come 1 logico.

Se voglio conoscere il valore dei pin 11 e 12 devo eseguire il seguente codice

#define STATUS (DATA+1)
unsigned char data, busy, po // Tre variabili ad 8 bit, senza segno
data = inportb (STATUS); // Leggo gli 8 bit di stato
data = data ^ 0x80; // Inverto il bit più significativo con uno xor
busy = (data & 0x80) >> 7; // Estraggo il valore di busy (bit 7)
po = (data & 0x20) >> 5; // Estraggo il valore di Paper Out (bit 5)

Il bit IRQ viene resettato dall'hardware in caso di interrupt attivato dalla linea Ack. Vale invece 1 qualora non si sia attivata nessuna interrupt.

Il control register

Questo registro è primariamente un registro di scrittura anche se, in alcuni casi, è possibile l'utilizzo in lettura. L'indirizzo è BASE + 2.

Il processore può scrivere in questo registro per impostare il valore di quattro pin di uscita, secondo la seguente tabella. Altri due bit sono per usi interni.

Indirizzo

Bit

Nome

Pin (DB25)

Invertito

BASE + 2

Control  7

Riservato

-

-

 

Control 6

Riservato

-

-

 

Control 5

Bidirezionale

-

-

 

Control 4

Abilitazione interrupt

-

-

 

Control 3

Select-in

17

SI

 

Control 2

Inizialize

16

NO

 

Control 1

Linefeed

14

SI

 

Control 0

Strobe

1

SI

Nel caso dei tre bit invertiti, la scrittura di un 1 causa sull'uscita una tensione di 0V.

Per esempio per portare tutti i quattro pin della LPT2 ad un livello logico alto devo eseguire la seguente istruzione

#define CONTROL (DATA+2)
outportb (CONTROL, 0x04);
// 0x04 = 00000100, cioè ricordando che 3 bit sono invertiti, 00001111

Ho accennato al fatto che i quattro segnali connessi al registro di controllo possono essere in alcuni casi utilizzati anche per l'input.

Per fare ciò è necessario porre prima tutti i bit di uscita a livello logico alto e quindi leggere il byte:

outportb (CONTROL, 0x04); // tutti i pin alti
data = inportb (CONTROL) & 0x0F;

Questa possibilità è subordinata al fatto che queste uscite siano a collettore aperto (open collector), possibilità prevista nell'originaria porta del PC XT ma non in tutte le porte parallele moderne, soprattutto se configurate come EPP o ECP. Per verificare se la porta funziona secondo questa modalità provate a collegare una resistenza da 1 kohm tra uno dei pin associati al registro di controllo e massa: se viene letto uno 0 le uscite sono open-collector e quindi possono essere usate come ingressi.

Personalmente sconsiglio l'uso di tale modalità anche se funzionante in quanto potrebbe portare alla distruzione della porta nel caso di porte senza uscita a collettore aperto, cioè praticamente per tutte le porte dei PC moderni correttamente configurati.

Il bit 5 del registro di controllo permette di attivare la modalità bidirezionale delle porte che ne sono provviste: ponendo a 1 questo bit è possibile leggere i dati presenti sugli otto pin 2..9, attraverso la lettura del registro dei dati, come di seguito mostrato

outportb (CONTROL, 0x20); // 0x20 = 0010 000 setto in ingresso
data = inportb (DATA);

Se il bit vale 0, è possibile scrivere nel registro dati, come precedentemente descritto.

Non tutte le porte hanno questa possibilità ed alcune funzionano con modalità diverse. Dalla mia esperienza posso dire che le tutte le porte configurate come EPP hanno questo funzionamento. Non l'hanno invece le porte del PC XT originale ed in genere le vecchie macchine. Per effettuare il test che verifica se la propria porta parallela è bidirezionale o meno è possibile usare la seguente procedura:

  • Collegare una resistenza da 1k tra il pin D0 e la massa.
  • Scrivere un byte qualunque nel registro dati, possibilmente mischiando alcuni 0 ed alcuni 1 (personalmente uso il byte 0xAA oppure 0x55, formati entrambi dall'alternarsi di 0 e 1).
  • Configurare la porta in ingresso settando il bit bidirezionale del registro di controllo.
  • Leggere il contenuto del registro data.

Se viene letto il numero binario 11111110 (0xFE) la porta supporta la modalità bidirezionale. Se viene letto il dato preventivamente scritto, la porta non supporta la modalità bidirezionale, perlomeno secondo lo schema che ho descritto: molte schede parallele hanno infatti capacità bidirezionali di tipo proprietario e quindi incompatibili con la procedura descritta.

Il bit 4 permette di abilitare le interrupt alla ricezione di un fronte sul pin Ack. Se l'interrupt è abilitato e la stampante connessa ad una linea del controllore di interrupt (p.e. attraverso l'apposito ponticello presente su molte schede,), una transizione sul pin Ack causa un'interrupt. Il fronte attivo può cambiare da scheda a scheda. L'uso di tale possibilità richiede la conoscenza delle problematiche correlate alla gestione delle interruzioni, argomento che va oltre lo scopo di questo tutorial.

Circuiti applicativi

Presento ora qualche piccolo circuito applicativo utile per fare le prime esperienze con la porta parallela. Ho già detto del rischio di danni al PC e quindi vi invito nuovamente prestare la massima attenzione alla realizzazione del circuito e ad evitare di effettuare modifiche al circuito con il PC acceso.

Accensione di un led

Un paio di circuiti veramente semplici per accendere un led permettono di vedere come usare la parallela. È necessario disporre di una resistenza di circa 3,3k ed ovviamente di un led e, limitatamente al secondo circuito, di una batteria o un alimentatore da 5 volt (ma va bene anche una batteria da 4,5V).

spp4 - Collegare un led

Il primo schema non necessita di particolari spiegazioni: quando il pin 2 viene posto alto, il led si accende, quando viene posto basso, si spegne. Il codice relativo è banale:

outportb (DATA, 0x01); // accendo il led collegato al pin 2 (D0)
// altre righe di codice non legate all'uso della SPP
outportb (DATA, 0x00); // spengo tutti il led

Ho sottointeso la dichiarazione delle varabili utilizzate, peraltro già inserire nelle righe di codice più sopra presentate.

Occorre ricordare che, una volta acceso il led, esso rimane tale fino allo spegnimento del PC o finché viene esplicitamente spento, indipendentemente dal fatto che il programma sia o meno in esecuzione, in quanto memorizzato dall'hardware.

La connessione utilizzata in questo primo circuito (il led è acceso dalla corrente uscente dal pin della porta parallela) ha il vantaggio di non richiedere nessuna alimentazione esterna ma il difetto che su alcune porte parallele (in particolare vecchie o di PC portatili) potrebbe non funzionare a causa del fatto che la corrente di source è troppo piccola.

Il secondo circuito utilizza una sorgente di alimentazione esterna e dovrebbe funzionare con tutte le porte parallele. In questo caso è lo zero che accende il led. Per aumentare la luminosità del led è possibile diminuire il valore della resistenza anche a valori molto più piccoli, quale 330 ohm.

Ovviamente i due circuiti possono essere ampliati connettendo altri sette led ai pin di dato.

Simile il discorso per i pin connessi al registro di controllo. L'unica nota è riferita al fatto che, nel caso di uscite a collettore aperto potrebbe essere necessario per il primo circuito diminuire il valore della resistenza o addirittura toglierla (quest'ultima è un'operazione rischiosa e che personalmente sconsiglio in quanto non è una configurazione adatta alla generalità delle LPT).

Collegamento a grossi carichi

Il precedente circuito è utile solo se sono richieste correnti molto piccole (pochi mA al massimo) e una tensione di 5V massimo. In altri casi, quale l'accensione di una lampadina da 12V o di un relè, è necessario l'utilizzo di un transistor di adeguata potenza e di un'alimentazione esterna.

spp5 - Connettere relay e lampadine

Lo schema mostra la connessione di un relè (osservate il diodo di ricircolo, che deve essere di tipo veloce) e di una lampadina. La Vcc è la tensione continua richiesta per il funzionamento della lampadina e della bobina del relè. Eventuali carichi in AC richiedono sempre la presenza di un relè o di un altro interruttore adeguato.

Ovviamente nel dimensionamento del transistor e della resistenza di base occorre tenere conto delle effettive tensioni e correnti in gioco (in particolare, nel caso di grossi teleruttori o lampade ad elevato assorbimento,  si rende necessario l'uso di transistor darlington) ma, con le dovute cautele, è possibile gestire lampade a bassa tensione da diverse decine di watt.

Attenzione: nel caso di rottura del transistor o di errori di connessione è possibile che la tensione di batteria si presenti alle uscite della porta parallela mettendo a rischio non solo la porta parallela ma anche l'intero PC; nel caso di tensioni elevate, vi è rischio anche per l'incolumità delle persone e quindi sconsiglio questi circuiti a persone non adeguatamente qualificate.

L'uso di interruttori

Nello schema seguente sono illustrati tre modi per connettere un interruttore alla porta parallela. In tutte e tre i casi l'interruttore chiuso viene letto come tensione di 0 volt, l'interruttore aperto come tensione di circa 5 volt.

spp6 - Leggere lo stato di un interruttore

Lo schema utilizzato con S1 richiede la presenza di una batteria esterna da 5V. Per conoscere lo stato dell'interruttore è sufficiente leggere lo stato del bit Error nel registro di controllo (oppure di un altro bit dello stesso registro se connesso ad un altro pin). È possibile la connessione con uno qualunque dei bit gestiti attraverso il registro di controllo. In certi casi questo circuito funziona anche senza batteria e senza resistenza ma l'estrema semplicità si paga con errori di lettura occasionali, soprattutto in ambiente rumoroso.

Lo schema usato per S2 è simile al precedente, con la differenza che la tensione non viene prelevata da una batteria ma da uno dei pin della porta dati, posto preventivamente a uno logico. Lo svantaggio è quello di richiedere per ciascun interruttore due pin della porta parallela, oltre la massa.

Lo schema utilizzato per S3 è il più semplice e funziona con i pin associati al registro di controllo; non richiede nessun componente oltre l'interruttore ma funziona esclusivamente a condizione che il pin a cui è connesso l'interruttore sia a collettore aperto e che la resistenza di pull-up sia montata internamente alla scheda. In questo caso, per leggere lo stato dell'interruttore occorre impostare a 1 il pin scrivendo nel registro di controllo e poi leggere il bit nello stesso registro. Attenzione: qualora la porta non fosse a collettore aperto (come succede in molte parallele moderne) si rischia la distruzione della porta. Pertanto sconsiglio l'uso di questo metodo.

Lettura di otto bit

Il seguente schema permette di leggere otto bit anche da porte non bidirezionali o senza uscite open collector. Viene utilizzato un multiplexer comandato dall'uscita di strobe, leggendo quattro bit alla volta.

spp7 - Leggere 8 bit con la SPP

Il difetto di tale metodo deriva dalla relativa lentezza (richiede due letture e due scritture della porta) e dal fatto che è ovviamente richiesta un'alimentazione esterna per l'integrato (non disegnata nello schema). Il vantaggio è che funziona con qualunque tipo di porta senza modifiche. Il codice da eseguire, è il seguente:

outportb(CONTROL, 0x01); // Seleziono il nibble basso
dataLow = inportb(STATUS) & 0xF0; // Leggo il nibble basso
dataLow = dataLow >> 4; // Allineo i quattro bit
outportb(CONTROL, 0x00); // Seleziono il nibble alto
dataHigh = inportb(STATUS) & 0xF0; // Leggo il nibble alto
data = dataHigh | dataLow; // Unisco i due nibble
data = data ^ 0x88; // Sistemo i due bit invertiti

Ovviamente se la porta è bidirezionale oppure se è possibile usare in ingresso i quattro bit associati al registro di controllo vi sono minori problemi, pagati con una minore compatibilità.

La soluzione più razionale nel caso in cui serva l'input di una quantità significativa di dati è però quella di adottare una porta EPP, sicuramente più standardizzata e veloce.

Collegare una stampante

Questo, non è un circuito applicativo, ma la schematizzazione dei segnali presenti sulla parallela durante il suo funzionamento più "naturale", cioè collegato ad una stampante secondo l'handshake centronics.

Una premessa: le temporizzazioni mostrate sono solo indicative in quanto non ho trovato standard a cui riferirmi e le varie pubblicazioni riportano dettagli differenti; forse tale standard neppure esiste e quello mostrato è solo una consuetudine più o meno rispettata. Il controllo è completamente effettuato dal software, in genere dalla routine del BIOS o del sistema operativo invocata per la stampa. È ovviamente possibile scrivere da sé il software per la gestione, magari da usare su un microcontrollore.

spp8 - Le temporizzazioni Centronics

In rosso ho indicato i segnali che vanno dal PC alla stampante, in verde quelli che hanno percorso inverso. Non ho indicato i segnali non coinvolti nella comunicazione.

  • Per prima cosa il PC deve scrivere i dati nel registro dei dati
  • Quindi è verificata la linea Busy proveniente dalla stampante: se è bassa la stampante è pronta a ricevere i dati, se è alta tutta l'operazione viene interrotta.
  • Il PC pone bassa la linea di Strobe, per almeno 1 microsecondo. Durante questo periodo i dati devono essere stabili (alcuni documenti citano tempi di hold e setup di qualche centinaio di microsecondi)
  • La stampante risponde ponendo altra la linea di Busy per tutto il tempo che le serve per acquisire il dato.
  • Il ciclo termina sul fronte di discesa del segnale Busy.

La linea Ack, proveniente dalla stampante in genere è ignorata dal PC (almeno in ambiente DOS e Windows).

Alcuni documenti riportano la linea Ack ritardata rispetto al Busy (il fronte di discesa di Ack coincidente con quello di Busy) ma non mi risulta che ciò sia corretto.

Risorse in rete

Un altro tutorial sulla SPP che potrebbe esservi utile è quello di Craig Peacock, disponibile sul sito http://www.beyondlogic.org/, dove sono presenti anche documenti sui device driver in ambiente Windows e la gestione delle interruzioni in ambiente MS-DOS.

Un'introduzione (in italiano) alla programmazione della alla LPT in ambiente Linux la potete trovare all'indirizzo http://linux.nuvoli.to.it/pj/pj9703/parallela.html

Un software per il debug della LPT, utile per i primi esperimenti, lo trovate su http://www.vincenzov.net/. Analogamente nella sezione Tutorial ho inserito un tutorial sull'interfaccia  parallela EPP sulle seriali RS232, e seriali RS485 e nella sezione Progetti diversi circuiti che utilizzano la porta parallela SPP, con esempi di programmazione in ambiente DOS e Windows.

GNU Free Documentation License

La licenza GNU FDL, disponibile sul sito http://www.gnu.org/ anche in versione italiana, è parte integrante di questo documento e ne contiene i termini di utilizzo. 

Questo tutorial è liberamente disponibile sul sito http://www.vincenzov.net/.

 





  il parere della community
esprimi il tuo voto approvi questa pagina? promo


  non sei autenticato, per questo non puoi visualizzare i commenti sulla pagina. Se sei registrato accedi oppure registrati.


difficoltà
costo
informazioni
Questa pagina è stata creata da grix [pagine pubblicate]
il 19/01/2006 ore 00:49
la pagina è stata visitata 14805 volte




Lo staff di www.grix.it non si assume responsabilità sul contenuto di questa pagina.
Se tu sei l'autore originale degli schemi o progetti proposti in questo articolo, e ritieni che siano stati violati i tuoi diritti, contatta lo staff di www.grix.it per segnalarlo.

   
 

 
 
indietro | homepage | torna su copyright © 2004/2020 GRIX.IT - La community dell'elettronica Amatoriale