PROGRAMANDO A PORTA SERIAL USANDO API DO WINDOWS NA LINGUAGEM C.

Documentos relacionados
Linguagem C Princípios Básicos (parte 1)

Algoritmos e Programação

Sistemas Operacionais. Entrada/Saída

LINGUAGEM DE PROGRAMAÇÃO C AULA 2. Professor: Rodrigo Rocha

Exercícios de Sistemas Operacionais 3 B (1) Gerência de Dispositivos de Entrada e Saída

Organização e Arquitetura de Computadores I

Programação: Vetores

Gerência de Dispositivos. Adão de Melo Neto

Manual do Usuário Brother Meter Read Tool

Manual do usuário - Kit 4EA2SA v2.0. Kit 4EA2SA v2.0 Manual do usuário. Copyright VW Soluções

Organização e Arquitetura de Computadores I

Programação I A Linguagem C. Prof. Carlos Alberto

Arquitetura Von Neumann Dados e instruções são obtidos da mesma forma, simplificando o desenho do microprocessador;

Notas da Aula 14 - Fundamentos de Sistemas Operacionais

Algoritmos e Estruturas de Dados. Prof. Marcelo Zorzan Profa. Melissa Zanatta

SSC510 Arquitetura de Computadores 1ª AULA

Sistemas Operacionais. Sistema de entrada e Saída

Introdução a Programação. Ponteiros e Vetores, Alocação Dinâmica

Aula 12: Memória: Barramentos e Registradores

ecos - Gestores de dispositivos

Tipos Básicos. Operadores de Incremento e Decremento. Operador Sizeof. Estruturas de Dados Aula 2: Estruturas Estáticas

Linguagem C: Introdução

Unidade II FUNDAMENTOS DE SISTEMAS OPERACIONAIS. Prof. Victor Halla

Gerência de Dispositivos. Adão de Melo Neto

Estrutura e Funcionamento dos Computadores (Conceitos Básicos)

Métodos Computacionais. Vetores e Matrizes Dinâmicas

Algoritmos e Estruturas de Dados I (DCC/003) Introdução à Programação de Computadores. Aula - Tópico 1

Introdução à Programação

Algoritmos e Estruturas de Dados I (DCC/003) Estruturas Básicas. Aula Tópico 2

Entrada/Saída. Capítulo 5. Sistemas Operacionais João Bosco Junior -

Algoritmos e Programação

Capítulo 6: Arquivos

Programação em C. Variáveis e Expressões. Universidade Federal do Rio Grande do Norte Departamento de Engenharia de Computação e Automação

Redes Industriais. Carlos Roberto da Silva Filho, M. Eng.

Sistemas Operacionais e Introdução à Programação. Programação com linguagem C

Sub Rotinas. Estrutura de Dados. Prof. Kleber Rezende

Estrutura de Dados. Aula 07 Alocação Dinâmica

Universidade Federal de Uberlândia Faculdade de Computação. Linguagem C: ponteiros e alocação dinâmica

Algoritmos e Estruturas de Dados I (DCC/003) 2013/1. Estruturas Básicas. Aula Tópico 4

Aula 09. Módulos de Entrada e Saída

Introdução à Programação. Introdução a Linguagem C. Prof. José Honorato F. Nunes

Periféricos possuem características diferentes. Periféricos são mais lentos que UCP e Memória Necessita-se de módulos de Entrada/Saída

Barramento. Prof. Leonardo Barreto Campos 1

PCS-2529 Introdução aos Processadores. Prof. Dr. Paulo Sérgio Cugnasca

Entrada e Saída e Dispositivos

3. Linguagem de Programação C

Problemas com Entrada e Saída

4. Estruturas Fundamentais de Programação em C

Introdução a Programação de Jogos

4 Arquitetura Adotada

Comunicação. Rotinas da dll

