Autor Tema: No me va el ADC - SOLUCIONADO  (Leído 6272 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
No me va el ADC - SOLUCIONADO
« en: 18 de Septiembre de 2007, 12:15:08 »
Hola, he cogido parte del código de algunos ejemplos en los que se usa el ADC pero no hay forma de que me funcione. El led de control me parpadea y en el LCD sale la información correctamente, pero el valor del ADC siempre es cero. La tensión que le inyecto al conversor es mediante un potenciómetro entre 5V y 0V y midiendo sobre la misma patita del PIC observo que hay, por ejemplo, 3,5V, etc...

Os pongo el código:
Código: [Seleccionar]
#include <16F818.h>                                //PIC a utilizar
#device adc=8                                      //numero de bits del ADC

#fuses XT                                          //configuracion de fusibles
#fuses NOWDT
#fuses PROTECT
#fuses PUT
#fuses NOBROWNOUT
#fuses MCLR
#fuses NOLVP
#fuses CPD
#fuses NOWRT
#fuses NODEBUG

#use delay (clock=3276800)                         //Fosc=3,2768Mhz

#define LED       PIN_A1                           //LED de funcionamiento
#define LCD_RS    PIN_B1                           //pinout del LCD
#define LCD_RW    PIN_B2
#define LCD_E     PIN_B3
#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7

#include <flex_lcd.c>                              //libreria LCD


int nClocks=0, flag_seg=0;


#INT_TIMER0
void Interrupcion_Timer0()                         //interrupcion cada 40ms
{
   nClocks++;                                      //contar numero de interrupciones del timer0
   output_low(LED);                                //parpadeo led

   if(nClocks==25)                                 //25 interrupciones -> ha pasado 1seg
   {
      nClocks=0;
      output_high(LED);
      flag_seg=1;
   }
}


void main(void)
{
   int valor_adc=0;

   disable_interrupts(GLOBAL);                     //deshabilitar interrupciones
   disable_interrupts(INT_EEPROM);                 //deshabilitar interrupcion EEPROM
   disable_interrupts(INT_RB);                     //deshabilitar interrupcion portb
   disable_interrupts(INT_TIMER1);                 //deshabilitar interrupcion timer1
   disable_interrupts(INT_TIMER2);                 //deshabilitar interrupcion timer2
   disable_interrupts(INT_CCP1);                   //deshabilitar interrupcion CCP1
   disable_interrupts(INT_EXT);                    //deshabilitar interrupcion RB0
   disable_interrupts(INT_SSP);                    //deshabilitar interrupcion I2C / SPI
   
   setup_TIMER_0(RTCC_INTERNAL | RTCC_DIV_128);    //preescaler=128 para 1seg
   setup_TIMER_1(T1_DISABLED);                     //desactivar timer1
   setup_TIMER_2(T2_DISABLED,0,1);                 //desactivar timer2   
   setup_CCP1(CCP_OFF);                            //desactivar modulo captura
   setup_SPI(SPI_SS_DISABLED);                     //desactivar SPI
   setup_ADC_PORTS(AN0);                           //entradas analogicas
   setup_ADC(ADC_CLOCK_INTERNAL);                  //activar modulo ADC

   set_tris_a(0b00000001);                         //configuracion de los puertos
   set_tris_b(0b00011111);
   set_adc_channel(0);                             

   ext_int_edge(H_TO_L);                           //interrupcion externa en flanco de bajada

   port_b_pullups(TRUE);                           //pullups portb activadas

   enable_interrupts(INT_AD);                      //habilitar interrupcion ADC
   enable_interrupts(INT_TIMER0);                  //interrupcion del timer0
   enable_interrupts(GLOBAL);                      //interrupciones activadas

   lcd_init();

   delay_ms(50);

   do
   {
      if(flag_seg==1)
      {
         flag_seg=0;
         valor_adc=read_adc();
         delay_ms(50);
         printf(lcd_putc,"\f");
         printf(lcd_putc,"Tension: %uV", valor_adc);

      }

   }while(TRUE);
}

Como véis he desactivado todo lo posible para evitar tener algún problema con eso, pero nada, no hay forma.

Un saludo y gracias!!
« Última modificación: 02 de Octubre de 2007, 08:07:43 por DarkVect »

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: No me va el ADC ¿?
« Respuesta #1 en: 18 de Septiembre de 2007, 13:19:45 »
Así probando he visto que si le asigno un valor diferente de cero a valor_adc y ejecuto el programa cambiando el orden de la visualización del LCD y de la conversión AD, en el LCD aparece ese valor: Tension: 10V (por ejemplo) y justo al segundo cuando hace la conversión pasa a valer 0, por lo que diría que intenta leer, y de hecho la función devuelve algo, pero no se qué puede estar pasando.

Seguiré provando a ver.

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: No me va el ADC ¿?
« Respuesta #2 en: 18 de Septiembre de 2007, 14:53:45 »
Fijate si estas usando variables de 8 bits o de 16 bits. 

Creo que read_adc() debiera volver un valor de 10 bits.  Si el tipo int en el CCS es de 8 bits entonces ahi ya tenes el primer problema.

Otra pregunta, el AD está encendido?
Podes visualizar el estado del registro ADCON0 y ADCON1 antes de disparar la conversión? es para ver si realmente se configuraron bien estos pines.

Saludos
- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7918
Re: No me va el ADC ¿?
« Respuesta #3 en: 18 de Septiembre de 2007, 22:19:13 »
El conversor esta a 8 Bits
Citar
#device adc=8                                      //numero de bits del ADC

Error 1, segun mi entender:
Citar
   set_tris_a(0b00000001);                         //configuracion de los puertos
   set_tris_b(0b00011111);
CCS configura los puestos en modo Standard segun como vayas utilizando los modulos, al declarar que usaras el conversor para la entrada 0...
Citar
setup_ADC_PORTS(AN0);                           //entradas analogicas
y luego le mandas :
Citar
set_tris_a(0b00000001);
le obligas a configurar ese pin como Input digital, ya no es analogica!!

Comenta ambos Set_Tris y vuelve a compilar... :mrgreen: :mrgreen:

Error 2, y aqui Maunix va a coincidir conmigo:
Citar
enable_interrupts(INT_AD);                      //habilitar interrupcion ADC
Para que habilitar una interrupcion que el programa ni siquiera contempla donde va a saltar cuando ocurra la misma??
No tienes rutina alguna para ejecutar cuando esta ocurra!!

Tambien comenta esa linea, deberia ocurrir esa interrupcion cada vez que termina la conversion, si no hace saltos raros el programa es solo por la gracia de Dios, je..je :mrgreen:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: No me va el ADC ¿?
« Respuesta #4 en: 19 de Septiembre de 2007, 04:14:26 »
Gracias a ambos por responder.

Como dice MGLSOFT el ADC está configurado a 8 bits para que el resultado cuadre con el int con el que lo leo. He quitado los set_tris de ambos de puertos y lo he dejado en modod standar (sin el fast_io).

Lo de la interrupción del ADC, la tenía desactivada en principio pero al ver que no iva pensé en activarla por si acaso. Se supone que CCS activa el ADC con la expresión setup_ADC(ADC_CLOCK_INTERNAL);

He vuelto a compilar y a probar y no hay manera. Lo he probado con hasta tres micros diferentes por si acaso.
« Última modificación: 19 de Septiembre de 2007, 04:19:12 por DarkVect »

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: No me va el ADC ¿?
« Respuesta #5 en: 19 de Septiembre de 2007, 05:07:58 »
YA ME VOY ACERCANDO!!

A ver, siguiendo el consejo de Maunix he hecho que en el LCD me salgan los valores de los registros ADCON 0 y 1 con los siguientes resultados:

ADCON1=14 es decir 0000 1110 lo que implica que sólo es analógica AN0, que las referencias son la alimentación (5V), que no se usa la división por 2 del reloj y que la justificación es a la izquierda. Está ahí el problema, en la justificaición??

ADCON0=192 es decir 1100 0000 lo que implica que se usa el timer interno del ADC (correcto) y que se usa el canal 0 (correcto). De los otros tres bits, uno o está implementado, el otro dice cuándo la conversión está en progreso (vuelve a cero después de la operación automáticamente) y finalmente el ADON que indica si el módulo está operando. Este último no debería ser 1??

He intentado hacer los deberes con el datasheet pero me han quedado esas dos dudas que no se cómo solucionarlas.

Un saludo y gracias!!

AÑADO: También me he puesto a visualizar los registros ADRESH y ADRESL donde se debería guardar el valor de la conversión y ambos son siempre 0.
« Última modificación: 25 de Septiembre de 2007, 04:26:19 por DarkVect »

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: No me va el ADC ¿?
« Respuesta #6 en: 19 de Septiembre de 2007, 12:17:53 »
A ver, siguiendo el consejo de Maunix he hecho que en el LCD me salgan los valores de los registros ADCON 0 y 1 con los siguientes resultados:

ADCON1=15 es decir 0000 1110 lo que implica que sólo es analógica AN0, que las referencias son la alimentación (5V), que no se usa la división por 2 del reloj y que la justificación es a la izquierda. Está ahí el problema, en la justificaición??
No es un problema si usarás 8 bits.  Si usas 10 bits, es más simple justificar a la derecha.  No lo llamaría 'un problema' pero si una complicación tenerlo justificado a la izquierda si vas a leer en 10 bits. 

ADCON0=192 es decir 1100 0000 lo que implica que se usa el timer interno del ADC (correcto) y que se usa el canal 0 (correcto). De los otros tres bits, uno o está implementado, el otro dice cuándo la conversión está en progreso (vuelve a cero después de la operación automáticamente) y finalmente el ADON que indica si el módulo está operando. Este último no debería ser 1??
Si, el ADON debe estar en uno siempre, salvo que el amigo CCS encienda el A/D justo antes de la conversión (solo una aplicación con extremo bajo consumo justificaría tal acción).


He intentado hacer los deberes con el datasheet pero me han quedado esas dos dudas que no se cómo solucionarlas.
y usar la fuerza bruta? jeje, es decir configurar vos mismo el ADCON0 y el ADCON1?


AÑADO: También me he puesto a visualizar los registros ADRESH y ADRESL donde se debería guardar el valor de la conversión y ambos son siempre 0.

Puede deberse a que no tenes funcionando el módulo A/D

- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado Trev_11

  • PIC10
  • *
  • Mensajes: 44
Re: No me va el ADC ¿?
« Respuesta #7 en: 19 de Septiembre de 2007, 13:59:20 »
Hola..no veo ke pongas ;1 el return en la funcion de interrupción ke usas ni tampoco esperas nada al seleccionar el canal (AN0),no conozco tu pic pero supongo que tu módulo AD contara con capacitor de entrada,hay que esperar hasta que se cargue a lo mas cuestion de centenas de µs cada vez ke se enciende el módulo,antes de solicitar una conversion y despues de seleccionar el canal,ademas no me parece lógico desperdiciar un módulo que cuenta con 10 bits de resulución(#device adc=10)pero eso es cuestion de gustos jeje aca te dejo mi código ke funciona a la perfección tienes proteus tambien te dejo el diseño suerte.

#include <16f877.h>
#device adc=10                            //La resolución del módulo A/D es de 10 bits.
#fuses XT,PUT,NOWRT,NOWDT,NOLVP,BROWNOUT,NOPROTECT
#use delay(clock=4000000)           //Cristal de 4MHz.
#include <lcd.c>
#use fast_io(D)                             //Para ahorrar lineas de código.



    float const P=0.002219;             //P=(5-2.73)/1023,trabajo con un LM335.
    float voltaje,temperatura;          //Declaro estas variables como globales.
    unsigned long int bin_lectura;     //Si bien trabajare con un dato entero de 10 bits.
   


main()
{
    set_tris_d(0x00);                      //Puerto D como salida.
    lcd_init();                                 //Inicializo el LCD en modo 4 bits.
    while(1)                                   //Bucle infinito.
    {
    set_tris_a(0x0D);                     //Configuro RA0,RA2(Vref-) y RA3(Vref+) como entradas.                                       
    setup_adc(adc_clock_internal);        //Pongo en marcha módulo A/D.
    setup_adc_ports(AN0_VREF_VREF);       
    set_adc_channel(0);                   //El canal analogo a emplear será RA0/AN0.     
    delay_us(20);                          //Tiempo de adquisición del dato.     
    bin_lectura=read_adc();               
    setup_adc(ADC_OFF);                   
    voltaje=(bin_lectura*P)+2.73;
    temperatura=(voltaje/0.01)-273;
    printf(lcd_putc,"TEMPERATURA=%.3f C",temperatura);
    delay_ms(3000);
    lcd_putc("\f");                       //Borro LCD.
    }
}

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: No me va el ADC ¿?
« Respuesta #8 en: 19 de Septiembre de 2007, 17:13:09 »
Trev_11 yo creo que si espera ya que lee el A/D cada 1 segundo y además nunca cambia el canal por lo tanto siempre se leerá el mismo canal.

Creo que el problema pasa por una configuración del A/D más que por un tiempo de captura.
- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: No me va el ADC ¿?
« Respuesta #9 en: 19 de Septiembre de 2007, 19:03:16 »
Como dice Maunix hago una lectura por segundo y entre la configuración, la lectura y el uso del valor siempre espero 50ms. Ya se que es mucho pero tampoco me importa. Utilizo 8 bits porque me es más sencillo de tratar el dato a posteriori, pero vamos tampoco tiene mucha importancia.

Mañana probaré a forzar los registros. Supongo que debo quitar toda asignación sobre el ADC que hay en el programa y directamente asignar el valor que toque al registro, no?

Gracias!!

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: No me va el ADC ¿?
« Respuesta #10 en: 25 de Septiembre de 2007, 05:00:17 »
FUNCIONANDO PERO MAL!!!

Maunix siguiendo tu consejo he programado los ADCON directamente con los siguientes valores:

ADCON0: 1100 0001 = 193 (reloj interno adc, canal 0 y activar el módulo adc) Este último bit (activar módulo) es el que CCS no ponía a 1 jamás y por lo tanto el adc no funcionaba.

ADCON1: X000 1110 = 14 (justificación y canales a utilizar) La X es la justificación y ahí viene el problema:

Lo que pasa es que si le pongo justificar a izquierdas, en el LCD veo como el valor del adc leído (valor=read_adc()) es muy proximo al que tendría que ser para tensiones de 2,5 a 5V pero a la que bajo de ahí se me pone en 680, por ejemplo, y valores raros!! Si uso sólo 8 bits el valor máximo debería 255, de dónde sale ese número??

Por contra si lo pongo a derechas el valor es 0 hasta 1,2V que pasa a 1 y ahí se queda.

Cómo puede terminar de arreglar esto??

PD: de todas formas, me cabrea mucho que mi CCS no funcione!!

 

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: No me va el ADC ¿?
« Respuesta #11 en: 25 de Septiembre de 2007, 06:01:28 »
YA ME VALE!! Los valores raros que me aprecían eran debidos a que no borraba el LCD!!! Es decir, que si por ejemplo marcaba 125 y bajaba de golpe para que marcara 90, el 5 se quedaba en el LCD y se veía 905 ¿? Como digo, vaya despiste!!

Bueno pués eso que ya funciona!! Mil gracias a todos!!

De todas formas, no entiendo porque CCS no me configura el bit para activar el ADC porque el resto de bits si los configura bien.

Finalmente, una duda técnica: el ADC tiene 256 valores, y por lo que he visto van del 1 al 255, pero el 0 no lo logro obtener con el potenciómetro a pesar de que el téster marca 0,00V. Es cuestión del potenciómetro?
« Última modificación: 25 de Septiembre de 2007, 06:08:58 por DarkVect »

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: No me va el ADC ¿?
« Respuesta #12 en: 25 de Septiembre de 2007, 08:23:48 »
Finalmente, una duda técnica: el ADC tiene 256 valores, y por lo que he visto van del 1 al 255, pero el 0 no lo logro obtener con el potenciómetro a pesar de que el téster marca 0,00V. Es cuestión del potenciómetro?

El ADC en modo 8 bits tomará 256 posibles valores; de 0 a 255 inclusive.

En 5V estamos hablando de unos 20mV o similar y podría ser perfectamente que en el pin del A/D no tengas exactamente 0.  Puedes probar subirle la presición al tester poniendolo en 200mV.  También si el potenciómetro no hace un corto franco con el GND, no tendrás 0V exactamente.

En otras circunstancias te diría que no esperas lo suficiente para que le capacitor interno se descargue pero 1 segundo entre muestras es más que un buen tiempo.... ¿el Potenciómetro es de muchos Ohms?

- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
Re: No me va el ADC ¿?
« Respuesta #13 en: 25 de Septiembre de 2007, 08:49:18 »
Para salir de dudas, puentea la entrada del ADC con masa. Si no te marca 0 es que hay algún problema en algún sitio.

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: No me va el ADC - SOLUCIONADO
« Respuesta #14 en: 02 de Octubre de 2007, 08:09:26 »
Hoy lo he podio retomar y al puentear el pin AN0 con la masa del circuito da 0. Así pués supongo que debe ser algún pequeño error del potenciómetro cuando está en el extremo de masa.

Saludos y muchas gracias por la ayuda!!


 

anything