• Welcome to LusoRobótica - Robótica em Português.
 

Problemas com ADC PIC18F4550

Started by jbecg, 28 de July de 2010, 20:31

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

jbecg

Tenho um problema com o ADC interno do pic com que estou a trabalhar (18F4550). Programei o pic e agora preciso de fazer um pequeno teste, aplicar um valor de tensão DC na entrada que defini como analogica e pretendendo ver a respectiva conversão binária do valor de tensão aplicado. Isto realmente acontece, eu conisgo ver a conversão binária do valor de tensão. O meu problema esta na conversão permanente de um valor de tensão variavel, isto é, ligo na um fonte de tensão DC faço-a variar, e o que acontece é que na maioria das vez a conversão binária acompanha essa variação da tensão analógica, noutras só consigo obter o valor da conversão binária desse valor quando primo um botão que tenho no meu circuito para fazer o reset ao meu dispositivo. Creio que estou com um problema electrico, não tenho certeza, como tenho o meu ADC a funiconar e depois deixa de o fazer, creio que poderá ser isso. Alguém tem algumas dicas ou sugestões para mim?

O código para o meu ADC está aqui;

#include <pic18.h>
#include <stdio.h>
#include <htc.h>
#include <peripheral/adc.h>

void init(void);
void ADC (void);
void main(void)
{
init();
ADC();
while(1)
{
   while(GODONE);
   PORTD=ADRESH;//(justificado à esquerda --> ADRESH tem o conteudo dos 8 bits mais significativos da conversão)   
}
}

void init(void)
{
   TRISD=0x00;//Definicao do porto A como saida
   TRISA=0xFF;//Definicao do porto A como entrada
   PORTD=0x00;
}

void ADC (void)
{
   //1.Configuracao do modulo ADC
   //Configuracao dos pinos analogicos e tensao de referencia
   ADCON1=0b00001011; //Registo de configuração dos pinos do modulo ADC  -|-|VCFG1|VCFG0|PCFG3|PCFG2|PCFG1|PCFG0
   //-=0 Lido com 0
   //-=0 Lido com 0
   //VCFG1=0 VREF-=VSS se pretendermos VREF-!=VSS então (VREF-=AN2) o que implica VCFG1=1
   //VCFG0=0 VREF+=VDD se pretendermos VREF+!=VDD então (VREF+=AN3) o que implica VCFG1=1
   //PCFG3:PCFG0= 1110 so AN0 como entrada analogica (1011 AN0:AN3 entradas analógicas)
   // Se VREF+!=VDD então (VREF+=AN3) se VREF-!=VSS então (VREF-=AN2) o que implica PCFG3:PCFG0= 1011 (AN0:AN3 como entradas analogicas)
   
   //Seleccao do canal de entrada
   ADCON0=0b00000000; //Registo de controlo de funcionamento do ADC  -|-|CHS3|CHS2|CHS1|CHS0|GO//DONE|ADON
   //-=0 Lido com 0
   //-=0 Lido com 0
   //CHS3=CHS2=CHS1=CHS0=0   Entrada analogica Canal 0 (AN0)
   //GO//DONE=0              Estado da conversao (Com ADON=1: GO//DONE=1 (em conversao) GO//DONE=0 (inactivo)
   //ADON=0                  Ligar/Desligar o bloco ADC ADON=1(Activo) ADON=0(Desactivo)

   //Seleccao do tempo de aquisicao e frequencia de clock
   ADCON2=0b00000000 ;//Registo de configuração do sinal de clock, tempo de aquisicao e jsutificacao do modulo ADC  ADMF|-|ACQT2|ACQT1|ACQT0|ADCS2|ADCS1|ADCS0
   //ADMF=0 justificado a esquerda (se justificado a direita então ADMF=1)
   //-=0 Lido com 0
   //ACQT2:ACQT0= 000  bits de seleccao do tempo de aquisicao (Ver tempo de aquisicao pg. 269)
   //ADCS2:ADCS0= 000  bits de seleccao da frequencia de clock de conversao (Ver frequencia de conversao pg. 269)

   //Ligar o modulo ADC
   ADON=1;// (ADCON0)

   //2. Configurar a Interrupcao o modulo A/D(se desejado)--> Desactivar as interrupcoes (Incluindo as do modulo ADC)
   GIE=0; //(Global interruppts enable)

   //3. Esperar o tempo necessario de aquisicao (se necessario)

   //4. Iniciar a conversao
   GODONE=1;   //Activar GO//DONE=1 (ADCON0)
}   

