Ir ao conteúdo
  • Cadastre-se

Conversor ADC pic 16f876 só lê canal 0


Posts recomendados

Olá boa tarde a todos, estou com um projeto de um voltímetro aqui que esta meio enrolado. :confused:

Ele funciona assim: é um voltímetro de 7 segmentos x 3 dígitos e mede de 0  a 500 volts no canal 0.

Ele funciona tudo OK, porém, eu quero ler um outro pino do adc que não seja o canal 0, qualquer outro pino do adc e não consigo de nenhuma maneira!!

Meu conhecimento em programação é bem curto, não consigo resolver ele.

Este projeto tem partes que eu peguei da web de um voltímetro que usava o 16f873 ai eu mudei para o 876 fiz mais umas gambiaras para que em determinada tensão ligue e desligue alguns leds e tudo funcionou, mas trocar de canal do adc nem matando ele :mad: .

Segue cod em ccs.

 

A quem quiser me ajudar qualquer ideia, sugestão é bem vinda.

   #include <16F876.h>   #device ADC=10    #fuses NOWDT, XT PUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD   #use delay(clock=4000000)   #use fast_io(A)   #use fast_io(   #use fast_io(C)   #DEFINE   Q1   PIN_B0                   // display 3   #DEFINE   Q2   PIN_B1                   // display 2   #DEFINE   Q3   PIN_B2                   // display 1   #BYTE    display=7   long  valor;   float volts;   int   a;  //------------------------------------------------------------------------------   struct digito_separados    {         //variavel em bcd  unidade dezena centena   int  unidade, dezena, centena;   }    digito;//------------------------------------------------------------------------------   struct dados    {                 // variavel de dados entrada e saida   int  dados1, dados2, resultado;   }   numeros;//------------------------------------------------------------------------------   void separar_digitos(){      // separa resultado en unidade, dezena, centena     int   temp;     digito.unidade=0;     digito.dezena=0;     temp=numeros.resultado;     while(temp>=10){       temp-=10;       digito.dezena++;     }     digito.unidade=temp;   }//------------------------------------------------------------------------------   void mostrar()   {               int const bcd_7seg[10]= {0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7B};      int contador;           //0    1     2    3    4    5    6    7    8    9      output_low(Q1);      output_low(Q2);      output_low(Q3);       for(contador=0;contador<11;contador++)         {         display=bcd_7seg[digito.unidade];           //mostra unidade         output_high(Q1);         delay_ms(5);         output_low(Q1);         delay_cycles(4);         display=bcd_7seg[digito.dezena];            //mostra dezena         output_high(Q2);         delay_ms(5);         output_low(Q2);         delay_cycles(4);         display=bcd_7seg[digito.centena];           //mostra centena         output_high(Q3);         delay_ms(5);         output_low(Q3);         delay_cycles(4);         }    }//------------------------------------------------------------------------------void main()   {   set_tris_a(0x00000001);     //canal 0 entrada restante saida   output_a(0b00000000);        // limpa    set_tris_b(0x00000000);     //tudo saida   output_b(0b00000000);        //limpa   set_tris_c(0x00000000);     //tudo saida               output_C(0b00000000);        //limpa     setup_adc_ports(ALL_ANALOG);   setup_adc(ADC_CLOCK_DIV_2);   set_adc_channel(0);   d:    valor = Read_ADC();  //  adcon1=0x0e;   delay_us(20);   volts=0.00488758*(float)valor;   a=(int)volts;   //------------------------------------------------------------------------------            if (valor>=430)// maior que   {   output_b(0b10000000);   }   //---------------------------------------------------------------------------   if (valor>=450)// maior que   {     output_b(0b01000000);   }   //---------------------------------------------------------------------------   if (valor>=470)// maior que   {   output_b(0b00100000);   }   //---------------------------------------------------------------------------   if (valor>=491)// maior que   {   output_b(0b00010000);   }   //---------------------------------------------------------------------------   if (valor>=511)// maior que   {   output_b(0b00001000);   }   //---------------------------------------------------------------------------   if (valor<=420)// menor que   {   output_b(0b00000000);   }   //---------------------------------------------------------------------------   if (valor>=515)// maior que   {   output_b(0b00000000);   }   //------------------------------------------------------------------------------   digito.centena=a;   volts=volts-(float)a;   numeros.resultado=(int)(100.0*volts);   separar_digitos();   mostrar();   goto  d;}

post-596061-0-51746900-1420142446_thumb.

Link para o comentário
Compartilhar em outros sites

Olá Fervolt muito grato pela ajuda, olha até funcionou, consegui trocar de canal an0, an1, an2, etc porém,,,,  :D  olha só que praga :mad: por exemplo eu seto o canal 0

vou la no proteus e funciona.

No potenciometro para ajustar a tensão acerto ele para ler 220V, ta OK funciona, ai ,,,, eu vou la no ccs e seto o canal 1 compila e tal. no proteus sem mexer no potenciometro apenas troco o pino an0 por an1 .

teclo F12, funcionou, porém ele indica apenas 100V  :mad:  :muro:  

Vou continuar mexendo, uma hora vai aparecer o grilo que tem aqui.  

Link para o comentário
Compartilhar em outros sites

Você descomentou a linha do delay? caso não, tente!

Seu esquema está meio estranho, não entendi o porque daqueles 2 pots daquele jeito. Coloque a referencia nos pots adequadamente, pino superior -> Power(vcc), pino do meio -> canal AD e pino inferior -> GND(0v).

