No funciona la conversion a 10bits (18F4550)

#1
saludos compañeros, les escribo en mi desesperación por resolver un problema con la conversión ADC a 10 bits con el microcontrolador PIC18F4550.

Les cuento que hace tiempo lograba comunicarme via usb con este tipo de conversión, sin embargo hace unas 3 semanas para acá ha dejado de funcionar y cuando conecto al computador sale un mensaje de error diciendo algo referente a que el hub no reconoce el dispositivo, luego me voy a panel de control/sistema/dispositivos de hardware y chequeo que aparece como "Dispositivo Desconocido", le doy click derecho y en detalles me doy cuenta que su PID y VID estan en 0000 y 0000...algo que me parece muy curioso, ya que esos dos valores siempre son distintos a eso que muestra y son los que se modifican en el controlador para cuando ocurren este tipo de errores.

Voy a adjuntarles la programación que no me quiere funcionar (En Proteus lo simula perfectamente, peor al llevarlo al protoboard no funciona).
_______________________________________________________________________________
Código:
#include <18F4550.h>
#device ADC=10      //Convertidor A/D a 10bit
#include <stdlib.h> //Permite hacer conversiones entre tipos numericos
#fuses HSPLL,NOWDT,NOPROTECT,NODEBUG,NOBROWNOUT,USBDIV,PLL5,CPUDIV1,VREGEN,PUT,MCLR,NOLVP,NOPBADEN, NOSTVREN, NOWRTC
#use delay(clock=48M)
#define ledv  PIN_C0                              
#define ledr  PIN_C1
#USE FAST_IO(A)
#USE FAST_IO(B)
#USE FAST_IO(C)
#USE FAST_IO(D)
#byte ADCON2=0xfc0
#byte adresl=0xfc3 //Registro donde se almacena el resultado de la conversion ADC
#byte adresh=0xfc4 //Registro donde se almacena el resultado de la conversion ADC
#include <usb_cdc.h> 
#include <ltc1298.c> // libreria para manejo LTC1298
////////////Declaración de Variables/////////////////////
   long int  data;
   char  Anc0L[4],Anc0H[4], Anc2[5];
   int16 dato, AL, AH;
   int a=0, b=0, prueba, local;

//////////////////////////////////////////////////////////////////////
///////////////////Programa Principal////////////////////
void main(void) 
{  
   set_tris_a(0b0000011);
   set_tris_b(0b00010000);
   set_tris_c(0b00000000);
   set_tris_d(0b00000000);
   output_low(PIN_C0);
   output_high(PIN_C1);
   usb_cdc_init();
   usb_init();                   // Inicializa el USB                                     
   usb_wait_for_enumeration();   //Espera hasta que el PicUSB sea configurado por el host                      
   output_low(PIN_C1);
   output_high(PIN_C0); 
   /////////////////// Configuración Modulo ADC ////////////////////
SETUP_ADC(ADC_CLOCK_INTERNAL); //Configuración del Reloj interno ADC_CLOCK_DIV_64
   SET_ADC_CHANNEL(0);      // Selección de canal A0
   SETUP_ADC_PORTS(ALL_ANALOG );
//////////////////////// Inicializa Rutina SPI //////////////////////////
   adc_init();                      //Inicializa la conversión Analógica/Digital
while(!usb_cdc_connected()){      // espera a detectar una transmisión de la PC
      while(true)
      {
         usb_task();                   //Habilita periférico usb e interrupciones 
         if (usb_enumerated())       // retorna verdadero si el dispositivo está enumerado
            { 
           if (usb_cdc_kbhit())     // en espera de un nuevo caracter en el buffer de recepción
            {  
               data = usb_cdc_getc();
               output_low (PIN_D0);
             if ((data== '1' ))        // 
               {
               output_low(Pin_b5);
               output_low(Pin_b6); 
               output_low(Pin_b7);
               if (input(pin_a1)== 1)//SIMULA LA CONDICIÓN DE LOS PINES 5&9
               {
               if (input(pin_b4)== 1)//SIMULA EL PULSO DE 50MSEG POR LOS PINES 7&8
                  {
                     a=1;
                  }
               if (a=1)
               {
                  output_high (PIN_D0);
                  delay_ms(100);
                  SET_ADC_CHANNEL(0);    //canal RA0
                  read_adc();
                  AL = adresl; //Guarda el byte bajo del resultado
                  AH = adresh; //Guarda el byte alto del resultado
                  itoa (AL,10,Anc0L);  // Función que convierte número entero a string
                  itoa (AH,10,Anc0H);  // Función que convierte número entero a string
                  prueba = bit_test (local,4);
                  dato = read_analog(prueba);    
                  convert_to_volts(dato,Anc2);
                  printf (usb_cdc_putc,"A%sB%sC%s;",Anc0L,Anc0H, Anc2);
                  
               }
               }
               usb_cdc_putc(data);
                 }
                  else {//

                  
                  if (data=='2') // INICIAR PROGRAMA DE TEMPERATURA 
               { 
                 output_high(Pin_b5);
                  }
                  else
                  {
                  output_low(Pin_b5);
                  }
               if (data=='3') // HABILITAR OPCION DE: "INTERFAZ PREPARADA" 
               {
                 output_high(Pin_b6); 
               }
               else
                  {
                  output_low(Pin_b6);
                  }
               if ((data=='4') && (b==0))  // HABILITAR "INICIO REMOTO" (PULSO DE 5MS)
               { 
                  b=1;       
                  output_high (PIN_b7);
                  delay_ms(10);
                  output_low (PIN_b7);
                               
               }
              else
              {
              }
             
               if ((data== '5' ))        // 
               {
               if (input(pin_a1)== 1)//SIMULA LA CONDICIÓN DE LOS PINES 5&9
               {
               if (input(pin_b4)== 1)//SIMULA EL PULSO DE 50MSEG POR LOS PINES 7&8
               {
               }
               if (a=1)
               {
                  output_high (PIN_D0);
                  delay_ms(100);
                  SET_ADC_CHANNEL(0);    //canal RA0
                  read_adc();
                  AL = adresl; //Guarda el byte bajo del resultado
                  AH = adresh; //Guarda el byte alto del resultado
                  itoa (AL,10,Anc0L);  // Función que convierte número entero a string
                  itoa (AH,10,Anc0H);  // Función que convierte número entero a string
                  prueba = bit_test (local,4);
                  dato = read_analog(prueba);    
                  convert_to_volts(dato,Anc2);
                  printf (usb_cdc_putc,"A%sB%sC%s;",Anc0L,Anc0H, Anc2);
                  
               }
               }
               usb_cdc_putc(data);
                 }
                 
                 }
                      
               }
               }
                                   
               }

}
               }
