16f877a. Defino ADC de 3 canales, solo funciona uno.

Buenas,

les cuento que estoy implementando 3 entradas analógicas en un pic 16f877a, las cuales convierten la información a digital en 8 bits.

El código me funciona bien al simularlo en proteus 7.5. El problema es que al implementarlo en la protoboard solo funciona la conversión del primer canal (RA0) y el resto es una salida (!!!) de 0 digital (0,1 volt aprox).
Le he dado mil vueltas y no entiendo qué puede ser. ¿alguna idea?

Este es el código (omití las partes que funcionan bien, son solo "if" y "else").

#include<16f877a.h>
#device ADC=8
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)


int sensord;
int sensort;
int giroiz;

void main(void){

set_tris_a(0x11011111); //puerto a es la entrada (excepto salida en pin A5)
set_tris_b(0x11000000); //puerto b es la salida (excepto entrada en pin B7 y B6)


SETUP_ADC_PORTS(AN0_AN1_AN3); //a0 a1 a3 entradas analogas
setup_adc(ADC_CLOCK_INTERNAL); //clock adc
// cristal para el pic. nunca está en modo sleep

do{

set_adc_channel(0);
delay_ms(20);
sensord = read_adc();


set_adc_channel(1);
delay_ms(20);
sensort = read_adc();


set_adc_channel(3);
delay_ms(20);
giroiz = read_adc();

}//do
while(true);
} //void

He probado las declaraciones RA0_RA1_RA3_ANALOG, ALL_ANALOG (aunque no me sirve, pero para ver si cambiaba algo). También probé distintos delays, usualmente 10 o 20us y distintos clocks para el ADC, como ADC_CLOCK_DIV_8.
En todos los casos, el pic hace el mismo error.
:confused:

Cualquier ayuda es bienvenida. Saludos.
 
prueba dando mas tiempo a la conversion
Y digo yo? Aver si el error lo tienes en el circuito. Has medido la tensión que tienes en la patilla?
 
Última edición:
Intentaré darle más, pero si en general se usa 10-50us, ahora con 10ms debería andar más que bien, considerando que además la impedancia es muy baja.

El circuito está bien, porque antes programaba el pic con puertos digitales y todo andaba bien, ahora cambié a esos análogos, le conecto las entradas análogas (resistencia variable, sensor infrarrojo, etc) y no funciona.

Ya medí voltajes, como mencioné en el primer párrafo, los pines RA1 y RA3 tiene poco más de cero volts (~0,1V) y están fijos, independiente de lo que conecte ahí. Todo lo demás del pic funciona bien.
 
Última edición:
Los puertos analogos deben funcionar como entrada.

Prueba declarando las variables como tipo float.
--------

set_adc_channel(3); --->> dede ser set_adc_channel(2)
delay_ms(20);
giroiz = read_adc();
 
Gracias por sus sugerencias.
Los puertos analogos deben funcionar como entrada.

Prueba declarando las variables como tipo float.
--------

set_adc_channel(3); --->> dede ser set_adc_channel(2)
delay_ms(20);
giroiz = read_adc();
Sé que deben funcionar como entrada, pero ahora se comportan como salida. RA1 y RA3 están pegados en 0.

Creo que el set_adc_channel(2) haría referencia a RA2 y ese no está definido como puerto análogo.
¿acaso los puertos análogos se numeran como puerto 0 el primero, puerto 1 el segundo, puerto 2 el tercero..etc, independiente del número de pin?
 
Si tienes fijo esa tensión, con el tester, Tienes mal la placa. Revisa cortos.

Aún no hago la placa. Esto es en protoboard y no está malo, porque cuando tenía el puerto A solo como I/O digital todos los pines funcionaban bien.

Hola, te cuento que lo estoy simulando y anda bien.. Sube el esquema de tu simulacion...

No me expliqué bien, lo siento. La simulación corre, pero proteus me indica que el pin RA2 no es A/D. Por lo tanto, el set_adc_channel(2) está llamando a RA2 y no a RA3.

La simulación es algo bien simple. adjunto imagen.

ya me estoy rindiendo con esto, ya he probado 3 pics 16f877a y todos hacen lo mismo.
estoy pensando usar el 16f628a e intentar hacer algo con los comparadores que trae :confused:
 

Adjuntos

  • 0.jpg
    0.jpg
    185.5 KB · Visitas: 37
A mi me paso igual, llevo poco en el tema de los microcontroladores.

Mi solución fue repetir el código, pues el PIC no puede leer ambos canales a la vez, pero por velocidad de trabajo pareciera que si.
Por lo tanto, aumenté la frecuencia del cristal y funcionó muy bien.

Aquí les dejo el código que usé.

PHP:
void main ()
{  
  float  temp; //Variable con decimales llamada temp
  //delay_ms(2000);  // Al encender el PIC espero 2 segundos a que estabilice el voltaje
  output_low(pin_A1); // arranco el pin de salida en bajo
  
  Setup_adc_ports(sAN2 | sAN0);    //pongo como analogo el puerto solo el pin NA0 
  setup_adc(adc_clock_internal); //selecciono reloj interno para conversion
  

while (true)
{
set_ADC_Channel(0);

temp=read_adc()/2; //lee el conversor ADC se lo asigna a la variable temperatura
delay_us(20);
//************************si la temperatura es mayor que 35
if(temp>=38)  // (Si temp es mayor o igual a 38) /(if(temperatura>=35&&temperatura<=40) :siesta entre 35 y 40)
{

output_high(pin_A1);  //enciende el ventilador
delay_ms(3000); //Espero 1 minuto para evitar variaciones al encender y apagar el ventilador

}
//*********si la temperaturaes correcta o menor de 35
else
{
output_low(pin_A1);  //Apaga el ventilador
}

//******************************************************************************
set_ADC_Channel(2);

temp=read_adc()/2; //lee el conversor ADC se lo asigna a la variable temperatura
delay_us(20);
//************************si la temperatura es mayor que 35
if(temp>=38)  // (Si temp es mayor o igual a 38) /(if(temperatura>=35&&temperatura<=40) :siesta entre 35 y 40)
{

output_high(pin_A1);  //enciende el ventilador
delay_ms(3000); //Espero 1 minuto para evitar variaciones al encender y apagar el ventilador

}
//*********si la temperaturaes correcta o menor de 35
else
{
output_low(pin_A1);  //Apaga el ventilador
}
}
Este proyecto consiste en leer dos sensores de temperatura LM35 con un PIC12F675, y si la temperatura es igual o mayor a 38°C, enciende un ventilador.
 
Última edición por un moderador:
Atrás
Arriba