Tutorial Modulo ADC
Tutorial Modulo ADC
Microprocessadores 2009/2010
Introdução
O mundo real é no seu todo um sistema analógico; a maioria das grandezas e variáveis
envolventes aos sistemas embebidos têm uma natureza e/ou uma interface analógica de algum
tipo. A temperatura, a pressão, a luminosidade, a humidade, uma tensão ou corrente eléctrica,
etc., são todos exemplos de grandezas analógicas que rodeiam e interferem no funcionamento
dos sistemas embebidos.
Por esta razão, a maioria dos microcontroladores existentes no mercado incluem nos seus
dispositivos periféricos internos módulos especiais que permitem esta interface de aquisição e
controlo analógico, que são respectivamente denominados por:
Um conversor analógico – digital (abreviado ADC) por definição é um dispositivo que converte
sinais analógicos contínuos em variáveis lógicas (digitais) discretas.
Neste caso, a variável digital de saída do conversor corresponde a uma palavra binária
directamente relacionada com o nível da grandeza analógica adquirida, seja tensão ou corrente
eléctrica.
Tal como se pode verificar através da Figura 1, o gráfico da função de transferência do ADC
não representa uma curva de correspondência contínua, mas antes uma curva discreta com
dados níveis bem definidos, que correspondem aos códigos resultantes da conversão.
Estes níveis definem o que é designado por resolução do conversor ADC, que é o número de
níveis ou códigos binários resultantes da conversão que o ADC consegue produzir ao longo de
uma dada gama de valores analógicos de entrada.
Dado que o resultado de uma conversão é normalmente expresso numa dada palavra binária, a
resolução de um conversor ADC é normalmente definida através do número de bits que
constituem essa palavra. Em consequência, o número de níveis ou códigos binários possíveis
numa conversão analógico – digital é definida como sendo: 𝑁 = 2𝑏𝑖𝑡𝑠 . Por exemplo, no caso da
figura anteriormente apresentada (Figura 1), pode-se concluir que o conversor ADC
correspondente tinha uma resolução de 3 bits, dado que existem 𝑁 = 23 = 8 níveis diferentes
na função de transferência.
Facilmente se depreende que quanto maior for a resolução do conversor, mais níveis (mais
codificações possíveis) existirão para a codificação de uma dada grandeza analógica, pelo que a
conversão será mais exacta, e a respectiva função de transferência apresentará uma curva mais
contínua, aproximando-se mais do sinal analógico real.
Nesta expressão, um LSB define o valor mínimo de tensão na entrada do conversor ADC que
pode ser convertido. Por outras palavras, define o valor em tensão a que corresponde cada bit da
palavra digital resultante da conversão.
Tendo o valor do LSB definido, pode ser feita a conversão inversa, isto é, determinar o valor
medido da grandeza analógica em função do resultante código binário da conversão, que é
assim definida pelo número de LSBs medidos (resultado da conversão), em função da tensão
correspondente a cada LSB, ou seja:
O erro de quantificação máximo de um conversor é dado por metade de um LSB, e define que o
valor real da grandeza medida pode estar compreendido entre o valor medido e um erro com
uma amplitude total de 1 LSB, ou seja:
Um outro parâmetro importante num conversor ADC e que depende directamente das
características do hardware e do tipo de implementação utilizado para a construção do ADC é o
chamado tempo de conversão, que define o período de tempo que decorre desde o inicio da
conversão até ser produzida a palavra digital correspondente. Em certas aplicações mais
exigentes, este parâmetro é um factor crítico a tomar em conta, pois pode influenciar o
desempenho do sistema, casos de sistemas que manipulem sinais de áudio e/ou vídeo.
tensão obtido com essa palavra com a tensão de entrada. Se 𝑉𝐷𝐴𝐶 > 𝑉𝐼𝑛 , então o bit
correspondente da conversão deve manter-se a „1‟, caso contrário o bit deve ser
colocado a „0‟. Fixando o valor desse bit com esta comparação, a conversão continua
efectuando o mesmo procedimento para o próximo bit mais significativo da conversão,
até se ter atingido o número de bits do conversor ADC:
Em antítese a um conversor ADC, que converte uma grandeza analógica numa dada palavra
digital, um conversor digital – analógico (abreviado DAC) é um dispositivo que converte uma
dada palavra digital num correspondente sinal analógico.
Tipicamente, um DAC converte uma dada palavra digital numa correspondente tensão ou
corrente eléctrica.
De uma forma semelhante ao caso dos conversores ADC, a codificação digital da variável
analógica pode ser feita de acordo com diferentes esquemas, por exemplo, codificação binária,
códigos de Gray ou ainda codificação binária em código de complementos de dois, sendo no
entanto vulgarmente utilizada a codificação binária simples.
Tal como acontece com um conversor ADC, um conversor DAC é igualmente caracterizado
pela resolução de conversão, que neste caso define o número de níveis (passos) de variação na
saída analógica em função da palavra digital de entrada.
Caso o conversor DAC seja um conversor em tensão, então a resolução do mesmo pode
igualmente ser expressa em termos da tensão, através da seguinte expressão:
Neste caso, um LSB define a variação de tensão na saída analógica do conversor que
corresponde à variação no bit menos significativo da palavra digital de entrada do conversor.
Analisando ainda a expressão indicada, as tensões de referência 𝑉𝑅𝐸𝐹+ e 𝑉𝑅𝐸𝐹− definem agora
respectivamente os limites máximo e mínimo da tensão de saída do conversor DAC.
Assim sendo, o valor da tensão analógica de saída do conversor DAC é definida como sendo
directamente proporcional à palavra digital de entrada do conversor, sendo a unidade de
conversão o valor de tensão correspondente a um LSB, isto é:
Tutorial - Módulo ADC Página 7 de 31
Departamento de Engenharia Electrotécnica
Microprocessadores 2009/2010
Binary-Weighted DAC, que consiste num esquema paralelo de resistências, todas elas
com um valor resistivo adequado ao peso do bit na palavra digital de entrada, e cuja
soma das correntes individuais produz, à saída do amplificador operacional, a tensão de
saída do conversor:
Pino Função
RA0/AN0 Canal 0 do módulo ADC
RA1/AN1 Canal 1 do módulo ADC
RA2/AN2/VREF- Canal 2 do módulo ADC / Tensão de referência negativa
RA3/AN3/VREF+ Canal 3 do módulo ADC / Tensão de referência positiva
RA5/AN4 Canal 4 do módulo ADC
RE0/AN5 Canal 5 do módulo ADC
RE1/AN6 Canal 6 do módulo ADC
RE2/AN7 Canal 7 do módulo ADC
RB2/AN8 Canal 8 do módulo ADC
RB3/AN9 Canal 9 do módulo ADC
RB1/AN10 Canal 10 do módulo ADC
RB4/AN11 Canal 11 do módulo ADC
RB0/AN12 Canal 12 do módulo ADC
1
Imagem retirada de [Link]
Tutorial - Módulo ADC Página 10 de 31
Departamento de Engenharia Electrotécnica
Microprocessadores 2009/2010
Ao módulo ADC estão ainda associados os seguintes registos, que regulam e controlam o seu
funcionamento:
Registo ADCON0
--- --- CHS3 CHS2 CHS1 CHS0 GO/*DONE ADON
Registo ADCON1
--- --- VCFG1 VCFG0 PCFG3 PCFG2 PCFG1 PCFG0
Registo ADCON2
ADFM --- ACQT2 ACQT1 ACQT0 ADCS2 ADCS1 ADCS0
ADRESH (ADC Result High Register) e ADRESL (ADC Result Low Register) –
Registos auxiliares que retornam o resultado obtido da conversão digital do sinal
analógico lido, contendo respectivamente o byte mais significativo e o byte menos
significativo da conversão.
Assim sendo, o programador deverá configurar estes bits em conformidade com os canais
analógicos que pretende utilizar, garantindo que esses canais são configurados como entradas
analógicas. As restantes linhas, se não utilizadas pelo módulo ADC do microcontrolador,
deverão ser definidas como linhas digitais comuns.
Para o correcto funcionamento do módulo ADC, é necessário que seja definido um relógio de
conversão, que define o período de tempo necessário para efectuar uma conversão de 1 bit.
Este período de tempo 𝑇𝐴𝐷 deve definido de tal forma a que seja no mínimo 0.7 us e, no
máximo, 25us.
2
𝑇𝐴𝐷 = 𝐹
𝑂𝑆𝐶
4
𝑇𝐴𝐷 = 𝐹
𝑂𝑆𝐶
8
𝑇𝐴𝐷 = 𝐹
𝑂𝑆𝐶
16
𝑇𝐴𝐷 = 𝐹
𝑂𝑆𝐶
32
𝑇𝐴𝐷 =
𝐹𝑂𝑆𝐶
64
𝑇𝐴𝐷 =
𝐹𝑂𝑆𝐶
1
𝑇𝐴𝐷 = 𝐹 , onde 𝐹𝑅𝐶 define a frequência do oscilador interno do módulo ADC. Neste
𝑅𝐶
Tendo definido este tempo 𝑇𝐴𝐷 , e de acordo com as características do conversor ADC do
microcontrolador PIC, o tempo necessário até se obter os 10 bits resultantes da conversão é
definido como sendo 𝑇𝑐𝑜𝑛𝑣 = 11 × 𝑇𝐴𝐷 , ou seja, o tempo de conversão é igual ao número de
bits da resolução do conversor multiplicado pelo tempo de conversão de cada bit 𝑇𝐴𝐷 , mais um
tempo 𝑇𝐴𝐷 .
O tempo de aquisição 𝑇𝐴𝐶𝑄 deve ser configurado para ser no mínimo 1.4us, sendo fornecidos ao
programador as seguintes opções de configuração, parametrizáveis através dos bits
ACQT<2:0> do registo ADCON2:
𝑇𝐴𝐶𝑄 = 0𝑇𝐴𝐷
𝑇𝐴𝐶𝑄 = 2𝑇𝐴𝐷
𝑇𝐴𝐶𝑄 = 4𝑇𝐴𝐷
𝑇𝐴𝐶𝑄 = 6𝑇𝐴𝐷
𝑇𝐴𝐶𝑄 = 8𝑇𝐴𝐷
𝑇𝐴𝐶𝑄 = 12𝑇𝐴𝐷
𝑇𝐴𝐶𝑄 = 16𝑇𝐴𝐷
𝑇𝐴𝐶𝑄 = 20𝑇𝐴𝐷
Considerando agora este tempo de aquisição, então o tempo total de conversão, desde a selecção
do canal analógico até à obtenção do resultado da conversão é definido por:
Ainda considerando este tempo, o diagrama temporal da conversão pode então ser representado
tal como na Figura 12.
Tomemos em consideração uma dada entrada analógica cuja gama de tensões varia entre +1V e
+3V. Utilizando as tensões de referência do microcontrolador, então o LSB da conversão seria
5−0
𝐿𝑆𝐵 = 210
≅ 4.88𝑚𝑉, o que para a gama de variação do sinal analógico, equivale a uma
3 1
resolução de 4.88×10 −3 − 4.88×10 −3 ≅ 410 𝑝𝑎𝑠𝑠𝑜𝑠 = 8.68𝑏𝑖𝑡𝑠.
As linhas de tensão de referência do conversor ADC estão mapeadas nas linhas de I/O
RA2/AN2/VREF- e RA3/AN3/VREF+, sendo que a linha 𝑉𝑅𝐸𝐹− corresponde ao limite inferior
(valor mínimo) e 𝑉𝑅𝐸𝐹+ corresponde ao limite superior (valor máximo) da gama de tensões a
referenciar para a conversão.
2
Imagem retirada de [Link]
Tutorial - Módulo ADC Página 16 de 31
Departamento de Engenharia Electrotécnica
Microprocessadores 2009/2010
A configuração das referências de tensão na conversão do módulo ADC é feita através dos bits
VCFG1:VCFG0 do registo ADCON1, garantindo que as linhas AN2VREF- e AN3/VREF+ estão
devidamente configuradas como entradas analógicas por meio dos bits PCFG<3:0>, também
no registo ADCON1.
3
Imagem retirada de [Link]
Tutorial - Módulo ADC Página 17 de 31
Departamento de Engenharia Electrotécnica
Microprocessadores 2009/2010
1. Configurar os pinos a utilizar como entradas analógicas, definindo a direcção de entrada nos
correspondentes tristate buffers;
2. Configurar as linhas de I/O como entradas analógicas, através do registo ADCON1;
3. Configurar quais as fontes das tensões de referência para o conversor ADC, se as tensões de
alimentação do microcontrolador, se as tensões nas linhas 𝑉𝑅𝐸𝐹+ e 𝑉𝑅𝐸𝐹−, através do registo
ADCON1;
4. Configurar o relógio de funcionamento do módulo ADC, através do registo ADCON2;
5. Configurar o tempo de aquisição no registo ADCON2;
6. Definir o formato de saída do resultado do ADC (justificado à direita ou à esquerda),
através do bit ADFM do registo ADCON2;
7. Habilitar o módulo ADC, através do bit ADON do registo ADCON0;
Após a configuração do módulo ADC, a conversão deve ser feita seguindo o seguinte
procedimento:
Esta biblioteca, que fica disponível ao programador através da inclusão do header file “adc.h”
providencia as seguintes funções:
Função Descrição
BusyADC Verifica se o conversor ADC está ocupado a realizar uma conversão.
CloseADC Desabilita o módulo ADC.
ConvertADC Dá a ordem para início de uma nova conversão no ADC.
OpenADC Configura e habilita o módulo ADC.
ReadADC Lê o resultado de uma conversão terminada do ADC.
SetChanADC Selecciona o canal ADC a utilizar.
Consulte a documentação das bibliotecas do compilador C18 para maior detalhe sobre como
utilizar as referidas funções.
/**
* Departamento de Engenharia Electrotécnica - ESTG
* Microprocessadores
*
* Tutorial Módulo ADC - Exemplo 1
*
* - Configuração e aquisição de uma entrada analógica
*/
#include <p18f4520.h>
#include <stdio.h>
#include <adc.h>
#include <delays.h>
#include "xlcd.h"
/**
* Calcula o valor de tensão na entrada analógica em função
* do resultado da respectiva conversão, e em função dos
* limites para a entrada.
*
* @param min Valor mínimo de tensão na conversão.
* @param max Valor máximo de tensão na conversão.
* @param read Resultado da conversão da entrada analógica.
*
* @return O valor da tensão na entrada analógica.
*/
static float scale(float min, float max, unsigned int read)
{
float res;
return res;
}
/**
* Imprime o valor da tensão na entrada analógica
* no ecrã LCD.
*
* @param val Valor, em tensão, da entrada analógica.
*/
static void print_lcd(float val)
{
Tutorial - Módulo ADC Página 20 de 31
Departamento de Engenharia Electrotécnica
Microprocessadores 2009/2010
int unit;
int decimal;
char str[5];
/*
* a função 'sprintf' das bibliotecas do compilador C18
* não suporta a conversão de valores em vírgula flutuante, com
* os literais '%f' e/ou "%lf", logo temos de manualmente fazer
* essa conversão
*/
unit = (int)val;
decimal = (int)((float)(val - (float)unit) * 100.0F);
return;
}
/**
* Ponto de entrada da aplicação.
*/
void main(void)
{
unsigned int read;
float volt;
/*
* inicialização dos portos de I/O
*/
/*
* linha RA0 como entrada analógica (CH0)
* restantes linhas não usadas
*/
TRISA = 0xFF;
/* porto B não usado */
TRISB = 0xFF;
/* porto C não usado */
TRISC = 0xFF;
/* porto D utilizado para o LCD */
TRISD = 0;
/* porto E não usado */
TRISE = 0x07;
/*
* inicialização do LCD
*/
OpenXLCD(FOUR_BIT & LINES_5X7);
while (BusyXLCD());
WriteCmdXLCD(DON & CURSOR_OFF & BLINK_OFF);
Tutorial - Módulo ADC Página 21 de 31
Departamento de Engenharia Electrotécnica
Microprocessadores 2009/2010
while (BusyXLCD());
WriteCmdXLCD(SHIFT_CUR_RIGHT);
while (BusyXLCD());
/* limpa LCD */
WriteCmdXLCD(CLEAR);
while (BusyXLCD());
/*
* configuração do módulo ADC
*
* - relógio de conversão configurado para Fosc/4 -> TAD = 1us
* - resultado da conversão justificado à direita
* - tempo de aquisição (sample & hold) de 4 ciclos do relógio
* de conversão TACQ = 4us
*
* - selecção inicial do canal 0 (AN0/CH0)
* - desactivação da interrupção de fim de conversão ADIF
* - VREF+ a VDD (+5V) e VREF- a GND (0V)
*
* - Port Cfg Bits = 0x0E (CH0 analógica, restantes digitais)
*/
OpenADC(ADC_FOSC_4 & ADC_RIGHT_JUST & ADC_4_TAD,
ADC_CH0 & ADC_INT_OFF & ADC_REF_VDD_VSS,
0x0E);
/* escreve linha 1 */
WriteCmdXLCD(LINE1);
while (BusyXLCD());
putrsXLCD("Conversao A/D CH0");
while (BusyXLCD());
/* escreve linha 2 */
WriteCmdXLCD(LINE2);
while (BusyXLCD());
putrsXLCD("Valor = -.--[V]");
while (BusyXLCD());
/*
* ciclo infinito
*/
while (1) {
/*
* não é necessário fazer a selecção de canal, dado que
* só estamos a adquirir uma entrada analógica,
* previamente seleccionada na chamada a OpenADC.
* Assim sendo, é só necessário dar a ordem de
* início de conversão
*/
ConvertADC();
/* aguarda fim da conversão */
while (BusyADC());
/* faz a leitura do resultado da conversão */
read = ReadADC();
/*
* limpa a flag de interrupção manualmente,
* para futuras chamadas a BusyADC
Tutorial - Módulo ADC Página 22 de 31
Departamento de Engenharia Electrotécnica
Microprocessadores 2009/2010
*/
[Link] = 0;
/* aguarda 500 ms */
Delay10KTCYx(50);
}
/**
* Departamento de Engenharia Electrotécnica - ESTG
* Microprocessadores
*
* Tutorial Módulo ADC - Exemplo 2
*
* - Configuração e aquisição de várias entradas analógicas,
* fazendo a selecção e conversão alternada das mesmas
*/
#include <p18f4520.h>
#include <stdio.h>
#include <adc.h>
#include <delays.h>
#include "xlcd.h"
/**
* Calcula o valor de tensão na entrada analógica em função
* do resultado da respectiva conversão, e em função dos
* limites para a entrada.
*
* @param min Valor mínimo de tensão na conversão.
* @param max Valor máximo de tensão na conversão.
* @param read Resultado da conversão da entrada analógica.
*
* @return O valor da tensão na entrada analógica.
*/
static float scale(float min, float max, unsigned int read)
{
float res;
return res;
}
/**
* Imprime o valor da tensão na entrada analógica
* no ecrã LCD.
*
* @param val1 Valor, em tensão, da entrada analógica do canal CH0.
* @param val2 Valor, em tensão, da entrada analógica do canal CH1.
*/
static void print_lcd(float val1, float val2)
{
int unit;
int decimal;
char str_ch0[5];
char str_ch1[5];
/*
* a função 'sprintf' das bibliotecas do compilador C18
* não suporta a conversão de valores em vírgula flutuante, com
* os literais '%f' e/ou "%lf", logo temos de manualmente fazer
* essa conversão
*/
unit = (int)val1;
decimal = (int)((float)(val1 - (float)unit) * 100.0F);
sprintf(str_ch0, "%01d.%02d", unit, decimal);
unit = (int)val2;
decimal = (int)((float)(val2 - (float)unit) * 100.0F);
sprintf(str_ch1, "%01d.%02d", unit, decimal);
return;
}
/**
* Ponto de entrada da aplicação.
*/
void main(void)
{
unsigned int read_ch0;
unsigned int read_ch1;
float volt_ch0;
float volt_ch1;
/*
* inicialização dos portos de I/O
*/
/*
* linha RA0 como entrada analógica (CH0),
* linha RA1 como entrada analógica (CH1),
* restantes linhas não usadas
*/
TRISA = 0xFF;
/* porto B não usado */
TRISB = 0xFF;
/* porto C não usado */
TRISC = 0xFF;
/* porto D utilizado para o LCD */
TRISD = 0;
/* porto E não usado */
TRISE = 0x07;
/*
* inicialização do LCD
*/
OpenXLCD(FOUR_BIT & LINES_5X7);
while (BusyXLCD());
WriteCmdXLCD(DON & CURSOR_OFF & BLINK_OFF);
while (BusyXLCD());
WriteCmdXLCD(SHIFT_CUR_RIGHT);
while (BusyXLCD());
/* limpa LCD */
WriteCmdXLCD(CLEAR);
while (BusyXLCD());
Tutorial - Módulo ADC Página 25 de 31
Departamento de Engenharia Electrotécnica
Microprocessadores 2009/2010
/*
* configuração do módulo ADC
*
* - relógio de conversão configurado para Fosc/4 -> TAD = 1us
* - resultado da conversão justificado à direita
* - tempo de aquisição (sample & hold) de 4 ciclos do relógio
* de conversão TACQ = 4us
*
* - selecção inicial do canal 0 (AN0/CH0)
* - desactivação da interrupção de fim de conversão ADIF
* - VREF+ a VDD (+5V) e VREF- a GND (0V)
*
* - Port Cfg Bits = 0x0D (CH0 analógica, CH1 analógica,
* restantes digitais)
*/
OpenADC(ADC_FOSC_4 & ADC_RIGHT_JUST & ADC_4_TAD,
ADC_CH0 & ADC_INT_OFF & ADC_REF_VDD_VSS,
0x0D);
/* escreve linha 1 */
WriteCmdXLCD(LINE1);
while (BusyXLCD());
putrsXLCD("Valor CH0 = -.--[V]");
while (BusyXLCD());
/* escreve linha 2 */
WriteCmdXLCD(LINE2);
while (BusyXLCD());
putrsXLCD("Valor CH1 = -.--[V]");
while (BusyXLCD());
/*
* ciclo infinito
*/
while (1) {
/* selecciona o canal CH0 */
SetChanADC(ADC_CH0);
/*
* não é necessário aguardar para a entrada estabilizar,
* dado que já foi definido um tempo de aquisição
* (Tacq) de 4Tad...
*/
/* inicia conversão */
ConvertADC();
/* aguarda fim da conversão */
while (BusyADC());
/* faz a leitura do resultado da conversão */
read_ch0 = ReadADC();
/*
* limpa a flag de interrupção manualmente,
* para futuras chamadas a BusyADC
*/
[Link] = 0;
/* aguarda 500 ms */
Delay10KTCYx(50);
}
/**
* Departamento de Engenharia Electrotécnica - ESTG
* Microprocessadores
*
* Tutorial Módulo ADC - Exemplo 3
*
* - Aquisição de uma entrada analógica, configurando as linhas
* AN2/VREF- e AN3/VREF+ como tensões de referência para a
* entrada analógica
*/
#include <p18f4520.h>
#include <stdio.h>
#include <adc.h>
#include <delays.h>
#include "xlcd.h"
/**
* Calcula o valor de tensão na entrada analógica em função
* do resultado da respectiva conversão, e em função dos
* limites para a entrada.
*
* @param min Valor mínimo de tensão na conversão.
* @param max Valor máximo de tensão na conversão.
* @param read Resultado da conversão da entrada analógica.
*
* @return O valor da tensão na entrada analógica.
*/
static float scale(float min, float max, unsigned int read)
{
float res;
return res;
}
/**
* Imprime o valor da tensão na entrada analógica
* no ecrã LCD.
*
* @param val Valor, em tensão, da entrada analógica.
*/
static void print_lcd(float val)
{
int unit;
int decimal;
char str[5];
/*
* a função 'sprintf' das bibliotecas do compilador C18
* não suporta a conversão de valores em vírgula flutuante, com
* os literais '%f' e/ou "%lf", logo temos de manualmente fazer
* essa conversão
*/
unit = (int)val;
decimal = (int)((float)(val - (float)unit) * 100.0F);
return;
}
/**
* Ponto de entrada da aplicação.
*/
void main(void)
{
unsigned int read;
float volt;
/*
* inicialização dos portos de I/O
*/
/*
* linha RA0 como entrada analógica (CH0),
* linha RA2 como tensão de referência negativa (VREF-),
* linha RA3 como tensão de referência positiva (VREF+),
* restantes linhas não usadas
*/
TRISA = 0xFF;
/* porto B não usado */
TRISB = 0xFF;
/* porto C não usado */
TRISC = 0xFF;
/* porto D utilizado para o LCD */
TRISD = 0;
/* porto E não usado */
TRISE = 0x07;
Tutorial - Módulo ADC Página 29 de 31
Departamento de Engenharia Electrotécnica
Microprocessadores 2009/2010
/*
* inicialização do LCD
*/
OpenXLCD(FOUR_BIT & LINES_5X7);
while (BusyXLCD());
WriteCmdXLCD(DON & CURSOR_OFF & BLINK_OFF);
while (BusyXLCD());
WriteCmdXLCD(SHIFT_CUR_RIGHT);
while (BusyXLCD());
/* limpa LCD */
WriteCmdXLCD(CLEAR);
while (BusyXLCD());
/*
* configuração do módulo ADC
*
* - relógio de conversão configurado para Fosc/4
* - resultado da conversão justificado à direita
* - tempo de aquisição (sample & hold) de 4 ciclos
* do relógio de conversão
*
* - selecção inicial do canal 0 (AN0/CH0)
* - desactivação da interrupção de fim de conversão ADIF
* - AN2 como VREF-, AN3 como VREF+
*
* - Port Cfg Bits = 0x0B (CH0, CH1, CH2 e CH3 analógicas,
* restantes digitais)
*/
OpenADC(ADC_FOSC_4 & ADC_RIGHT_JUST & ADC_4_TAD,
ADC_CH0 & ADC_INT_OFF & ADC_REF_VREFPLUS_VREFMINUS,
0x0B);
/* escreve linha 1 */
WriteCmdXLCD(LINE1);
while (BusyXLCD());
putrsXLCD("Conversao A/D CH0");
while (BusyXLCD());
/* escreve linha 2 */
WriteCmdXLCD(LINE2);
while (BusyXLCD());
putrsXLCD("Valor = -.--[V]");
while (BusyXLCD());
/*
* ciclo infinito
*/
while (1) {
/*
* não é necessário fazer a selecção de canal, dado que
* só estamos a adquirir uma entrada analógica,
* préviamente seleccionada na chamada a OpenADC.
* Assim sendo, é só necessário dar a ordem de início
* de conversão
*/
Tutorial - Módulo ADC Página 30 de 31
Departamento de Engenharia Electrotécnica
Microprocessadores 2009/2010
ConvertADC();
/* aguarda fim da conversão */
while (BusyADC());
/* faz a leitura do resultado da conversão */
read = ReadADC();
/*
* limpa a flag de interrupção manualmente,
* para futuras chamadas a BusyADC
*/
[Link] = 0;
/*
* converte o valor da conversão em tensão
* dado que usamos AN2 e AN3 para VREF- e VREF+, os
* limites de tensão são então definidos pelas tensões
* nessas linhas, que são respectivamente 1V e 4V.
*/
volt = scale(1.0F, 4.0F, read);
/* aguarda 500 ms */
Delay10KTCYx(50);
}