LINGUAGEM C: FUNÇÕES FUNÇÃO 04/07/2017. Funções são blocos de código que podem ser nomeados e chamados de dentro de um programa.

Algoritmos e Técnicas de Programação Introdução Givanaldo Rocha de Souza

Introdução à Programação. Operadores, Expressões Aritméticas e Entrada/Saída de Dados

CAP. IX - MANIPULAÇÃO DE ARQUIVOS Generalidades sobre Arquivos. 9.2 Abertura e Fechamento de Arquivos. Operações com arquivos:

BARRAMENTO DO SISTEMA. Adão de Melo Neto

Dispositivos de Entrada e Saída

Organização de Computadores

Introdução à Linguagem C Variáveis e Expressões

Projeto de Algoritmos

FUNDAMENTOS DE ARQUITETURAS DE COMPUTADORES SISTEMAS DE COMPUTAÇÃO. Cristina Boeres

Sistema de entrada e saída (E/S)- Módulos de E/S; tipos de operações de E/S

Vetores. e o programa deverá ler os valores separadamente:

Tecnólogo em Análise e Desenvolvimento de Sistemas. Sistemas Operacionais (SOP A2)

Introdução à Programação

Manual do InCD Reader

Aula 5 Oficina de Programação Introdução ao C. Profa. Elaine Faria UFU

Introdução aos Algoritmos

LINGUAGEM C: FUNÇÕES FUNÇÃO 08/01/2018. Funções são blocos de código que podem ser nomeados e chamados de dentro de um programa.

Puca Huachi Vaz Penna

Estruturas da linguagem C. 1. Identificadores, tipos primitivos, variáveis e constantes, operadores e expressões.

Métodos Computacionais

AULA TEÓRICA 3 Tema 2. Introdução a programação em Java (JVM, JDK)

Ambiente de desenvolvimento

1 Exercícios com ponteiros

ORGANIZAÇÃO DE COMPUTADORES

Transcrição:

PROGRAMANDO A PORTA SERIAL USANDO API DO WINDOWS NA LINGUAGEM C. Para elaborar um programa em linguagem C que realize a comunicação com a porta serial, podemos utilizar algumas funções/comandos da API (Application Programming Interface) do próprio Windows. Usar a API torna a programação mais fácil e evita que o programa desenvolvido possa prejudicar outros que estiverem em execução simultaneamente no ambiente Windows. Além disso, o programador não precisa conhecer detalhes específicos do hardware pois os programas de aplicação limitam-se apenas a pedir ao sistema operacional que execute determinadas tarefas. O controle do hardware é feito através de pequenos programas especiais denominados drivers. Para cada um dos periféricos do computador, tem de existir um driver apropriado. O uso de drivers permite trocar e atualizar periféricos facilmente, desde que também se troque o respectivo driver fornecido pelo fabricante. Os programas de aplicação se comunicam com o sistema operacional através da Application Programming Interface (API). Tal como o nome sugere, trata-se de uma interface de software que permite a comunicação nos dois sentidos. Normalmente, os compiladores utilizados pelo programadores possuem bibliotecas que tomam conta das chamadas à API. No caso do Turbo C++ 4.5, a biblioteca windows.h possui funções, tipos de dados, e estruturas de dados definidas para tomar conta dessas chamadas. A descrição detalhada da API está normalmente incluída no kit de desenvolvimento do sistema operacional (SDK) e, muitas vezes, pode ser baixada gratuitamente da Internet. Os programas de aplicação só se comunicam com o sistema operacional. Portanto, o programador não necessita saber como o sistema operacional realiza internamente o trabalho que lhe foi solicitado pelo programa de aplicação, mas tem de conhecer em detalhes a forma de fazer os pedidos. A API passa os pedidos para o núcleo do sistema operacional (kernel), que toma as medidas necessárias para atender os pedidos. Quando um programa de aplicação pede para um determinado componente do hardware ser utilizado, o kernel serve-se do driver do componente. É o driver que se comunica diretamente com o hardware. Desse modo, o programador também não necessita conhecer em profundidade o hardware. A comunicação entre o driver e o kernel não é feita através da API, mas sim da System Programming Interface (SPI) que é um outro modo de comunicação. Algumas funções da API para controlar a Porta Serial no Turbo C++ 4.5 estão descritas na tabela abaixo: Nome OpenComm CloseComm ReadComm WriteComm BuildCommDCB SetCommState GetCommState GetCommError Uso Abrir uma porta de comunicação seqüencial (ou paralela). Fechar uma porta de comunicação especificada e liberar toda a memória alocada para suas filas de transmissão e recepção, após enviar todos os caracteres remanescentes na fila de transmissão. Ler um número especificado de bytes de uma porta de comunicação. Escrever caracteres numa porta de comunicação. Traduzir um texto de definição de parâmetros de uma porta de comunicação para o formato apropriado para preenchimento de uma estrutura (variável) do tipo bloco de controle de dispositivo. Aplicar parâmetros de configuração a uma porta de comunicação. (Configurar a porta de comunicação) Obter os valores dos parâmetros de configuração de uma porta de comunicação Recuperar o valor do último código de erro ocorrido e o estado de uma porta especificada, além dos números de dados presentes nas filas de entrada e saída. UMC Universidade de Mogi das Cruzes - Professor Rodrigo 1