Para usar os vários canais, não precisa ficar mudando o código e compilando, crie variáveis para receber o valor de cada canal, como por exemplo:

int16 adc0, adc1, adc2;//em algum ponto dentro de main()set_adc_channel(0);delay_us(15);adc0 = read_adc();set_adc_channel(1);delay_us(15);adc1 = read_adc();set_adc_channel(2);delay_us(15);adc2 = read_adc();//...//segue o código

Att,

Link para o comentário
Compartilhar em outros sites

post-596061-0-65644400-1420241545_thumb.

beleza :aplausos:  agora esta tomando jeito a brincadeira aqui, perfeito Fervolt com sua ideia deu certo agora consigo trocar de canal sem ter que compilar cada vez,, é que a cabeça aqui não ajuda . :D ...

também mudei aquela gambiara de potenciometro  e coloque uma chavinha seletora para trocar de canal.

Bom sobrou só um detalhe agora, que é o seguinte, o canal 0 da resultado diferente dos outros  :confused:  só o canal 0, os outros dão o mesmo resultado quando muda de posição a chave seletora.

É estranho porque deveria todos os canais dar o mesmo resultado, eu acho kkkkkkkkkkkkkkkkk.

segue cod 

   #include <16F876.h>   #device ADC=10    #fuses NOWDT, XT PUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD   #use delay(clock=4000000)   #use fast_io(A)   #use fast_io(   #use fast_io(C)   #DEFINE   Q1   PIN_B0                   // display 3   #DEFINE   Q2   PIN_B1                   // display 2   #DEFINE   Q3   PIN_B2                   // display 1   #BYTE    display=7  // long  valor;   float volts;   int16 adc0,adc1,adc2 ;   int   a;  //------------------------------------------------------------------------------   struct digito_separados    {         //variavel em bcd  unidade dezena centena   int  unidade, dezena, centena;   }    digito;//------------------------------------------------------------------------------   struct dados    {                 // variavel de dados entrada e saida   int  dados1, dados2, resultado;   }   numeros;//------------------------------------------------------------------------------   void separar_digitos(){      // separa resultado en unidade, dezena, centena     int   temp;     digito.unidade=0;     digito.dezena=0;     temp=numeros.resultado;     while(temp>=10){       temp-=10;       digito.dezena++;     }     digito.unidade=temp;   }//------------------------------------------------------------------------------   void mostrar()   {               int const bcd_7seg[10]= {0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7B};      int contador;           //0    1     2    3    4    5    6    7    8    9      output_low(Q1);      output_low(Q2);      output_low(Q3);       for(contador=0;contador<11;contador++)         {         display=bcd_7seg[digito.unidade];           //mostra unidade         output_high(Q1);         delay_ms(5);         output_low(Q1);         delay_cycles(4);         display=bcd_7seg[digito.dezena];            //mostra dezena         output_high(Q2);         delay_ms(5);         output_low(Q2);         delay_cycles(4);         display=bcd_7seg[digito.centena];           //mostra centena         output_high(Q3);         delay_ms(5);         output_low(Q3);         delay_cycles(4);         }    }//------------------------------------------------------------------------------void main()   {   set_tris_a(0x00000111);     //canal 0 entrada restante saida   output_a(0b00000000);        // limpa    set_tris_b(0x00000000);     //tudo saida   output_b(0b00000000);        //limpa   set_tris_c(0x00000000);     //tudo saida               output_C(0b00000000);        //limpa      setup_adc_ports(ALL_ANALOG);   setup_adc(ADC_CLOCK_DIV_2);   d:   set_adc_channel(0);delay_us(15);adc0 = read_adc();set_adc_channel(1);delay_us(15);adc1 = read_adc();set_adc_channel(2);delay_us(15);adc2 = read_adc();                          volts=0.0488758*(float)adc0,adc1,adc2;   a=(int)volts;   //------------------------------------------------------------------------------    /*        if (valor>=430)// maior que   {   output_b(0b10000000);   }   //---------------------------------------------------------------------------   if (valor>=450)// maior que   {     output_b(0b01000000);   }   //---------------------------------------------------------------------------   if (valor>=470)// maior que   {   output_b(0b00100000);   }   //---------------------------------------------------------------------------   if (valor>=491)// maior que   {   output_b(0b00010000);   }   //---------------------------------------------------------------------------   if (valor>=511)// maior que   {   output_b(0b00001000);   }   //---------------------------------------------------------------------------   if (valor<=420)// menor que   {   output_b(0b00000000);   }   //---------------------------------------------------------------------------   if (valor>=515)// maior que   {   output_b(0b00000000);   }   //------------------------------------------------------------------------------*/   digito.centena=a;   volts=volts-(float)a;   numeros.resultado=(int)(100.0*volts);   separar_digitos();   mostrar();      goto  d;}
Link para o comentário
Compartilhar em outros sites

 

attachicon.giftesteok.jpg

       volts=0.0488758*(float)adc0,adc1,adc2;   a=(int)volts;   }

 

Não entendo nada de C, mas essa multiplicação deve ser o seu problema....

Como o programa sabe qual desses 3 valores tem de ser multiplicado ????

Creio que o compilador faz apenas o primeiro, que é o do adc0.

Os outros canais, embora iguais, devem estar errados.

 

Paulo

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...