Autor Tema: lectura del adc 8 y 10 bits en un solo proceso  (Leído 5190 veces)

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

Desconectado pikman

  • Moderador Local
  • PIC24F
  • *****
  • Mensajes: 679
lectura del adc 8 y 10 bits en un solo proceso
« en: 12 de Agosto de 2004, 13:44:00 »
Hola,
        Estoy en un problema, en mi aplicacion necesito, leer el conversor en 8 bits y con el resultado de esta variable hacer un ajuste, esto ya funciona perfectamente, en otro momento debo con otro canal leer la tension de alimentacion para mostrarla en un display, pero tiene que ser a 10 bits, osea que el canal 0 del adc debe devolver un valor de 8 bits y el 1 uno de 10, el problema es que CCS justifica cuando esta a 10 bits pone en adressl los 8 bits msb y en adressh los 2 MSB, cuando esta en 8 bits hace al reves entonces por mas que copie los registros en una variable no me queda el valor correcto de 8 bits leyendo siempre a 10 bits, bueno ya estoy recontraenredado espero que me entiendan.

saludos

Ariel
saludos
PikMan

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: lectura del adc 8 y 10 bits en un solo proceso
« Respuesta #1 en: 12 de Agosto de 2004, 13:57:00 »
No entiendo el cometido de los objetos adressh y adressl ¿son variables que has declarado tú?
Puedes poner un poco de tu código para verlo?

Desconectado pikman

  • Moderador Local
  • PIC24F
  • *****
  • Mensajes: 679
RE: lectura del adc 8 y 10 bits en un solo proceso
« Respuesta #2 en: 12 de Agosto de 2004, 15:41:00 »
Bueno, era enrredado como lo anticipe, el conversor del 16F877 que es el que estoy usando entrega 10 bits en dos bytes llamados addressl y addressh, los declare porque pense para la medicion de tension usar 10 bits y para el setup de un temporizador 8 bits.

Si miras el DS entenderas mejor mi planteo pues CCS no te deja usar un canal a 8 bits y otro a 10 , cambiando la forma de justificar el resultado de 10 bits en los dos registros de 8 bits.

Pero despus de mirar detenidamente como es el proceso de justificacion consegui la solucion y es rotar 2 bits a la derecha el resultado tal como lo entrega read_adc().

Entonces quedo esto :

con el conversor ajustado para 10 bits con lo siguiente solo se
leen 8 bits

resultado=read_adc()>>2;

Para entenderlo te vuelvo a recomendar mirar el data sheet del 16F87X donde habla de la justificacion del resultado.

saludos y gracias por responder.

Ariel






saludos
PikMan

Desconectado rferrero

  • PIC16
  • ***
  • Mensajes: 113
RE: lectura del adc 8 y 10 bits en un solo proceso
« Respuesta #3 en: 28 de Noviembre de 2004, 06:18:00 »

    Sí, los ADDRESH y ADDRESL son los registros internos del micro donde se guardan la parte alta y baja, respectivamente, de la conversión A/D del dispositivo conectado.

    Por qué no lo justificas a la derecha escribiendo en ADCON0 (ó el 1, no recuerdo exactamente), guardas los valores de ADDRESH y ADDRESL en sendas variables de 8 bits y, finalmente, haces:

               make16(ADDRESH,ADDRESL);

     Asunto arreglado. No te complicas la vida con rotacioes y demás.
 
     Un saludo.

Desconectado pikman

  • Moderador Local
  • PIC24F
  • *****
  • Mensajes: 679
RE: lectura del adc 8 y 10 bits en un solo proceso
« Respuesta #4 en: 28 de Noviembre de 2004, 08:02:00 »
Hola, gracias por responder, el problema es que CCS como digo en el post anterior, deja seleccionar #device adc=10   ó    #device adc=8 y esta directiva NO se puede incluir en cualquier parte del codigo, por otra parte se puede desde C de CCS seleccionar la justificacion, para esto habria que incluir ASM que es lo que trato de no hacer en mis aplicaciones mientras la situacion me lo permite.