jagsilva

Gostava de poder ajudar mas fiquei um pouco confuso com o texto e o código (tens um botão para inserir código que facilita a posterior leitura).
Que compilador estás a usar?

Já tinha postado um pequeno programa noutro tópico que acho que poderá servir para ti com pequenas modificações.
Vê aqui

Em relação ao teu código. Que faz isto? para que serve while(GODONE);?
while(1)
{
   while(GODONE);
   PORTD=ADRESH;//(justificado à esquerda --> ADRESH tem o conteudo dos 8 bits mais significativos da conversão)   
}
}


Tu dentro do ciclo while(1), na minha opinião, deverias ter:
-uma instrução para ler a entrada
-uma(s) para a trabalhar (enviar pela porta serie ou para o porto D)
-talvez uma pausa entre leituras

Qualquer duvida avisa.
jagsilva

jbecg

O botão no meu circuito serve somente para fazer o reset do dispositivo.

Estou a usar o hi-tech e basicamente o programa faz é converte uma tensão analógica para digital e envia o valor dos oito bits mais significativos para um porto, neste caso o porto D.

o GODONE é bit do registo ADCON0 que esta a 1 quando a conversão está em processo e a 0 quando a conversão está terminada.

Não percebi a parte da instrução para ler a entrada, uma(s) para a trabalhar e talvez uma pausa entre leituras. Será que é possivel esclarecer melhor esta situação ?

Obrigado.

Cumps,

jagsilva

não conheço esse compilador, por isso é que fiquei admirado com o GODONE, poque não vejo onde é que ele muda de estado.

Diz-me uma coisa: quantas conversões é que faz o teu circuito? uma? mais?

Sérgio_Sena

JBECG,

o GODONE é um pino com duas funções, e passivel de ESCRITA/LEITURA.

O que significa que quando queres arrancar com a conversão :: GODONE = 1.
Tens que aguardar que GODONE vá para ZERO.
Está tudo explicadinho no datasheet.

Assim, tens que juntar mais uma linha.

while(1)
{
     GODONE = 1;
     while(GODONE);
     PORTD=ADRESH;//(justificado à esquerda --> ADRESH tem o conteudo dos 8 bits mais significativos da conversão)   
}



Atenção que eu não vi mais nada do código. Apenas detectei este primeiro erro.
Vê se ajuda.

Conselho :: se não tiveres pressa, aumenta o tempo de aquisição, para estabilizar melhor o sinal de entrada.
Cumprimentos,
Sérgio Sena

Electronic Gear for Musicians

Instagram

jbecg

Obrigado, pela sugestão.

Depois de resolvido o problema do ADC, segue-se outro: enviar esses dados pela UART para conseguir comunicar com PC.  Sei que vou ter alguns problemas com a frequência de transmissão de dados uma vez que a frequência de conversão do ADC gera mts mais dados que aqueles que posso enviar pela porta série, mas esse é um passo mais à frente, o meu objectivo para já é enviar um sequencia de caracteres conhecido para poder trabalhar com a porta série e fazer o respectivo debug do circuito, neste sentido alguém tem sugestões?

Outra questão, trabalho com o hi-tech e sei que é possível utilizar o fontes de código que o próprio compilador já tem, o problema é que não sei como fazer, alguém me pode ajudar relativamente a isto?