_____________________________________________________________________________
 
Última edición por un moderador:
#2
Verificaste que el capacitor del regulador usb este bien? Yo uso electrolitico de 47uF normalmente. Descartando que sea un problema de software, normalmente miraria esto como primera causa.
 
#3
que tal seaarg?... si yo utilizo ese capacitor en el montaje.

Olvide mencionarles que si utilizo la resolución a 8bits si inicia la comunicación usb, convierte el dato ADC, etc etc etc... Eso me tiene desconcertado.

Necesito usar la resolución a 10bits, hace algunos meses lograba emplearla, solo que este problema ha surgido repentinamente y ahora ni siquiera puedo agregar como dispositivo nuevo a mi ordenador.
 
#4
Primero: deberías incluir un tiempo de espera luego de llamar a setup_adc_channel (tiempo de adquisición).
Segundo: no manejo ccs, pero según veo de la página 60 de:
http://es.scribd.com/doc/14536209/PIC-C-Compiler-Ccscmanual
podrías declarar una variable long (de 16 bits) y guardar allí el valor del adc. En tu caso veo que ya tenes definida una:
dato = read_adc();

Desconozco por qué no anda el USB al cambiar de 8 bits a 10 bits.
Con ADC de 8 bits te anda en la protoboard?, o solo en el proteus?.

Veo que hay una llamada a adc_init(), pero no encuentro la definición en tu código ni en el manual del CCS, que hace esa función?.

Otra cosa "preocupante" son estas líneas:
#byte ADCON2=0xfc0
#byte adresl=0xfc3 //Registro donde se almacena el resultado de la conversion ADC
#byte adresh=0xfc4 //Registro donde se almacena el resultado de la conversion ADC

Si usas las funciones de ADC que provee el CCS entonces no deberías acceder a esas ubicaciones de memoria en forma directa sino a través de las funciones del CCS (read_adc para leer los valores, las demás para configurar, etc)
 
#6
Qué tal compañeros? Gracias por tomarse su tiempo para responder y darme alguna idea de que es lo que ocurre con mi problemita.

Ardogan te cuento que adc_init es una función utilizada para iniciar la conversión ADC.

Voy a solucionar y modificar lo que dijiste que era preocupante, =S... no soy el mejor programando microcontroladores, pero chequeare bien eso que me indicas y veo que resuelvo.

De nuevo gracias por estar pendiente del tema, pronto traigo las modificaciones.
 
#7
Olvide responder la pregunta:

Con ADC de 8 bits te anda en la protoboard?, o solo en el proteus?.
Si anda en el protoboard con la configuracion a 8 bits, tambien en proteus...

El problema radica en que la señal analogica de entrada al pic se inicia en 2mV y varia segun las condiciones del analisis, provienen de un cromatografo de gases.
 
Arriba