Usar chamadas à API do Windows em programas de aplicação exige que todos os valores dos parâmetros de configuração sejam armazenados em uma única variável. Isso pode ser obtido através de variáveis do tipo struct. Cada uma das variáveis que compõem a variável struct é chamada de campo do registro, ou simplesmente campo. Como a API tem o papel de facilitar o trabalho do programador, você não precisa declarar a variável do tipo struct pois a biblioteca windows.h já tem pronta a declaração do tipo de dado DCB. Uma variável do tipo de dado DCB é um registro com campos para diversos parâmetros de configuração de portas de comunicação. Segue abaixo a descrição de alguns dos campos do registro que armazenará os valores dos parâmetros de configuração da porta de comunicação serial e como fazer o acesso a esses campos. Campo id Descrição Especifica o dispositivo de comunicação. Este valor é ajustado pelo driver do dispositivo. Se o bit mais significativo for 1, a estrutura especifica um dispositivo de comunicação paralela BaudRate Especifica a taxa de baud na qual operarão os dispositivos de comunicação. Se o valor do byte mais significativo for igual a 0xFF, o byte menos significativo especifica o índice da taxa de baud, que pode ser um dos seguintes valores: CBR_110 CBR_6000 CBR_19200 CBR_4400 CBR_28000 CBR_9200 CBR_9600 CBR_8400 CBR_14400 CBR_256000 CBR_38400 CBR_56000 CBR_128000 Se o byte mais significativo for diferente de 0xFF, este parâmetro especifica a taxa de baud real. ByteSize Parity StopBits Especifica o número de bits nos caracteres transmitidos e recebidos. Este campo pode conter qualquer um dos números inteiros de 4 até 8. Especifica o esquema de paridade usado. Este campo pode conter qualquer um dos seguintes valores: Valor EVENPARITY MARKPARITY NOPARITY ODDPARITY Significado Par Marca Sem paridade Ímpar Especifica a duração do bit de parada a ser usado. Este campo pode ter um dos seguintes valores: Valor Significado 0, ONESTOPBIT Duração igual à de 1 bit 1, ONE5STOPBITS Duração de 1,5 bit 2, TWOSTOPBITS Duração de 2 bits Para fazer acesso a um desses campos basta especificar o nome da variável seguido de um ponto final seguido do nome do campo. Por exemplo, para armazenar o valor 1200 no campo BaudRate de uma variável do tipo DCB chamada confporta digite o comando: confporta.baudrate = 1200. Para exibir o valor armazenado no campo StopBits pode ser usado o comando: printf( StopBits = %d\n,confporta.stopbits). UMC Universidade de Mogi das Cruzes - Professor Rodrigo 2