En mi aplicacion debo, recibir una variable que es de 8 bits en un canal analogico y en los demas, (uso un pic 16F870), variables de 10 bits, entonces debo tener la facilidad de "conmutar" entre una resolucion y la otra, la unica manera que encontre de hacer esto con la menor cantidad de ROM y RAM fue de esta manera, simplemente rotando 2 veces a la derecha el registro de 10 bits, entonces con 2,5 Volts en el conversor configurado a 10 bits leeria

1000000000=512

y si quiero 8 bits


(1000000000)>>2

que es

10000000=128


Las rotaciones a veces parecen complicadas pero son a mi parecer, el camino a la optimizacion y la sencilles de un programa , claro que usando ASM de Microchip la solucion es tan sencilla como tu dices.

desde ya te agradezco el intreres de ayudarme,


saludos

PIKMAN





saludos
PikMan

Desconectado rferrero

  • PIC16
  • ***
  • Mensajes: 113
RE: lectura del adc 8 y 10 bits en un solo proceso
« Respuesta #5 en: 28 de Noviembre de 2004, 13:30:00 »

     De nada.
     La manera de cambiar la justificación es simple. Se puede hacer en C, sin ASM.

          ...............
        #byte ADCON1=0x9F
          ...............
   ADCON1=0b10000000;      //Puerta A entradas analógicas
          ...............


   1 = Pone en el registro ARDESH  los seis bit de mayor peso a “0” (alineación a la derecha).

0 = pone los 6 bit de menor peso del registro ADRESL a “0” (alineación a la izquierda).

Por lo tanto los 16 bits que forman el registro ARDESH-ARDESL con ADFM=1 tiene los 6 bit de mayor peso a cero y con ADFM=0 los 6 bit de menor peso están a cero.


      El programa completo es:

#device PIC16F876 ADC=10
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=62, rcv=63) // PIN_C6=62 y PIN_C7=63
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, WRT

#define ADC_CLOCK_DIV_32    0x81
#define ALL_ANALOG          0x80         // A0 A1 A3 Ref=Vdd
#define ADC_CLOCK_INTERNAL  0xC1              // Internal 2-6us
#define ADC_START_AND_READ     7   // This is the default if nothing is specified
#define ADC_START_ONLY         1
#define ADC_READ_ONLY          6
#define GO                   2
#define ADIF                6
#define ADON                0

#byte PIR1=0x0C
#byte TRISA=0x85
#byte ADCON1=0x9F
#byte ADCON0=0x1F
#byte ADRESL=0x9E
#byte ADRESH=0x1E

void main()
{
//Se activa el ADC y se selecciona el canal RA3/AN3. Frecuencia de trabajo Fosc/32
   int h, l;
   float const resol = 5.0/1024.0;
   float volt;
   long int medida;

   TRISA=0b00001000;      //Puerta RA3 entrada
   ADCON0=0b10011001;      //ADC en On, seleciona canal AN3
   ADCON1=0b10000000;      //Puerta A entradas analógicas

  while(1)
  {
   bit_clear(PIR1,ADIF);   //Restaura el flag del conversor AD
   bit_set(ADCON0,GO);   //Inicia la conversión
//   while(bit_test(PIR1,ADIF));   //Fin de conversión ??
   while(bit_test(ADCON0,GO));   //Fin de conversión ??
   h=ADRESH;
   l=ADRESL;

   medida=make16(h,l);

   volt=medida*resol;

//    printf("
 (%ld) Voltios ",medida);
    printf("
 (%f) ",volt);

//   bit_clear(ADCON0,GO);

   delay_ms(500);
  }
}

   Lo del device ... no entiendo muy bien a qué te refieres. Pon = a 10 y ya está. Justificado a la derecha y los ceros a la izquierda.

    Un saludo.   Sonrisa


 

anything