Este é o nosso 9º tutorial sobre como aprender microcontroladores PIC usando MPLAB e XC8. Até agora, cobrimos muitos tutoriais básicos como introdução ao MPLABX, LED piscando com PIC, temporizadores em PIC, interface de LCD, interface de 7 segmentos, etc. Se você for um iniciante absoluto, visite a lista completa de tutoriais de PIC aqui e comece a aprender.
Neste tutorial, aprenderemos como usar ADC com nosso microcontrolador PIC PICF877A. A maioria dos projetos de Microcontroladores envolverá um ADC (Conversor Analógico para Digital), por ser uma das formas mais utilizadas de leitura de dados do mundo real. Quase todos os sensores como sensor de temperatura, sensor de fluxo, sensor de pressão, sensores de corrente, sensores de tensão, giroscópios, acelerômetros, sensor de distância e quase todos os sensores ou transdutores conhecidos produzem uma tensão analógica de 0V a 5V com base na leitura dos sensores. Um sensor de temperatura, por exemplo, pode fornecer 2,1 V quando a temperatura for 25 ° C e subir para 4,7 quando a temperatura for 60 ° C. Para saber a temperatura do mundo real, o MCU precisa apenas ler a tensão de saída desse sensor de temperatura e relacioná-la com a temperatura do mundo real. Portanto, ADC é uma ferramenta de trabalho importante para projetos MCU e vamos aprender como podemos usá-lo em nosso PIC16F877A.
Verifique também nossos artigos anteriores sobre o uso de ADC em outros microcontroladores:
- Como usar ADC no Arduino Uno?
- Tutorial do Raspberry Pi ADC
- Interface do ADC0808 com o microcontrolador 8051
ADC no microcontrolador PIC PIC16F877A:
Existem muitos tipos de ADC disponíveis e cada um tem sua própria velocidade e resolução. Os tipos mais comuns de ADCs são flash, aproximação sucessiva e sigma-delta. O tipo de ADC usado em PIC16F877A é chamado de ADC de aproximação Sucessiva ou SAR em resumo. Portanto, vamos aprender um pouco sobre o SAR ADC antes de começar a usá-lo.
ADC de aproximação sucessiva: O ADC de SAR funciona com a ajuda de um comparador e algumas conversas lógicas. Este tipo de ADC usa uma tensão de referência (que é variável) e compara a tensão de entrada com a tensão de referência usando um comparador e a diferença, que será uma saída digital, é salva a partir do bit mais significativo (MSB). A velocidade da comparação depende da frequência do relógio (Fosc) na qual o PIC está operando.
Agora que sabemos alguns princípios básicos sobre ADC, vamos abrir nossa folha de dados e aprender como usar o ADC em nosso MCU PIC16F877A. O PIC que estamos usando tem ADC de 8 canais de 10 bits. Isso significa que o valor de saída de nosso ADC será 0-1024 (2 ^ 10) e há 8 pinos (canais) em nosso MCU que podem ler a tensão analógica. O valor 1024 é obtido por 2 ^ 10, pois nosso ADC é de 10 bits. Os oito pinos que podem ler a tensão analógica são mencionados na folha de dados. Vamos dar uma olhada na foto abaixo.
Os canais analógicos AN0 a AN7 são destacados para você. Apenas esses pinos serão capazes de ler a tensão analógica. Portanto, antes de ler uma tensão de entrada, temos que especificar em nosso código qual canal deve ser usado para ler a tensão de entrada. Neste tutorial, usaremos o canal 4 com um potenciômetro para ler a tensão analógica neste canal.
O módulo A / D tem quatro registradores que devem ser configurados para ler dados dos pinos de entrada. Esses registros são:
• Registro alto do resultado A / D (ADRESH)
• Registro baixo de resultado A / D (ADRESL)
• Registro de controle A / D 0 (ADCON0)
• Registro de controle A / D 1 (ADCON1)
Programação para ADC:
O programa para usar ADC com Microcontrolador PIC é muito simples, basta entender esses quatro registradores e então ler qualquer tensão analógica será simples. Como de costume, inicialize os bits de configuração e vamos começar com o void main ().
Dentro do void main () , temos que inicializar nosso ADC usando o registrador ADCON1 e o registrador ADCON0. O registro ADCON0 possui os seguintes bits:
Neste registro temos que ligar o módulo ADC tornando ADON = 1 e ligar o relógio de conversão A / D usando os bits ADCS1 e ADCS0, o resto não será definido por enquanto. Em nosso programa, o relógio de conversão A / D é selecionado como Fosc / 16, você pode tentar suas próprias frequências e ver como o resultado muda. Detalhes completos disponíveis na página 127 do datasheet. Portanto, ADCON0 será inicializado da seguinte maneira.
ADCON0 = 0b01000001;
Agora o registro ADCON1 tem os seguintes bits:
Neste registro, temos que fazer A / D Result Format Select bit high por ADFM = 1 e fazer ADCS2 = 1 para selecionar o Fosc / 16 novamente. Os outros bits permanecem zero, pois planejamos usar a tensão de referência interna. Detalhes completos disponíveis na folha de dados página 128. Portanto, ADCON1 definiremos como segue.
ADCON1 = 0x11000000;
Agora, depois de inicializar o módulo ADC dentro de nossa função principal, vamos entrar no loop while e começar a ler os valores ADC. Para ler um valor ADC, as seguintes etapas devem ser seguidas.
- Inicialize o Módulo ADC
- Selecione o canal analógico
- Inicie o ADC aumentando o valor Go / Done
- Aguarde até que o bit Go / DONE baixe
- Obtenha o resultado ADC do registro ADRESH e ADRESL
1. Inicialize o Módulo ADC: Já aprendemos como inicializar um ADC, então apenas chamamos esta função abaixo para inicializar o ADC
A função void ADC_Initialize () é a seguinte.
void ADC_Initialize () {ADCON0 = 0b01000001; // ADC ON e Fosc / 16 é selecionado ADCON1 = 0b11000000; // A tensão de referência interna é selecionada}
2. Selecione o canal analógico: Agora temos que selecionar qual canal vamos usar para ler o valor ADC. Vamos fazer uma função para isso, para que ele vai ser fácil para nós para alternar entre cada canal dentro da enquanto loop.
unsigned int ADC_Read (unsigned char channel) {// **** Selecionando o canal ** /// ADCON0 & = 0x11000101; // Limpando os bits de seleção de canal ADCON0 - = canal << 3; // Definindo os bits necessários // ** Seleção de canal concluída *** ///}
Então o canal a ser selecionado é recebido dentro do canal variável. Na linha
ADCON0 & = 0x1100101;
A seleção de canal anterior (se houver) é desmarcada. Isso é feito usando o operador bit a bit e “&”. Os bits 3, 4 e 5 são forçados a ser 0, enquanto os outros são deixados em seus valores anteriores.
Em seguida, o canal desejado é selecionado deslocando para a esquerda o número do canal três vezes e definindo os bits usando o bit a bit ou o operador “-”.
ADCON0 - = canal << 3; // Definindo os bits necessários
3. Inicie o ADC tornando o bit Go / Done alto: Uma vez que o canal é selecionado, temos que iniciar a conversão ADC simplesmente tornando o bit GO_nDONE alto:
GO_nDONE = 1; // Inicializa a conversão A / D
4. Aguarde até que o bit Go / DONE fique baixo: O bit GO / DONE permanecerá alto até que a conversão ADC seja concluída, portanto, temos que esperar até que esse bit fique baixo novamente. Isso pode ser feito usando um enquanto loop.
while (GO_nDONE); // Aguarde a conclusão da conversão A / D
5. Obtenha o resultado ADC do registro ADRESH e ADRESL: Quando o bit Go / DONE fica baixo novamente, significa que a conversão ADC está completa. O resultado do ADC será um valor de 10 bits. Como nosso MCU é um MCU de 8 bits, o resultado é dividido em 8 bits superiores e 2 bits inferiores. O resultado de 8 bits superior é armazenado no registro ADRESH e o resultado de 2 bits inferior é armazenado no registro ADRESL. Portanto, temos que adicioná-los aos registradores para obter nosso valor ADC de 10 bits. Este resultado é retornado pela função conforme mostrado abaixo:
return ((ADRESH << 8) + ADRESL); // Returns Result
A função completa que é usada para selecionar o canal ADC, acionar o ADC e retornar o resultado é mostrada aqui.
unsigned int ADC_Read (unsigned char channel) {ADCON0 & = 0x11000101; // Limpando os bits de seleção de canal ADCON0 - = canal << 3; // Definir os bits necessários __delay_ms (2); // Tempo de aquisição para carregar o capacitor de retenção GO_nDONE = 1; // Inicializa a conversão A / D enquanto (GO_nDONE); // Aguarde a conclusão da conversão A / D return ((ADRESH << 8) + ADRESL); // Returns Result}
Agora temos uma função que tomará a seleção do canal como entrada e nos retornará o valor ADC. Por isso podemos chamar directamente esta função dentro do nosso enquanto circuito, uma vez que estamos a ler a voltagem analógica a partir do canal 4 neste tutorial, a chamada função será como se segue.
i = (ADC_Read (4)); // armazena o resultado de adc em “i”.
Para visualizar a saída de nosso ADC, precisaremos de algum tipo de módulo de exibição como o LCD ou o de 7 segmentos. Neste tutorial, estamos usando um display de 7 segmentos para verificar a saída. Se você quiser saber como usar 7 segmentos com foto siga o tutorial aqui.
O código completo é fornecido abaixo e o processo também é explicado no Vídeo ao final.
Configuração e teste de hardware:
Como de costume simule o código usando Proteus antes de realmente ir com nosso hardware, o esquema do projeto é mostrado abaixo:
As conexões do módulo de display de 7 segmentos de 4 dígitos com microcontrolador PIC são as mesmas do projeto anterior, acabamos de adicionar um potenciômetro ao pino 7 que é o canal analógico 4. Variando o potenciômetro, uma tensão variável será enviada ao MCU que será lido pelo módulo ADC e exibido no módulo de display de 7 segmentos. Verifique o tutorial anterior para aprender mais sobre o display de 7 segmentos de 4 dígitos e sua interface com o PIC MCU.
Aqui usamos a mesma placa de microcontrolador PIC que criamos no tutorial de LED piscando. Depois de garantir a conexão, carregue o programa no PIC e você deverá ver uma saída como esta
Aqui, lemos o valor ADC do potenciômetro e o convertemos para a tensão real mapeando a saída 0-1024 como 0-5 volts (conforme mostrado no programa). O valor é então exibido no segmento de 7 e verificado com o multímetro.
Pronto, agora estamos prontos para usar todos os Sensores Analógicos disponíveis no mercado, vá em frente e experimente e se você tiver algum problema como de costume use a seção de comentários, teremos o maior prazer em ajudá-lo.