desktop

No funciona la conversion a 10bits (18F4550)

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:
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.
 
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.
 
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)
 
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.
 
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.
 
Atrás
Arriba