Escolar Documentos
Profissional Documentos
Cultura Documentos
http://www.inf.pucrs.br/~eduardob/disciplinas/extensao/HW_SW_Interface
Objetivo:
Tópicos abordados:
1. Portas de entrada/saída
a. Visão geral
b. Porta paralela em detalhes (IEEE 1284)
c. Porta serial em detalhes (RS-232C)
d. Porta infrared em detalhes (IrDA)
e. Porta USB em detalhes
3. Interface software/hardware
a. Baixa potência (max 232, ‘245)
b. Interface de potência (transformador, relê, acoplador óptico, tip/bd)
5. Prática
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 1
1. Portas de entrada/saída
a. Visão geral
• Essas instruções colocam o endereço da porta a ser acessada nos 16 bits menos
significativos do barramento de endereços, e os bits no barramento de dados são
enviados/recebidos para/da porta endereçada.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 2
• Um modem conectado à porta serial é um exemplo típico de utilização de portas
de entrada/saída para conexão de um computador à outro computador ou à
internet.
• As demais portas abordadas nesse curso (serial, infrared e USB), são utilizadas
para envio/recepção de bits serialmente para/de um dispositivo externo ao
computador;
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 3
• A porta serial e utilizada principalmente para comunicação de dados. Pode ser
utilizada tambem para acessar/controlar dispositivos conectados ao PC, mas
possui algumas desvantagens em relação a porta paralela.
• Com relação a comunicação de dados, a porta serial sempre foi o meio preferido
desde a introdução dos primeiros PCs. No passado havia apenas uma opção de
porta paralela, o padrão RS-232C, que sempre foi um gargalo com relação a
velocidade de transmissão de dados. Os PCs sempre processaram dados milhares
de vezes mais rapidamente do que o padrão RS-232C pode gerenciar.
• IrDA utiliza sinais infra-vermelho para transferência de arquivos entre PCs, sinais
esses identicos aos encontrados em um controle remoto de TV.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 4
funciona como um verdadeiro barramento podendo conectar ate 127 dispositivos,
sem preocupações com diferentes pinagens de conectores e cabos. A velocidade
de transferência de dados e muitas vezes superior a do padrão RS-232C.
• Apesar das diferencas entre esses padrões, eles possuem uma caracteristica
comum que e a transferência de dados de forma uni-dimensional como uma fila
de bits.
• Nos primeiros PCs a porta paralela era um recurso bastante utilizado para
conectar impressoras.
• Por ser bem mais rápida e simples de utilizar que a única outra porta padrão
existente na época, a serial RS-232, a porta paralela se tornou a preferida também
para acessar dispositivos externos e até mesmo para comunicação entre dois PCs.
• Infelizmente, com o passar dos anos, os engenheiros não satisfeitos com o padrão
existente, acabaram criando outros padrões para a porta paralela, e a característica
de simplicidade de utilização e instalação desse recurso se perdeu um pouco.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 5
• Antes da definição do padrão IEEE 1284, as portas paralelas eram classificadas
em 4 tipos: Standard Parallel Port (SPP), Enhanced Parallel Port (EPP),
Extended Capabilities Ports (ECP) e Bi-directional Parallel Ports (ou PS-2).
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 6
• A tabela a seguir mostra a pinagem do conector de acordo com o padrão IEEE
1284-A (existem ainda os padrões B e C), em todos os modos de operação.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 7
Pin Compatibility mode Nibble mode Byte mode EPP mode ECP mode
1 nStrobe HostClk HostClk nWrite HostClk
2 Data 1 Data 1 Data 1 AD1 Data 1
3 Data 2 Data 2 Data 2 AD2 Data 2
4 Data 3 Data 3 Data 3 AD3 Data 3
5 Data 4 Data 4 Data 4 AD4 Data 4
6 Data 5 Data 5 Data 5 AD5 Data 5
7 Data 6 Data 6 Data 6 AD6 Data 6
8 Data 7 Data 7 Data 7 AD7 Data 7
9 Data 8 Data 8 Data 8 AD8 Data8
10 nAck PtrClk PtrClk Intr PeriphClk
11 Busy PtrBusy PtrBusy nWait PeriphAck
12 Perror AckDataReq AckDataReq User def. 1 nAckReverse
13 Select Xflag Xflag User def. 3 Xflag
14 nAutoFd HostBusy HostBusy nDStrb HostAck
15 nFault nDataAvail nDataAvail User def. 2 nPeriphRequest
16 nInit nInit nInt nInt nReverseRequest
17 nSelectIn 1284 Active 1284 Active nAStrb 1284 Active
18 Pin 1 (nStrobe) ground
return
19 Pins 2 and 3 (Data 1 and
2) ground return
20 Pins 4 and 5 (Data 3 and
4) ground return
21 Pins 6 and 7 (Data 5 and
6) ground return
22 Pins 8 and 9 (Data 7 and
8) ground return
23 Pins 11 and 15 ground
return
24 Pins 10, 12, and13
ground return
25 Pins 14, 16, and 17
ground return
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 8
• Cada porta paralela em um PC possui um endereço base único. No PC original,
IBM utilizou os endereços 03BCH, 0378H e 0278H. Esses endereços foram
mantidos e utilizados ate hoje.
• Cada um dos 8 bits desse registrador esta ligado a cada um dos 8 pinos de dados
do conector da porta paralela para interface com o mundo exterior. A
correspondencia e direta: o bit mais significativo do registrador esta conectado ao
bit mais significativo do conector.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 9
• O terceiro registrador (endereço 037AH para endereço base 0378H), e utilizado
no PC original para envio de comandos para a impressora. O Registrador de
Controle de Impressora envia comandos utilizando seus 5 bits menos
significativos.
13 12 11 10 9 8 7 6 5 4 3 2 1
25 24 23 22 21 20 19 18 17 16 15 14
Pino 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Função C0 D0 D1 D2 D3 D4 D5 D6 D7 S6 S7 S5 S4 C1 S3 C2 C3
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 10
Registrador de Controle (end. Base + 1):
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 11
• No caso dos computadores padrão IBM-PC, o módulo responsavel pela gerencia
da porta paralela e implementado com um circuito integrado baseado no Intel
8250.
• A UART 8250 passou a fazer parte dos computadores padrão IBM-PC em 1981.
Esse dispositivo possui capacidade de armazenamento para apenas um byte e nao
e o mais adequado, por exemplo, para comunicação utilizando os modems da
epoca com velocidade mais rapida que esse dispositivo podia gerenciar. Nesse
caso caracteres recebidos em uma comunicação podiam ser perdidos.
• As UARTs utilizadas nos PCs atuais são compativeis com a 166550, porem são
encapsuladas em dispositivos do tipo ASIC (Application Specific Integrated
Circuit) ficando dificil sua identificação visual na placa do computador.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 12
• Devido a utilização do padrão RS-232C, e possível interfacear um dispositivo
externo a um IBM-PC via porta serial, bastando para isso incluir um 8250, ou
qualquer outra UART compativel com esse padrão, no projeto do dispositivo.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 13
PC DB-9 macho DB-9 macho dispositivo
DB-9 femea DB-9 femea
• A UART 8250 trabalha com níveis de tensão TTL (0V para 0 lógico, e +5V para
1 lógico), e e preciso utilizar um conversor de níveis de tensão para realizar a
transformação de 0V para +15V, e de +5V para –15V, e vice-versa. Para isso e
utilizado o circuito integrado MAX232.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 14
velocidade de transferência de dados, com uma determinado tamanho de palavra
de dados, um determinado numero de stop bits, e uma determinada paridade. Os
mesmos parametros devem ser utilizados para programar a UART em utilização
do outro lado da linha. Caso alguma dessas informações esteja diferente em um
dos dois lados, nao haverá comunicação pois as duas UARTs estarão utilizando
protocolos diferentes.
• A figura a seguir mostra o envio da letra ‘A’ em uma UART programada para
uma palavra de tamanho 8 bits, com 1 stop bit, paridade impar e com uma
velocidade de 300 bps. Como a letra ‘A’ na tabela ASCII possui 2 bits em 1 e os
demais em 0, o bit de paridade esta em 1 de forma a gerar um numero impar de
bits em 1.
Registrador de dados:
Status:
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 15
7 6 5 4 3 2 1 0
0 TxE TBE Break Erro de Erro de Erro de RxRdy
framming paridade overrun
7 6 5 4 3 2 1 0
DCD RI DSR CTS ∆ DCD ∆ RI ∆ DSR ∆ CTS
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 16
Controle:
7 6 5 4 3 2 1 0
Obs. Se a quantidade de bits por caracter for igual a 5, o numero de stop bits será
automaticamente 1 ½ stop bits.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 17
Registrador de Controle de Interrupção: utilizado para habilitar os quatro tipos
de interrupção do 8250.
7 6 5 4 3 2 1 0
0 0 0 0 Pinos de Erro na TBE RxRdy
entrada recepção
7 6 5 4 3 2 1 0
0 0 0 Loop GP02 GP01 RTS DTR
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 18
velocidade Divisor MSB Divisor (LSB)
Divisor (Dec)
(bps) Reg. Contr. Interrupcao Reg. Dados
50 2304 09h 00h
300 384 01h 80h
600 192 00h C0h
2400 48 00h 30h
4800 24 00h 18h
9600 12 00h 0Ch
19200 6 00h 06h
38400 3 00h 03h
57600 2 00h 02h
115200 1 00h 01h
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 19
d. Portas infrared (infra-vermelho)
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 20
• O padrão IrDA permite o uso de todas as velocidades convencionais em portas
seriais a partir de 2.400 bps a 115.200 bps, utilizando o padrão de modulação
RZI. O padrão IrDA de alta velocidade (IrDA v. 1.1) possui três velocidades
adicionais: 576 Kbps; 1,152 Mbps e 4,0 Mbps.
• Em velocidades de ate 115.200 bps, cada pulso infra-vermelho precisa durar pelo
menos 1,41 microsegundos. Cada pulso IrDA dura apenas 3/16 do comprimento
de um bit com uma tolerancia de 10% para mais. Por exemplo, cada bit de um
sinal de 9.600 bps dura 104,2 microsegundos (um segundo dividido por 9600).
Um pulso IrDA tipico, nessa velocidade de 9.600 bps, dura 3/16 desse tempo, ou
seja, 19,53 microsegundos.
• O sistema IrDA nao trabalha com dados a nível de bits. Os dados transmitidos
são trabalhados a nível de pacotes (o nome utilizado no padrão IrDA e frames).
Um frame IrDA pode possuir de 5 a 2050 bytes ou mais. Assim como em outros
sistemas baseados em pacotes, um frame IrDA possui informação de endereço,
dados, e correção de erros (aplicada a nível de frame). O formato do frame esta
bem definido do padrão IrDA.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 21
e. Porta USB
• O padrão USB foi introduzido em 1996 e e visto como o sucessor natural do RS-
232C conectando a maioria, senao quase todos, os periféricos existentes. O
padrão e utilizado para conectar de forma simples desde teclados ate caixas
registradoras.
• USB classifica o hardware serial em dois tipos: hubs e funções. Um hub USB
possui “tomadas” nas quais podem ser conectadas funções. Uma função USB e o
dispositivo (periférico) propriamente dito.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 22
que e construida de forma simples bastando utilizar as regras para conexão
ilustradas na figura anterior. Nao existe um limite para o numero de hubs a serem
utilizados, porem existe um numero máximo de 127 funções a serem utilizadas
em um sistema (arvore) USB. Esse limite e imposto pelos 7 bits utilizados no
endereçamento das funções (um endereço e reservado).
• Outro limite e o comprimento de no máximo 5 metros que um cabo USB pode ter
para conectar uma função a um barramento. Porem, como hubs podem fortalecer
o sinal, um sistema USB pode se prolongar por grandes distancias ao se utilizar
diversos hubs.
• Devido ao uso desse sistema de endereçamento, cada dispositivo USB precisa ter
um software basico para entender o protocolo. No computador pessoal, cada
função precisa ter um driver, normalmente em software, responsavel por gerar os
comandos ou pacotes de dados para o dispositivo associado.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 23
• Um driver USB funciona como um provedor de servicos, fornecendo o canal
(pipe) para roteamento dos dados para as diversas funções. Consequentemente,
para cada dispositivo USB adicionado ao barramento e necessario a instalação do
driver (software).
• Os fios de dados são verde (sinal positivo D+ na figura abaixo) e branco (sinal
negativo D- na figura abaixo). A alimentação e o fio vermelho, e o terra o fio
preto.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 24
• O protocolo USB e baseado em pacotes. Todas as mensagens trocadas
necessitam de três pacotes. Uma troca de mensagens inicia com o host enviando
um pacote tocken. O pacote tocken possui o endereço do dispositivo desejado e
tambem informação de controle descrevendo a natureza da mensagem.
Dependendo da natureza da operação, o host ou o dispositivo envia o pacote de
dados. Apesar desse nome, o pacote de dados poderá estar vazio, sem nenhuma
imformação. A troca de dados finaliza com o recebimento de um pacote ACK
que informa o recebimento do pacote de dados. Um quarto tipo de pacote,
denominado pacote Especial, e utilizado para funções adicionais.
• Apenas o host envia pacotes do tipo token. Esses pacotes possuem quatro bytes,
e se divide em cinco partes, conforme mostrado na figura a seguir.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 25
• Os dois primeiros bytes seguem o padrão de todos os pacotes USB. O primeiro
byte e um campo de sincronismo que marca o inicio dos bits do token. O segundo
byte e a identificação do pacote (PID).
• O PID define quatro tipos de pacotes token: pacote de saida que envia dados do
host para o dispositivo; pacote de entrada que recebe dados no host proveniente
de um dispositivo; pacote de configuração (setup) que endereça um dispositivo
especifico; e um pacote de inicio de frame, que ajuda na sincronização do
sistema. A tabela a seguir mostra PIDs e respectivos tipos de pacote token.
• Para pacotes token “Entrada”, “Saida” e “Setup”, os sete bits que seguem o PID
representam o campo de endereço, que identifica o dispositivo para o qual o host
deseja comandar ou enviar dados. Quatro bits adicionais fornecem um codigo
Endpoint. Um Endpoint e uma seção endereçavel individualmente de uma função
USB, que possibilita que projetistas de hardware possam separar um dispositivo
fisico em diversas unidades logicas. Por exemplo, um teclado com um mouse
embutido pode ter um endereço geral para atuar como um dispositivo USB único.
Atribuindo Endpoints individuais ao teclado e ao mouse, possibilita que os
projetistas possam endereçar individualmente cada componente do teclado.
• Pacotes token do tipo inicio de frame (SOF) diferem de outros pacotes USB uma
vez que eles são do tipo broadcast. Todos os dispositivos do sistema recebem e
decodificam esses pacotes, mas nao retornam um ACK referente a eles. Os 11
bits que deveriam ser os campos de endereço e Endpoint indicam um numero do
frame.
• O host envia um pacote token do tipo SOF a cada milisegundo definindo o incio
do frame USB denominado one-millisecond.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 26
• Todos os pacotes token possuem no final cinco bits de codigo CRC (Cyclic
Redundacy Check). O CRC fornece uma forma de verificar a integridade do
campo de endereçamento e Endpoint. O CRC nao cobre o PID, que possui o sua
propria correção de erro embutida.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 27
que ele enviara será Dados 1. A partir dessa troca no tipo do pacote de dados, o
receptor sabera que o seu ACK foi recebido com sucesso.
• Existem duas solucoes para o problema de acesso as portas de entrada e saida nas
versoes 32 bits do Windows. A primeira solucao e a criacao de um device driver
que executara com privilegio nivel 0 para entrada/saida (modo kernel, ou super-
usuario). Dados poderao entao ser enviados por programas do usuario (privilegio
nivel 3) para o device driver, e o driver executara a operacao de entrada/saida.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 28
• Uma outra alternativa e a modificacao da tabela de permissoes de entrada/saida
do sistema operacional. Existe um bit nessa tabela para cada porta do sistema. A
tabela podera ser modificada de forma a dar permissao de acesso irrestrito a uma
determinada porta. A opcao do device driver e a melhor. O driver devera ser
escrito de forma a verificar se existem conflitos antes de acessar a porta.
• Para as portas que não possuem um padrão bem definido, é mais difícil de se
encontrar APIs padronizadas, e o usuário acaba tendo que utilizar o
conhecimento mais baixo nível sobre a porta para implementar o driver ou
aplicação.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 29
• O sistema de entrada/saída do unix possui uma estrutura conhecida como open-
read-write-close, uma vez que esses são os passos para a realização de uma
operação de E/S com arquivos, dispositivos ou portas de E/S.
• Nas próximas seções são apresentados trechos de programa para acessar as portas
de entrada/saída de um computador pessoal, utilizando tanto as instruções para
acesso direto do processador (in e out), quanto as interrupções da BIOS e do
DOS, e também o acesso via descritores de arquivos e APIs. Serão apresentados
exemplos de acesso às portas paralela e serial (RS-232C), pois existe
disponibilidade no laboratório de dispositivos externos que utilizam essas
portas/protocolos.
• O primeiro exemplo, listado a seguir, usa a porta serial via acesso direto ao
hardware do computador, e os exemplos seguintes utilizam recursos de mais alto
nível como, por exemplo, interrupções e chamadas de sistema (function call). O
sistema operacional e compilador utilizados estão identificados nos comentários
no início do programa.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 30
Obs. Uma chamada de sistema é uma rotina implementada em software, fazendo
parte do sistema operacional ou como um driver, que é utilizada pelo sistema
operacional ou pela aplicação para acesso ao hardware. Uma chamada de
sistema pode solicitar uma interrupção, que por sua vez é originada no
firmware do computador pessoal, ou fornecida pelo driver em software. A
função tanto da chamada de sistema quanto da interrupção é a mesma, ou seja,
chegar na interface a nível de hardware e utilizar características específicas
dessa porta de entrada e saída.
1
2 /*
3 serial_io.c
4
5 Programa em C para gerencia da porta serial RS-232C utilizando acesso direto
6 ao hardware pelas instrucoes in e out.
7
8 Eduardo Augusto Bezerra, Maio de 2003
9
10 compilador Turbo C++ versao 1.0 (Borland)
11 */
12 #include <stdio.h>
13 #include <dos.h>
14 #include <process.h>
15 #include <conio.h>
16 #define end_ctrl_50 0x03FD /* Enderecos da UART 8250 */
17 #define end_dado_50 0x03F8
18 #define LRC 0x03FB
19 #define MSB 0x03F9
20 #define LSB 0x03F8
21 #define MCR 0x03FC
22 #define LSR 0x03FD
23 #define MSR 0x03FE
24 #define IOR 0x03F8
25 #define IIR 0x03FA
26 #define IER 0x03F9
27
28 void inic8250(){ /* inicializacao da 8250 */
29 outportb(LRC, 0x80); /* DLAB = 1, programa velocidade em MSB e LSB */
30 outportb(MSB, 0x00);
31 outportb(LSB, 0x0C); /* 00H 0CH == 9600 bps */
32 outportb(LRC, 0x07); /* 8 bits de dados, 1 stop bit, sem paridade */
33 }
34
35 void reseta8250(){ /* reseta a 8250 */
36 inportb(LSR);
37 inportb(MSR);
38 inportb(IOR);
39 inportb(IIR);
40 }
41
42 void enable8250(){ /* habilita a 8250 */
43 outportb(IER, 0x01);
44 }
45
46 void disable8250(){ /* desabilita interrupcoes da 8250 */
47 outportb(IER, 0x00);
48 }
49
50 void transm_dado(unsigned char caracter){ /* transmite um caracter */
51 while (!(32 & inportb(end_ctrl_50)) == 32);
52 outportb(end_dado_50, caracter);
53 }
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 31
54
55 unsigned char status(){ /* Le status da 8250 */
56 return (inportb(end_ctrl_50) & 0x01);
57 }
58
59 int main(){
60 int opcao = 0;
61 unsigned char caracter = '';
62 unsigned char aux = '';
63
64 inic8250();
65 reseta8250();
66 outportb(IER, 0x00); /* sem interrupcoes */
67 while (opcao != 4){
68 clrscr();
69 printf("Entre com:\n");
70 printf("\t\t\t1 - Transmitir um caracter pela serial\n");
71 printf("\t\t\t2 - Receber um caracter pela serial\n");
72 printf("\t\t\t3 - Transmitir arquivo pela serial\n");
73 printf("\t\t\t4 - Sair do programa\n");
74 opcao = getch() - '0';
75 caracter = '';
76 /* transmissao de um caracter */
77 if (opcao == 1)
78 while (caracter != 0x1B){ /* repete ate' pressionar ESC */
79 disable8250();
80 printf("\nEntre com o carcter a ser transmitido ... ");
81 caracter = getch();
82 printf("%c", caracter);
83 transm_dado(caracter); /* envia um caracter */
84 }
85 /* recepcao de um caracter */
86 if (opcao == 2){
87 printf("\n\nAguardando caracter na porta serial ... ");
88 for (;;){
89 while(!status()) if (kbhit()) break;
90 if (kbhit() && getch()) break;
91 aux = inportb(end_dado_50); /* recebe um caracter */
92 printf("\nRecebido o caracter --> %c", aux);
93 }
94 }
95 /* transmissao de arquivo */
96 if (opcao == 3){
97 FILE *fp;
98 char arq[20];
99 printf("\n\nNome do arquivo: "); gets(arq);
100 if (!(fp = fopen(arq, "r"))){
101 printf("\nArquivo nao existe!");
102 exit(-1);
103 }
104 while(!feof(fp)){ /* transmite arquivo */
105 caracter = fgetc(fp);
106 disable8250();
107 transm_dado(caracter);
108 if (status()) putch(inportb(end_dado_50));
109 }
110 fclose(fp);
111 printf("\nPressione qualquer tecla para o menu.");
112 while(!kbhit());
113 }
114 }
115 return 0;
116 }
• A função outportb (int porta, unsigned char valor); envia para o endereço
especificado em porta um byte especificado em valor. A função inportb (int
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 32
porta); le um byte de um endereço especificado em porta. Com essas duas
funcoes é possível acessar todos os registradores da 8250, enviando palavras de
controle para sua programação, bem como enviando e recebendo bytes da
interface RS-232C. Os endereços utilizados no programa acima foram discutidos
na seção 1 (portas de entrada/saida, porta serial RS-232C em detalhes).
• Uma outra forma de acessar a UART 8250 é por intermédio dos serviços da
ROM-BIOS (interrupção 14H da BIOS), listados na tabela a seguir:
Inicialização – AL: 7 6 5 4 3 2 1 0
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 33
11 = paridade par
1 /*
2 serial_bios.c
3
4 Programa em C para gerencia da porta serial RS-232C
5 utilizando a INT 14H da BIOS.
6
7 Eduardo Augusto Bezerra
8 Maio de 2003
9
10 compilador Turbo C++ versao 1.0 (Borland)
11 */
12 #include <stdio.h>
13 #include <dos.h>
14 #include <conio.h>
15 #define SERIAL 0x14
16 #define ESC 0x1B
17
18 int main(){
19 union REGS r;
20 unsigned char caracter = '';
21 /* 7654321 */
22 r.h.ah = 0x000; /* 11100011 9600 bps, */
23 r.h.al = 0x0E3; /* = 8 bits de dados, */
24 r.x.dx = 0x000; /* E3H 1 stop bit, */
25 int86(SERIAL, &r, &r); /* sem paridade */
26
27 while (caracter != ESC) {
28 printf ("\nEntre com o caracter: ");
29 caracter = getch();
30 printf("%c", caracter);
31 r.h.ah = 1; /* AH = 1, transmite caracter */
32 r.h.al = caracter;
33 r.x.dx = 0;
34 int86(SERIAL, &r, &r); /* Transmite o caracter */
35 }
36 return 0;
37 }
• A função int int86(int nr. interrupção, union REGS *inregs, union REGS
*outregs); realiza um pedido de interrupção para a CPU. Essa segunda forma é
bem mais simples do que o acesso direto à 8250 mostrado anteriormente.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 34
Porta Serial RS-232C
acesso direto ao hardware – inb, outb
linguagem C – Linux
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 35
52 printf("\nEntre com o caracter a ser transmitido ... ");
53 scanf("%c", &caracter);
54 printf("%c", caracter);
55 outb(caracter, end_dado_50); /* envia um caracter */
56 }
57 return 0;
58 }
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 36
1 /************************************************************
2 * File RobotLinux.cpp - Implementation for the RobotLinux class
3 *
4 * This class has the implementation for virtual
5 * methods from Robot.h (and Robot.cpp)
6 *
7 * Project: Fischer Arm
8 *
9 * Author: Eduardo Augusto Bezerra
10 * Date: 04/04/2003
11 *
12 * Last change: Eduardo Augusto Bezerra
13 * Date: 26/04/2003
14 *
15 * Methods for controlling the robot in C++ under linux
16 * This code has been tested on linux Red Hat 8.0
17 *
18 *************************************************************/
19
20 #include "RobotLinux.h"
21
22 /************************************************************
23 * Constructor
24 *************************************************************/
25 RobotLinux::RobotLinux(void){
26 motorWord = 0;
27 fd = -1;
28 }
29 /************************************************************
30 * Destructor
31 *************************************************************/
32 RobotLinux::~RobotLinux(void){
33 close(fd);
34 }
35
36 /************************************************************
37 * void RobotLinux::openSerial(int ser)
38 *
39 * open the serial connection;
40 * sets the serial parameters to 9600 Baud, no parity, 8, 1;
41 * and turns all motors off
42 *
43 *************************************************************/
44 void RobotLinux::openSerial(int ser){
45 // serial names
46 const char *com1="/dev/ttyS0", *com2="/dev/ttyS1",
47 *com3="/dev/ttyS2", *com4="/dev/ttyS3";
48
49 struct termios options;
50
51 switch(ser) {
52 case 1: strcpy(serial,com1);
53 break;
54 case 2: strcpy(serial,com2);
55 break;
56 case 3: strcpy(serial,com3);
57 break;
58 case 4: strcpy(serial,com4);
59 break;
60 default: cout << "Error! valid ports are 1, 2, 3 and 4. "
61 << "Will try to open port 1." << endl;
62 }
63
64 fd = open(serial, O_RDWR|O_NOCTTY|O_NDELAY);
65 if (fd == -1) // ERROR!!
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 37
66 cout << "Error opening " << serial << endl;
67 else
68 fcntl(fd, F_SETFL, 0);
69 cout << "Serial port in use: " << serial << endl << endl;
70
71 // Program serial port to 9600, 8, 1, no parity
72 //
73
74 // Get the current options for the port
75 tcgetattr(fd, &options);
76
77 // Set the baud rate to 9600
78 cfsetispeed(&options, B9600);
79 cfsetospeed(&options, B9600);
80
81 // Enable the receiver and set local mode
82 options.c_cflag |= (CLOCAL | CREAD);
83
84 // Setting parity checking (no parity) 8N1
85 options.c_cflag &= ~PARENB; /* no parity */
86 options.c_cflag &= ~CSTOPB; /* 1 stop bit */
87 options.c_cflag &= ~CSIZE; /* Mask the character size bits */
88 options.c_cflag |= CS8; /* Select 8 data bits */
89
90 // Setting raw input
91 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
92
93 // Setting raw output
94 options.c_oflag &= ~OPOST;
95
96 // Set the new options for the port
97 tcsetattr(fd, TCSANOW, &options);
98
99 motorsOff(); // motors off
100 }
101
102 /************************************************************
103 * char sendCommand(char motorWord)
104 *
105 * gets a full word representing all inputs (1..8)
106 *************************************************************/
107 char RobotLinux::sendCommand(char motorWord){
108
109 char commandWord[2];
110 commandWord[0] = '\xc1'; // 1st byte: 193 in hexadecimal
111 commandWord[1] = motorWord; // 2nd byte: motorWord
112 int i;
113
114 if (fd == -1)
115 cout << "Erro: the serial port is closed. Please, "
116 << "use the openSerial() method to open it. " << endl;
117 else{
118 int n = write(fd, commandWord, 2); // send 2 bytes command & motors
119 if (n < 0)
120 cout << "Error! write() command and motor bytes failed." << endl;
121 else {
122 fcntl(fd, F_SETFL, FNDELAY);
123 i = read(fd, commandWord, 1); // read 1 Byte interface status
124 fcntl(fd, F_SETFL, 0);
125 commandWord[1] = 0; /* set end of string, so we can printf */
126 }
127 }
128 return commandWord[0];
129 }
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 38
• De forma semelhante ao exemplo de acesso direto ao hardware, a solucao
utilizada no caso da aplicacao para controle do braco robo foi a criacao de um
usuario especial pertencente ao grupo uucp, e a execucao dos programas para
acesso a serial (ao braco robo) realizada por esse usuario.
• A funcao fcntl na linha 68 e utilizada para configurar a porta serial para possiveis
operacoes de leitura. O flag F_SETFL e utilizado em conjunto com o terceiro
argumento para ativar ou desativar o modo de leitura da porta. Ao se utilizar 0
como terceiro argumento na funcao fcntl, uma operacao de leitura na porta serial
(read) ira bloquear a execucao do programa ate que um carcter seja recebido, um
intervalo de tempo expire, ou um erro ocorra. Para realizar leituras nao
bloqueantes na serial, utlizar o flag FNDELAY, no lugar do 0.
• Logo a seguir, na linha 78, a funcao cfsetispeed e utilizada para programar a porta
serial para velocidade de recepcao de 9600 bps. Na linha seguinte a funcao
cfsetospeed e utilizada para programar a porta serial para velocidade de
transmissao de 9600 bps.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 39
• O envio de comandos para o braco robo e realizado na linha 118 por intermedio
da funcao write que envia o comando a ser realizado, utilizando para isso o
descritor do arquivo aberto na linha 64. A funcao write funcao o numero de bytes
enviados, ou –1 caso tenha ocorrido um erro.
• Notar o uso do flag FNDELAY na funcao fcntl (linha 122) para configurar a
operacao de leitura nao-bloqueante do status da serial. Esse flag faz com que a
funcao read retorne 0, caso nao existam dados disponiveis para serem lidos na
porta serial.
• Caso o valor lido da porta nao e o esperado verificar, alem dos itens acima:
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 40
Porta Serial RS-232C
Acesso via API – commapi
linguagem Java – Win32 e Solaris
• A commapi e uma API que pode ser utilizada por desenvolvedores em programas
em Java para acesso as portas de entrada e saida (paralela e serial). Os arquivos
dessa API podem ser obtidos na pagina do curso (ver Exercicio 3 da aula pratica),
e tambem dicas de instalacao e utilizacao.
• Para instalar a commapi no Windows e preciso ter permissao de escrita no
diretorio onde o jdk esta instalado. Para realizar a instalacao executar os seguintes
passos (<jdk> e o caminho onde o jdk esta instalado):
o Copiar o arquivo win32com.dll para o diretorio <jdk>\jre\bin
o Copiar o arquivo comm.jar para o diretorio <jdk>\jre\lib\ext
o Copiar o arquivo javax.comm.properties para o diretorio <jdk>\jre\lib
• Uma dica extra e a execucao da aplicacao utilizando a virtual machine (java) que
se encontra no mesmo diretorio do arquivo win32com.dll (<jdk>\jre\bin). O
ambiente pode estar configurado para ser utilizado outro java, e nesse caso o
programa nao funcionara corretamente.
• A melhor forma de entender o funcionamento dessa API e por meio do estudo
das aplicacoes exemplo que acompanham os arquivos. Um bom ponto de partida
e a aplicacao “Serial Demo”. O arquivo README que acompanha essa aplicacao
contem dicas de compilacao e utilizacao.
• Na classe SerialConnection da aplicacao SerialDemo, observar:
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 41
Porta Paralela
acesso direto ao hardware – inportb, outportb
linguagem C – MS-DOS/Windows 9x
• A porta paralela pode ser acessada de forma semelhante a porta serial, utilizando
acesso direto ao hardware por intermedio da funcoes outportb (int porta,
unsigned char valor); e inportb (int porta);, como mostrado no programa a
seguir:
/* par_io.c - Programa em C para gerencia da porta paralela utilizando
acesso direto ao hardware pelas instrucoes IN e OUT.
int main(){
int opcao = 0;
unsigned char caracter = 0, aux;
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 42
Porta Paralela
Uso de interrupcoes – int 17H
linguagem C – MS-DOS/Windows 9x
• O programa a seguir utiliza a int 17H da BIOS para enviar o caracter ‘A’ para
uma impressora (ou dispositivo que se comporte como uma impressora)
conectada a porta paralela:
#include <dos.h>
#define INT_PARALELA 0x17
int main(){
union REGS r;
unsigned char caracter = 'A';
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 43
escrito nessa porta. Lembrar que o ASCII ‘A’ equivale a 41H ou 01000001 em
binario.
Porta Paralela
acesso direto ao hardware – inb, outb
linguagem C++ – Linux
/*
* Parallel Port Comunication
* (c)Diogo Becker de Brum, 2002
*
* Last change: 05/06/2003
* Changed by: Eduardo Augusto Bezerra
*
* compiler: g++ (as root)
*
* chmod 4755 ./a.out to allow users to open the parallel port
* using setuid (see below)
*/
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <sys/io.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
class Lpt {
public:
Lpt();
void init();
void send(char aByte);
char read();
void finish();
};
void Lpt::init(){
int a;
a = setuid(0);
printf("setuid = %d\n", a);
if (ioperm(BASEPORT, 2, 1)) {
perror("ioperm");
printf("Erro: Nao liberou a porta paralela!");
}
}
char Lpt::read(){
char a;
a = inb(BASEPORT);
usleep(DELAY);
return a;
}
void Lpt::finish(){
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 44
if (ioperm(BASEPORT, 2, 0))
{
perror("ioperm");
}
}
int main(){
int a = 0;
Lpt lpt;
lpt.init();
lpt.send((char)0x00);
printf("Leu: %d\n", lpt.read());
cin >> a;
lpt.send((char)0x55);
printf("Leu: %d\n", lpt.read());
cin >> a;
lpt.send((char)0x0FF);
printf("Leu: %d\n", lpt.read());
cin >> a;
lpt.send((char)0x80);
printf("Leu: %d\n", lpt.read());
cin >> a;
lpt.send((char)0x08);
printf("Leu: %d\n", lpt.read());
cin >> a;
lpt.send((char)0x01);
printf("Leu: %d\n", lpt.read());
cin >> a;
lpt.send((char)0x00);
printf("Leu: %d\n", lpt.read());
cin >> a;
lpt.finish();
}
Sockets
Acesso a dispositivo conectado a outro computador da rede
linguagem Java – Win32, Linux
Internet
Acesso usando browser com dispositivo conectado a
outro computador na Internet
linguagens HTML, Java, Servlet, C++ – J2EE, Win32 e Linux
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 45
• Todos os fontes que compoem essa aplicacao estao disponiveis para download
em:
http://www.inf.pucrs.br/~eduardob/disciplinas/extensao/Robot/WebRobot/
• Os seguintes diretorios contem os arquivos dessa aplicacao:
Client/
Contem robot_client.html que e o cliente em HTML. Notar na linha 141 a chamada
ao programa servlet RobotServlet.class para passar o conteudo dos campos do
formulario: <form method="POST" action="/robot/servlet/RobotServlet">. Essa
chamada e realizada quando o usuario pressiona “Submit” no browser.
servlet/
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 46
Contem RoboServlet.java que e o programa em Java (servlet) a ser executado no
servidor J2EE. Esse programa utiliza a classe HttpServletRequest para se comunicar
com o cliente HTML. Por exemplo, para obter o conteudo do campo Acao do
formulario, ou seja, movimento a ser realizado pelo braco robo, o programa utiliza:
String userAcao = (String)request.getParameter("Acao");
O servlet tambem realiza a conexao via sockets a maquina onde o robo esta
conectado. Para isso e preciso informar o endereco IP da maquina remota e a porta a
ser utilizada (linhas 64 e 65):
Apos isso basta criar a nova conexao socket (linha 73) e o stream de saida (linha 74):
try{
mySocket = new Socket(serverURL,porta);
out = new DataOutputStream(mySocket.getOutputStream());
in = new DataInputStream(mySocket.getInputStream());
Caso a maquina remota esteja desligada ou caso o servidor socket nao esteja em
execucao naquela maquina, entao mensagens de erro sao fornecidas ao usuario
(cliente HTML):
}catch (UnknownHostException e) {
outClient.println("<center><h2> ERRO: Nao encontrou host: ... </h2></center>");
}catch (IOException e) {
outClient.println("<center><h2>ERRO: Sem conexao de I/O para: </h2></center>");
}
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 47
programa em Java (JNI), que no caso sao openSerial e sendCommand. Notar a
sintaxe JNI utilizada nesse programa para a definicao das funcoes. O arquivo
RobotProxy.h e automaticamente gerado pelo compilador javah a partir do
RobotProxy.class (gerado a partir do Robot Proxy.java).
O programa em C++ por sua vez envia os comandos para o braco robo, utilizando o
protocolo definido pelo programa em execucao no microcontrolador no modulo de
controle do braco robo: envio de dois bytes. O primeiro byte sempre devera ser
0xc1, seguido pelo byte contendo o comando a ser realizado.
Para compilar o programa, utilizar o usuario serial (do grupo uucp) e executar o
Makefile:
make clean
make
Para executrar o servidor socket na maquina onde se encontra o braco robo, sempre
como usuario serial, executar o Makefile:
make runServer
• No mesmo endereco estao tambem arquivos com dicas de como realizar o deploy
da aplicacao no servidor J2EE (deploytool_HOWTO.html), e tambem o codigo
fonte em perl (perl_cgi) para processamento do formulario, caso nao tenha acesso
a um servidor J2EE:
http://www.inf.pucrs.br/~eduardob/disciplinas/extensao/Robot/WebRobot/
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 48
• Uma alternativa ao J2EE seria a utilizacao do Jboss (http://www.jboss.org),
totalmente gratuito, que pode ser executado diretamente na maquina onde o braco
robo se encontra. Nesse caso nao seria necessaria a comunicacao via sockets.
4. Exemplos de aplicacoes
• As chaves estao conectadas nos pinos de status (pinos 11, 10, 12 e 13 do DB-25),
sendo alimentadas pelo pino 9 do proprio conector DB-25. Assim, quando for
desejado realizar uma leitura nas chaves, e preciso antes colocar um nivel logico
alto (1) no pino 9 (D7) do conector DB-25.
• O endereco para escrita nos LEDs e o 378H e a leitura das chaves deve ser
realizada no endereco 379H.
• Componentes da placa:
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 49
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 50
d. RS232C via radio (wireless)
• Componentes da placa:
• Para realizar uma comunicação com envio e recepção de dados cada um dos
pontos deve ter um transmissor e um receptor;
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 51
J5
1
Antena Receptora
CONNECTOR_DB9 Receptor J2
1 gnd
6 U1 1
2 data 2
7 14 12 3 C5
3 13 T1OUT R1OUT 9 vcc5v 4
8 8 R1IN R2OUT 5 4.7n
4 7 R2IN 11 gnd 6
9 1u C1 T2OUT T1IN 10 ant 7
5 1 T2IN 8
3 C+
P1 4 C1-
C2 5 C2+ gnd
1u 2 C2- data 1
6 V+ D 12v 2 C6
C
C4 V- N C ant 3
G V 4 4.7n
C3 MAX232
1u 1u 5 6 Transmissor J1
1 1
VCC_CIRCLE
J4
1
0 Antena Transmissora
12v 5v gnd
J3
3 2 1
POWER
4. Exercicios praticos
Atividades
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 52
II. Controle do braco robo usando a linguagem C
Atividades
Atividades
Atividades
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 53
V. Comunicacao serial entre computador pessoal e placa com microcontrolador
Atividades
Atividades
onde: '?' e' um valor em hexadecimal para acender os LEDs conectados aos
reles (um rele' para cada LED). O valor 1 acendera' um LED. Ex: F acende todos os
LEDs, e 0 apaga todos os LEDs.
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 54
Alguns links de interesse
• Outra opcao (alem da commapi) para comunicacao serial em Java:
http://www.frii.com/~jarvi/rxtx/download.html
http://jusb.sourceforge.net/
http://www.beyondlogic.org/
• Mais informacao:
http://www.cera2.com/WebID/software/index.htm
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 55
• Interfacing the Enhanced Parallel Port (EPP)
RS-232 Interfacing
Acessando Dispositivos Externos com Computadores Pessoais, FACIN, PUC-RS, Porto Alegre, RS, Junho de 2003. 56