O programa exemplo a seguir mostra como abrir a porta de comunicação COM1, obter os valores dos seus parâmetros de configuração, e exibir alguns dos valores obtidos. Observe o uso das chamadas às funções da API, e o acesso aos campos da variável registro confporta. if (GetCommState(idporta,&confporta) < 0) printf( Erro ao obter os valores dos parâmetros de configuração\n ); printf( Alguns valores de parâmetros de configuração:\n ); printf( Taxa de transferência = %d bps\n,confporta.baudrate); printf( Tamanho do dado = %d bits\n,confporta.bytesize); printf( Paridade= ); if (confporta.parity == NOPARITY) printf( Nenhum\n ); if (confporta.parity == ODDPARITY) printf( Impar\n ); if (confporta.parity == EVENPARITY) printf( Par\n ); printf( StopBits = %d\n,confporta.stopbits); return 0; /* fim do programa */ A função OpenComm tenta alocar uma porta de comunicação para o seu programa. Obviamente, ela precisa saber qual das portas é a desejada. Isso justifica a especificação COM1. Os outros dois parâmetros especificam os tamanhos (em bytes) das filas de entrada e saída, respectivamente, para a porta. Essas filas são áreas de memória que a porta utilizará para se comunicar com seu programa. Como os dados podem chegar à porta a qualquer momento, pode acontecer de um dado chegar quando seu programa não estiver no ponto de tratá-lo. Para evitar que o dado fique parado bloqueando a porta, este é imediatamente transferido para uma área da memória do computador conhecida como fila de entrada. Quando seu programa estiver pronto para tratar o dado, ele o procurará na fila de entrada. Também pode ocorrer do seu programa desejar transmitir um dado quando a porta estiver ocupada. Neste caso, ao invés de bloquear o programa até que a porta esteja disponível, o dado é colocado na fila de saída, de onde será retirado pela porta para ser transmitido no momento oportuno. Dados podem ser perdidos caso os tamanhos especificados para essas filas sejam pequenos para as necessidades do programa. Caso a porta esteja disponível para uso do seu programa, a função OpenComm retornará um número inteiro, fornecido pelo driver do dispositivo, e que será usado como identificador da porta. Caso a porta não esteja disponível (não instalada ou já alocada para outro programa), a função retornará um valor menor do que zero. Isso justifica a necessidade do teste (comando if) após o uso da função OpenComm. A função GetCommState obtém os valores dos parâmetros de configuração da porta identificada pelo valor da variável idporta e deve armazená-los em alguma variável registro do tipo DCB. Daí a necessidade de especificar o identificador da porta e a variável (endereço da variável) que armazenará os valores obtidos. A função CloseComm fecha a porta de comunicação identificada pelo valor da variável idporta. UMC Universidade de Mogi das Cruzes - Professor Rodrigo 3

