Adaptado de Newton C. Braga, Revista Saber Eletrônica No. 320/99
A melhor linguagem de programação para desenvolver aplicações eletrônicas que acessem a porta paralela do PC, definitivamente, é aquela que você já domina bem.
Para os que desejam uma interface gráfica com um visual melhor ou mais sofisticado, programas em ambientes visuais como Delphi, Visual Basic (VB) ou LabView são os indicados.
Todavia, outras linguagens como Pascal, C++, QuickBasic e até mesmo o Debug podem ser usadas para acessar a porta paralela.
Nesse artigo serão apresentados blocos básicos de programação para o acesso à porta paralela em diversas linguagens, os quais podem ser aproveitados como parte de programas de controle mais complexos.
O endereço da porta paralela (LPT1) foi aqui considerado 378h, como comumente ocorre na maioria dos computadores. No entanto, antes de rodar seus programas, convém verificar se este endereço corresponde às especificações da sua máquina. Boa sorte!
O acesso às portas I/O dos microprocessadores da linha 80x86 é obtido através de dois arrays: Port e PortW.
Var
Port: array[0..65535] of byte;
PortW: array[0..65534] of word;
Os elementos indexados de cada array casam com o endereço
correspondente da porta I/O. Agregando um valor a um elemento de port ou portW,
faz-se com que esse valor apareça na saída da porta correspondente.
Const
Data = $5378;
Status = Data + 1;
Control = Data + 2;
Var
bits: Byte;
Port(Data)
:= bits; {output data}
Bits
:= Port(Status); {input data}
As versões mais recentes do Delphi não permitem mais a utilização das funções Port e PortW , por questões de segurança do sistema. Com efeito, o Windows NT não permite acesso aos registradores da máquina por outros programas, a não ser que estes solicitem ao próprio sistema operacional a realização dessa tarefa.
Uma solução eficiente para este empecilho é a utilização
de rotinas em Assembler. A seguir apresentamos uma procedure responsável
pela escrita de um valor em um determinado endereço, e uma function que
retorna o valor lido em um esdereço especificado.
Procedure
EscreveByte(Addr: byte; Value: byte); assembler; register;
asm
XCHG AX, DX
OUT DX, AX
end;
Function
LeituraByte(Addr: byte): byte; assembler; register;
asm
MOV DX, AX
IN AX, DX
end;
Exemplo:
(...)
Var Bytes : integer;
(...)
EscreveByte ($378, 15);
{envia o byte $0F para o registrador de dados}
Bytes := LeituraByte
($379);
{atribui a Bytes o valor lido no registrador de estado}
As funções pré-definidas para acesso às portas I/O dos microprocessadores 80x86 são:
_inp / _inpw e
_outp / _outpw.
int
_inp ( unsigned portid );
/*retorna a leitura do byte na variável portaid da porta I/O */
unsigned
_inpw ( unsigned portaid, int value );
/*retorna a leitura do byte na variável portaid da porta I/O */
int
_outp ( unsigned portid, int value );
/*escreve um byte - value - na porta identificada por portid e retorna os dados realmente escritos */
unsigned
_outpw ( unsigned portid, unsigned value );
/*escreve uma palavra - value - na porta identificada por portid e retorna os dados realmente escritos */
Portid pode ser qualquer inteiro entre 0 e 65 535.
#include <conic.h>
/* necessário para declaração das funções */
#define data 0x378
#define status 0x379
#define control 0x37A
int Bits,
/* 0<= Bits <= 255 */
Dummy;
Dummy = _outp
(data, Bits);
/* saída de dados */
Bits = _inp (status);
/* entrada de dados */
Através do Debug também é possível Ter acesso de forma muito simples à porta paralela.
Comecemos por entrar no Debug:
C:\debug /?
Debug [[drive:][path:] filename [testfile - parameters]
[drive:][path:] filename Especifica o arquivo que desejamos testar.
[testfile - parameters] Especifica a linha de comando necessária pelo arquivo que deve ser testado.
Depois que o Debug carrega, digite ‘?’ para Ter uma lista de comandos.
O Debug pode proporcionar comandos de entrada e saída:
i port_address e
o port_address
byte_value
Por exemplo:
c:\>debug
-o 378 2b {saída de dados}
-i 279 {requisição de entrada}
3E {entrada de dados}
-q {exit}
C:\>
Também é válido para o Borland C e C++.
O Turbo C e o Borland C/C++ proporcionam acesso às portas I/O dos microprocessadores da série 80x86 via funções pré-definidas: inportb/inport e outportb/outport.
int
inportb(int portid);
/* retorna um bit lido como portid na porta I/O */
int
inport (int portid);
/* retorna uma palavra lida na porta I/O como portid */
void
outportb(int portid, unsigned char value);
/* escreve o valor do byte (value) na porta I/O (portid) */
void
outport(int portid, int value);
/ escreve o valor da da palavra (value) na porta I/O (portid)*/
#include
<stdio.h>
#include
<dos.h>
#define
Data 0x378
#define
Status 0x379
#define
control 0x37A
unsigned
char bits;
outport(Data,
bits);
/* saída de dados */
bits
= inportb(Status);
/*entrada de dados*/
O acesso à porta paralela pelo QuickBasic (QB ou QBasic) é feito pelas instruções IN e OUT.
IN (portid) “retorna o byte lido na porta I/O portid”
OUT portid, value “escreve na saída I/O portid o valor do byte value”
pdata = &H378
status = &H379
control = &H37A
OUT pdata, bits “saída de dados”
bits = IN (status) “entrada
de dados”
Os programadores em ambiente LabView (Linguagem G) tem duas opções para realizar o acesso à porta paralela do PC.
As versões mais novas do software contêm VI’s específicas que realizam o acesso a endereços de memória: In Port e Out Port. Essas VI’s encontram-se à disposição na paleta Fuctions >> Advanced >> Memory.
A entrada de dados é feita com a VI In Port. Deve ser passado como parâmetro o endereço da porta que se deseja acessar, e a VI retorna opcionalmente ou um byte ou uma palavra lidos na porta especificada.
|
|
Fig.1 – Diagrama de utilização da VI In Port
A saída de dados é feita com a VI Out Port. São passados como parâmetros o endereço da porta e o valor a ser escrito, e a VI escreve no endereço especificado um byte ou uma palavra opcionalmente.
|
|
Fig.2 – Diagrama
de utilização da VI Out Port
Convém assegurar-se de que o endereço da porta está sendo escrito corretamente em hexadecimal. Caso contrário, a VI endereçará uma outra porta qualquer do PC e não conseguirá acessar a porta paralela.
Outra forma de acessar a porta paralela é através da VI Write to Serial Port.Vi. Para acessar a porta paralela LPT1, deve-se entrar com o número 10 como parâmetro de especificação da porta. Caso se queira acessar uma porta LPT2, deve-se especificar porta No. 11, e assim por diante.
|
|
Fig.3 – Diagrama de Utilização da VI Write to Serial Port
Essa VI escreverá no registrador de dados da porta paralela o byte correspondente ao código ASC-II do caractere passado como parâmetro em uma string.
Importante: para que seu programa funcione, você deve antes ligar os pinos 10, 11 e 12 a um dos pinos de terra da porta paralela (pino 25, por exemplo). Caso contrário, a Vi retornará o erro –37, indicando que a impressora conectada à porta não está pronta ou está sem papel.
Com efeito, a VI Write to Serial Port.Vi não têm a finalidade de interagir com circuitos conectados à porta paralela, mas simplesmente enviar dados para um instrumento ou para uma impressora.
A vantagem desse método é que pode ser implementado com
facilidade em versões mais antigas do LabView. Contudo, este método permite
apenas escrever na porta paralela, ficando impossibilitado de ler
quaisquer dados do dispositivo.
É muito fácil, portanto, escrever programas simples que acessem a porta paralela do PC para fins de interação com circuitos eletrônicos.
Uma boa dica para poupar tempo e esforços é a utilização de uma interface com LED’s durante o desenvolvimento de suas aplicações, a fim de verificar se os pulsos de saída na porta paralela estão realmente de acordo com os requerimentos do seu projeto.