Breve tutorial sulla programmazione della porta parallela
by Ciaby


Questo semplice e stupido tutorial può servire come base per costruire piccoli device esterni controllati via pc.

La porta parallela ha un cavo di uscita a 8 bit, per cui possono essere presi come input o output 8 canali differenti, più che sufficenti per qualunque progettino hardware semplice. Nel kernel linux le 2 funzioni principali per usare una porta di I/O sono inb() e outb(), rispettivamente di input e output. Per poter accedere alla porta tramite un programma in userspace bisogna settare i permessi, e questo viene fatto con ioperm(), ovviamente il programma dovrà girare con i privilegi di root. Il primo pezzo di codice illustra come aprire e chiudere la porta, e fare alcune semplici operazioni:

#include //include necessario per outb e ioperm
#define PORT 378 //tipicamente l'i/o della porta parallela
[...]
ioperm(PORT,1,1); //assegna permesso di scrittura alla porta PORT
outb('0',PORT); //setta l'output a 0, in pratica spegne tutti i canali
ioperm(PORT,1,0); //ri-setta a 0 i permessi alla parallela
[...]

Con queste poche di righe di codice è già possibile pilotare una discreta quantità di dispositivi, il più semplice di questi sono 8 led collegati ognuno ad un canale (se ci mettete anche una resistenza in mezzo è meglio) :-D Dimenticavo, la parallela dà un output di circa 5V, non troppo ma neanche troppo poco...

:-)

La parallela funziona in binario, per cui per settare il canale x occorrerà fare:

x -> 2^(x-1)
Es: per accendere il canale 3 occorrerà fare 2^(3-1)=4 e quindi outb(4,porta);
Per accendere + canali contemporaneamente basta sommare i risultati es. voglio
accendere i canali 1,4 e 7:
2^(1-1)+2^(4-1)+2^(7-1) = 1 + 8 + 64 = 73 --> outb(73,porta);

Credo non serva specificare altro, incollo in fondo un semplice programma per testare tutti gli output:

pat.c
-->BEGIN<--
#include 
#include 
#include 
#define PORT 0x278

void set();
void pulisci();

char leds[8];

int main(void)
    {
    unsigned int a;
    ioperm(PORT,1,1);

    for(a=0;a<256;a++)
	{
	outb(a,PORT);
	printf("%d\n",a);
	usleep(1000);
	}

    pulisci();
    set();
    ioperm(PORT,1,0);
    }

void set()
    {
    char output;
    output = 0;
    if (leds[0] == 1)
	output = output +1;
    if (leds[1] == 1)
	output = output +2;
    if (leds[2] == 1)
	output = output +4;
    if (leds[3] == 1)
	output = output +8;
    if (leds[4] == 1)
	output = output +16;
    if (leds[5] == 1)
	output = output +32;
    if (leds[6] == 1)
	output = output +64;
    if (leds[7] == 1)
	output = output + 128;
    outb(output,PORT);
    usleep(1000000);
    }

void pulisci()
    {
    int i;
    for(i=0;i<8;i++)
    leds[i]=0;
    }
-->END<--

P.S. la funzione set() si riferisce all'array leds[8], che viene preso come modello per rappresentare gli output.
es. se leds[0] è uguale a 0 allora il primo canale sarà spento, se 1 acceso. semplice? :-D