OBJETIVOS
• Compreender a operação do conversor A/D do PIC;
• Aprender a utilizar as funções do drive de LCD ;
• Desenvolver uma IHM usando o LCD e o teclado da placa de experimentos;
CONVERSOR A/D
O módulo do conversor A/D possui 8 entradas analógicas, que possuem um capacitor de sample-
and-hold. A saída do sample-and-hold é conectada a entrada do conversor A/D a partir de um
multiplex 8 x 1. O conversor A/D gera uma palavra binária de 10 bits para representar o valor de
tensão na entrada analógica selecionada.
O módulo A/D tem duas entradas de tensão de referência (alta e baixa), que são selecionadas por
software, entre algumas opções de combinação pré-estabelecidas. Uma característica apenas
presente no módulo conversor A/D é que o mesmo pode operar mesmo o PIC estando no modo
SLEEP. Para operar neste modo o sinal de clock do conversor A/D (CAD) deve ser derivado do
oscilador RC interno do PIC.
O conversor A/D possui quatro registradores:
• Registrador do byte mais significado do resultado da conversão (ADRESH);
• Registrador do byte menos significado do resultado da conversão (ADRESL);
• Registrador de controle 0 (ADCON0) e
• Registrador de controle 1.
1
• Sete o bit GO/DONE (ADCON0)
5. Aguarde o tempo de conversão ter transcorrido;
• Realize um POLLING no bit GO/DONE, verificando se o seu valor é zero
(indicativo de fim de conversão A/D);
• ou aguarde pela interrupção gerada pelo módulo A/D ao fim da conversão;
6. Leia o par de registradores (ADRESH:ADRESL), resete o bit ADIF se a interrupção do
conversor A/D está sendo utilizada;
7. Para realizar uma nova conversão retorne ao passo 1 ou 2 (antes de uma nova conversão
ser iniciada, deve ser aguardado um tempo de 2TAD, que é o tempo de conversão por bit,
cujo valor é definido na tabela 1).
O conversor A/D necessita de no mínimo 12 TAD para realizar uma conversão de 10 bits. A fonte
do clock do conversor A/D é selecionada por software entre as possibilidades abaixo:
• 2Tosc
• 8Tosc
• 32Tosc
• Oscilador RC interno
Para uma conversão correta, o clock do conversor A/D deve ser selecionado para garantir um TAD
mínimo de 1.6µs. A tabela 1 mostra os valores de TAD em função da seleção da fonte do clock.
Se o bit GO/DONE for resetado durante uma conversão, esta será abortada. Os registradores de
resultado do módulo A/D não serão atualizados com a parcialmente concluída conversão. Assim,
os registradores ADRESH:ADRESL continuaram armazenando o valor da última conversão
concluída (ou o último valor escrito para os registradores ADRESH:ADRESL). Após uma
conversão ser abortada, um tempo de 2TAD é necessário antes de uma nova conversão ser
iniciada. Após este tempo, a aquisição do canal selecionado é automaticamente iniciada.
O par de registradores ADRESH:ADRESL comporta 16 bits, assim, o valor convertido de 10 bits
pode ser justificado a direita ou à esquerda, de acordo com o bit seleção de formato do conversor
A/D (ADFM), que controla a justificação. Os bits extras não utilizados são carregados com “0”
(zeros). Quando o módulo A/D não estiver sendo utilizado, os registradores ADRESH:ADRESL
podem ser usados como dois registradores de propósito geral de 8 bits.
2
Justificação do resultado da conversão A/D
3
Registrador ADCON0 - Controla a operação do módulo A/D.
4
Registrador ADCON1 – Configura a função dos pinos das portas (A e E)
Os registradores ADCON1 e TRIS controlam a operação dos pinos das portas A/D. Os pinos das
portas que serão entradas analógicas devem ter seus correspondentes bits TRIS setados. Se o bit
está resetado, o nível de tensão da saída digital será convertido. A operação do conversor A/D
independe do estado dos bits CHS2:CHS0 e dos bits TRIS
Observações:
1 – Quando o registrador da porta é lido, qualquer pino configurado como um canal de entrada
analógica será lido como zero (nível baixo). Pinos configurados como entradas digitais irão se
converter em entradas analógicas. Níveis analógicos em uma entrada configurada como digital,
não afetarão a precisão da conversão.
2 – Níveis analógicos em qualquer pino que é definido como uma entrada digital (incluindo os
pinos AN7:AN0) podem fazer com que o buffer de entrada consuma corrente que está fora das
especificações do dispositivo.
5
Registradores associados com o módulo do conversor A/D
/*=====================================================================
=======================================================================
ARQUIVO - DRIVER: LCD_16x2_LIB.C
DATA DE CRIAÇÃO: 03/11/2003
REVISÃO: 1.0
DATA DA ULTIMA REV: 03/12/2004
ULTIMA REV: 1.1
MICROCONTROLADOR: FAMILIA PIC
FUNÇÃO:
=======================================================================
=====================================================================*/
#ifndef CS_LCD
6
#endif
/*=====================================================================
FUNÇÃO: ENVIA_NIBBLE_LCD()
PARÂMETROS: BYTE, DADO...
RETORNO: BYTE, NENHUM.
=====================================================================*/
void envia_nibble_lcd( byte dado )
{
/*=====================================================================
FUNÇÃO: ENVIA_BYTE_LCD()
PARÂMETROS: BYTE, ENDERECO, DADO...
RETORNO: BYTE, NENHUM.
=====================================================================*/
void envia_byte_lcd( boolean endereco, byte dado )
{
7
output_low(CS_LCD); // Desabilita o Display.
envia_nibble_lcd(dado >> 4); // Envia a primeira parte do byte.
envia_nibble_lcd(dado & 0x0f); // Envia a segunda parte do byte.
}
/*=====================================================================
FUNÇÃO: INI_LCD()
PARÂMETROS: BYTE, NENHUM.
RETORNO: BYTE, NENHUM.
=====================================================================*/
void ini_lcd_16x2()
{
byte conta;
output_low(CS_LCD);
output_low(D4_LCD);
output_low(D6_LCD);
output_low(D7_LCD);
output_low(RS_LCD);
output_low(CS_LCD);
delay_ms(15);
envia_nibble_lcd(2);
/*=====================================================================
FUNÇÃO: XY_LCD()
PARÂMETROS: BYTE, X,Y.
RETORNO: BYTE, NENHUM.
=====================================================================*/
8
void posicao_xy_lcd( byte x, byte y)
{
byte endereco;
if(y != 1)
endereco = lcd_seg_lin;
else
endereco = 0;
endereco += x-1;
envia_byte_lcd(0,0x80|endereco);
}
/*====================================================================
FUNÇÃO: EXIBE_LCD()
PARÂMETROS: BYTE, C...
RETORNO: BYTE, NENHUM.
=====================================================================*/
void exibe_lcd( char caracter)
{
switch (caracter)
{
case '\f' : // Envia um byte de Comando de Limpar (CLEAR) o
//Display.
envia_byte_lcd(0,1);
delay_ms(2);
break;
case '\n' :
posicao_xy_lcd(1,2);
break;
case '\b' :
envia_byte_lcd(0,10);
break;
}
}
Referências
1 – PIC16F87X Datasheet – Microchip Technology Incorporated. USA. Nov 1999.
9
PREPARAÇÃO
1 – Descreva como ficam distribuídos os 10 bits da palavra digital gerada pelo conversor A/D,
após uma conversão, quando é utilizada a justificação à direita e a esquerda.
2 - Considerando que o conversor A/D realiza uma conversão de 10bits no tempo mínimo (12Tad)
e que o clock do PIC é de 4MHz, determine que opção para os bits ADCS2: ADCS1: ADCS0
deve ser escolhida na tabela 1, para essa freqüência de Clock e qual o tempo total de conversão,
baseado na seleção de ADCS2: ADCS1: ADCS0 e no clock do PIC.
3 - Descreva a operação realizada por cada uma das funções abaixo e também o que representa
cada opção dos parâmetros da função em termos do funcionamento do bloco ao qual a função está
associada (quando houver):
SETUP_ADC (mode)
mode: ADC_OFF
ADC_CLOCK_DIV_2
ADC_CLOCK_DIV_8
ADC_CLOCK_DIV_32
ADC_CLOCK_INTERNAL
SETUP_ADC_PORTS (value)
value: NO_ANALOGS
ALL_ANALOG
AN0_AN1_AN2_AN4_AN5_AN6_AN7_VSS_VREF – VRefh=A3
AN0_AN1_AN2_AN3_AN4
AN0_AN1_AN2_AN4_VSS_VREF – VRefh=A3
AN0_AN1_AN3
AN0_AN1_VSS_VREF – VRefh=A3
AN0_AN1_AN4_AN5_AN6_AN7_VREF_VREF – VRefh=A3 VRefl=A2
AN0_AN1_AN2_AN3_AN4_AN5
AN0_AN1_AN2_AN4_AN5_VSS_VREF – VRefh=A3
AN0_AN1_AN4_AN5_VREF_VREF – VRefh=A3 VRefl=A2
AN0_AN1_AN4_VREF_VREF – VRefh=A3 VRefl=A2
AN0_AN1_VREF_VREF – VRefh=A3 VRefl=A2
AN0
AN0_VREF_VREF – VRefh=A3 VRefl=A2
READ_ADC (mode)
mode: ADC_START_AND_READ
ADC_START_ONLY
ADC_READ_ONLY
SET_ADC_CHANNEL (chan)
4 – Elabore um programa em C para o PIC 16F877 que incremente uma variável do tipo “LONG”
a cada 524ms. Utilize a interrupção do “Overflow” do Timer 1, ajustando o Timer1 para gerar um
overflow no período indicado acima. Na rotina de interrupção devem ser implementadas as
seguintes operações:
a) Incremento da variável do tipo “LONG” a cada 524ms;
b) Escrita da mensagem “Contagem = <valor da variável “LONG”>”, na linha superior do
display, a cada 524ms. O termo entre < > corresponde ao valor da variável, que deve aparecer
após o texto “Contagem =”;
10
Implemente também uma rotina, utilizando a interrupção do “CAPTURE” do bloco CCPx, para
identificar quando um botão é pressionado (transição de 1 para 0). Na rotina do “CAPTURE”,
SET/RESET um flag (variável do tipo “SHORT”), que libera ou inibi o incremento do valor da
variável do tipo “LONG” na interrupção do Timer 2, segundo a seguinte lógica:
Flag setado (igual a 1) – libera contagem;
Flag resetado (igual a 0) – inibe contagem (congela a contagem);
A rotina deverá funcionar da seguinte forma: o flag inicia a execução com zero, quando o botão
for pressionado pela primeira vez, o seu valor muda para 1. Após uma segunda ativação do botão
o valor do flag volta para zero e na seqüência o mesmo fica trocando de estado cada vez que o
botão for pressionado.
5 – Escreva uma rotina em C que faça a leitura do valor de um sinal analógico aplicado na
entrada AN0 a cada 524 ms. A cada leitura o valor lido (de 10 bits) deve ser apresentado no
display através da seguinte mensagem: “Valor Lido: XXX”, onde os caracteres XXX
correspondem ao valor de 10 bits, no formato hexadecimal. Utilize a rotina de interrupção do
Timer1 da questão anterior para implementar a leitura/escrita da mensagem a cada 524ms
11