Transcript
ENTRADA E SAÍDA DIGITAL
Acionando / desativando uma saída digital
Na linguagem C padrão CCS, podemos realizar o controle de saídas
digitais uma a uma, ou através do PORT inteiro.
Para acionar uma saída digital, podemos usar a função
output_high(PINO), e para desativá-la, usamos a função output_low(PINO),
onde o PINO identifica qual o pino a ser acionado. Lembrando que os pinos
são agrupados em PORTs (no PIC16F877, são PORTA, PORTB, PORTC, PORTD e
PORTE). Observe na imagem ao lado.
Portanto, para se acionar a saída digital (PINO 16), basta utilizarmos
a instrução output_high(PIN_C1). Já, para desativar esta saída, usamos a
instrução output_low(PIN_C1).
Em baixo nível, o que esta função causa é o acerto do registrador de
direção (identificando que este pino é saída digital), e posteriormente a
modificação do nível lógico (ligado ou desligado) do pino em questão.
Isso, no entanto, pode ser obtido de outra forma, que chamamos de
endereçamento direto do pino. Desta forma, como em assembly, teremos que
determinar a direção do pino antes de usá-lo. Isso causa uma significativa
redução na memória consumida pelo programa para cada acionamento do pino.
Veja o exemplo:
void main()
{
TRIS_C0 = 0; // diz que o pino C0 será saída digital. 0 = output, 1 =
input.
TRIS_D2 = 0; // diz que o pino D2 será saída digital.
while(1) // identifica laço infinoto
{
PINO_C0 = 1; // liga C0
PINO_D2 = 0; // desliga D2
delay_ms(100); // tempo
PINO_C0 = 0; // desliga C0
PINO_D2 = 1; // liga D2
delay_ms(100); // tempo
}
}
Lendo uma entrada digital
Para identificar o estado de um pino, podemos proceder a leitura
usando a função input(PINO). Esta função retorna o estado digital do pino,
sendo 1 para nível alto (ligado), e 0 para nível baixo (desligado).
Por exemplo, para buscar o estado de um pino e armazená-lo em uma
variável, podemos usar :
ESTADO = input(PIN_b2);
Desta forma, a variável ESTADO (que deve ser previamente declarada)
irá receber o valor 1 caso o pino D0 estiver acionado, e 0 caso o pino D0
estiver desativado.
Outra forma mais comum de uso é junto à uma estrutura condicional ou
de repetição (que será aprofundada em tópicos futuros). Veja o exemplo no
trecho de programa abaixo:
void main ( ){
output_a(0);
while(1){
if ( input(PIN_b2) ) // se o pino b2 estiver acionado ...
{
output_high(PIN_a0); // liga C0
output_low(PIN_A4);
}
if ( ! input(PIN_b2) ) // se o pino A1 NÃO estiver acionado
{
output_high(PIN_A4); // liga A4
output_low(PIN_A0); // liga A5
}
}
}
ENDEREÇAMENO DIRETO PARA LEITURA DE ENTRADA DIGITAL
Da mesma forma que nas saídas digitais, podemos utilizar um pino
diretamente como entrada digital, sem o uso da função input. Isso torna o
programa mais eficiente, mas o programador deve lembrar de configurar o
pino para entrada digital antes de realizar a leitura.
Veja o exemplo:
#bit PINO_A0 = 0x05.0 // endereço físico de memória do PINO A0 para
o pic16f876
#bit PINO_B2 = 0x06.2 // endereço físico de memória do PINO B2 para
o pic16f876
#bit TRIS_A0 = 0x85.0 // registrador de direção do pino a0
#bit TRIS_B2 = 0x86.2 // registrador de direção do pino b2
void main()
{
TRIS_A0 = 0; // diz que o pino C0 será saída digital. 0 = output, 1 =
input.
TRIS_B2 = 1; // diz que o pino D2 será entrada digital.
output_a(0);
while(1) // identifica laço infinoto
{
if (! PINO_b2 == 1) // se o pino D2 estiver acionado
{
PINO_A0 = 1; // liga C0
delay_ms(100); // tempo
PINO_A0 = 0; // desliga C0
delay_ms(100); // tempo
}
}
}
ACIONANDO UM PORT INTEIRO
Para definir o estado de todos os pinos de um PORT podemos utilizar a
instrução output_x(valor), onde x deve ser substituído pela letra do PORT
correspondente, e valor é o valor binário a ser atribuído aos pinos.
Por exemplo, a instrução output_d(0x1F) irá ativar os pinos D0, D1,
D2, D3, D4 e desativar os pinos D5 ,D6, D7, pois :
0x1F é um valor expresso em hexadecimal, que convertido para binário
resulta em 00011111. Vide figura ao lado.
Portanto, para zerar todos os pinos do PORTC, em uma única linha de
instrução, podemos usar
output_c(0x00);
E para ativar todos os pinos do PORTD, em uma única instrução, podemos
usar:
output_d(0xFF);
LENDO UM PORT INTEIRO
Da mesma forma que podemos atribuir um valor a um PORT inteiro,
também podemos ler destes pinos e armazenar o valor lido em uma variável de
8 bits.
Dada uma variável X, declarada como um int, a linha
X = input_d();
Irá atribuir a variável o valor correspondente à combinação de sinais
de entrada dos pinos D0 a D7. Por exemplo, supondo que na execução esta
instrução, somente o pino D2 estava em nível lógico 1 (ligado), e os demais
pinos estavam desligados, a variável X passaria a valer 0x04 (em decimal,
4).
Exercícos
Observando os comentários do programa abaixo, complete as lacunas com a
instrução adequada e execute o programa na estação PLCPIC. Para a estação
CUSCOPiC, substitua os pinos A1, A2 e B3 respectivamente por D1, D2 e E2.
#include <16f877.h>
#use delay (clock=____________) // Verifique o valor do clock que irás
utilizar
void main()
{
while(1) // identifica laço infinoto
{
if (_________________) // se o pino A1 estiver acionado ...
{
______________________; // aciona o pino B3
delay_ms(50); // tempo de 50 milésimos de segundo
______________________; // desliga o pino B3
delay_ms(100); // tempo de 100 milésimos de segundo
}
if (_________________) // se o pino A2 estiver acionado ...
{
______________________; // aciona todos os bits do PORTD
}
if (_________________) // se o pino A3 estiver acionado ...
{
______________________; // desativa todos os bits do PORTD
}
}
}