O próximo programa mostra como abrir uma porta de comunicação série e ajustar seus parâmetros de configuração usando as funções BuildCommDCB e SetCommState. if (BuildCommDCB( COM1:1200,n,7,1,&confporta) < 0) printf( Erro ao codificar os valores dos parâmetros de configuração\n ); if (SetCommState(&confporta) < 0) printf( Erro ao ajustar os parâmetros de configuração\n ); return 3; /* o programa só executa as linhas abaixo se a nova configuração estiver estabelecida */ if (GetCommState(idporta,&confporta) < 0) printf( Erro ao obter os valores dos parâmetros de configuração\n ); return 4; printf( Alguns dos novos valores dos parâmetros de configuração:\n ); printf( Taxa de transferência = %d bps\n,confporta.baudrate); printf( Tamanho do dado = %d bits\n,confporta.bytesize); printf( Paridade= ); if (confporta.parity == NOPARITY) printf( Nenhum\n ); if (confporta.parity == ODDPARITY) printf( Impar\n ); if (confporta.parity == EVENPARITY) printf( Par\n ); printf( StopBits = %d\n,confporta.stopbits); return 0; /* fim do programa */ A função BuildCommDCB apenas interpreta um texto contendo valores de parâmetros de configuração e armazena esses valores nos campos apropriados de uma variável registro do tipo DCB. O texto deve especificar o nome da porta (COM1) seguido de um sinal dois-pontos, seguido da taxa de transferência desejada (1200), do tipo de verificação de paridade (n = nenhum), do tamanho do dado (7 bits por dado), e da duração do bit de parada (1). Deve-se usar a função SetCommState, em seguida à BuildCommDCB, para aplicar os novos valores dos parâmetros de configuração armazenados na variável registro do tipo DCB à porta. O próximo programa ilustra uma técnica, conhecida como polling, para ler dados transmitidos por um dispositivo ligado à porta de comunicação serial. Esta técnica consiste em ficar consultando a porta sobre a chegada de um dado. Quando a consulta indicar que algum dado está disponível então a leitura é feita. A determinação da presença de dados na porta é feita através de uma chamada à função GetCommError, a qual recupera o valor do último código de erro ocorrido e o estado da porta, além das quantidades de dados presentes nas filas de entrada e de saída. Os valores retornados pela função GetCommError devem ser armazenados em uma única variável. Como já explicado anteriormente, esta UMC Universidade de Mogi das Cruzes - Professor Rodrigo 4

variável deve ser do tipo registro (struct). A biblioteca windows.h já tem declarado um tipo de dado registro para armazenar essas informações; trata-se do tipo COMSTAT. Abaixo estão relacionados os campos desse registro. Campo Flags CbInQue CbOutQue Descrição Contém os códigos dos erros ocorridos e o estado da porta Contém o número de dados presentes na fila de entrada. Contém o número de dados presentes na fila de saída Sabendo que existem dados disponíveis na fila de entrada de uma porta de comunicação seqüencial, a leitura desses dados pode ser feita usando-se a função ReadComm. Antes de testar o programa que lê dados da porta, lembre-se que é preciso ligar algum dispositivo que envie dados pela porta seqüencial. Supõe-se, aqui, que você tenha um mouse adicional (2º mouse) ligado à porta COM1. Este será o dispositivo que enviará dados para o seu programa. Para evitar que o Windows instale um segundo mouse no seu sistema, só conecte o mouse adicional à porta COM1 após a carga completa do sistema operacional. O mouse serial padrão monitora dois botões e dois sensores de movimento. Sempre que um ou mais desses componentes monitorados sofre uma alteração, o mouse envia para a porta seqüencial três bytes de dados, nos quais são informadas as situações dos botões e informados os deslocamentos horizontal e vertical do dispositivo. O mouse transmite a uma taxa de 1200 bps, usando 7 bits para cada dado, sem verificação de paridade, e com bit de parada de mesma duração dos demais bits (1 stopbit). COMSTAT estadoporta; /* registro com informações de estado da porta */ char dado[3]; /* local onde ficarão os dados lidos da porta */ if (BuildCommDCB( COM1:1200,n,7,1,&confporta) < 0) printf( Erro ao codificar os valores dos parâmetros de configuração\n ); if (SetCommState(&confporta) < 0) printf( Erro ao ajustar os parâmetros de configuração\n ); return 3; /* a repetição abaixo caracteriza a técnica de polling */ do GetCommError(idporta,&estadoporta); while (estadoporta.cbinque < 3); /* espera até que existam pelo menos 3 dados na fila */ printf( Primeiros 3 dados lidos:\n ); ReadComm(idporta, dado, 3); printf( 1: %x\n2: %x\n3: %x\n,dado[0],dado[1],dado[2]); return 0; UMC Universidade de Mogi das Cruzes - Professor Rodrigo 5