Autor Tema: ADC-PIC32: Resistencia limitadora de corriente en Avdd.  (Leído 8819 veces)

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

Desconectado manwenwe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2211
ADC-PIC32: Resistencia limitadora de corriente en Avdd.
« en: 25 de Octubre de 2010, 15:45:26 »
Hola,

en mi último proyecto decidí diseñar el esquemático de forma algo más ortodoxa: siguiendo todas las recomendaciones del datasheet de mi PIC32. Añadí todos los condensadores de desacoplo y resistencias limitadoras de corriente (pagina 32):

http://ww1.microchip.com/downloads/en/DeviceDoc/61143G.pdf



La resistencia en serie con MCLR# funciona genial y además le añadí un zener de 3.6V + resistencia: harto de quemar PICs cuando abría el proyecto equivocado (PIC18) en MPLAB (10ms de 9V en MCLR# y tu PIC pasa a mejor vida :D :D :D). El problema es que la resistencia de 10ohms entre VDD y AVDD no funcionó bien: el ADC me oscilaba de forma aleatoria un 20% en torno al valor real. Ahora he conectado AVDD a VDD directamente y el ADC funciona bien.

Conecté VSS-AVSS a 0V y VDD a 3.3V. A AVDD no lo apliqué otro voltaje: la corriente llegaba a través de la resistencia de 10ohms. ¿Quizá la resistencia  sólo sirve si AVDD y VDD tienen diferente voltaje?

¿Alguna otra idea?

Gracias por anticipado. Saludos.
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado manwenwe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2211
Re: ADC-PIC32: Resistencia limitadora de corriente en Avdd. (SOLUCIONADO)
« Respuesta #1 en: 28 de Octubre de 2010, 16:22:14 »
Después de varios días probando, desoldando y soldando, rompiéndome la cabeza... conseguí solucionar mi problema. No se debía al ACD del PIC32, se debía a los amplis que utilizo para acondicionar las señales que van al ADC: LMC6484. No sé realmente que ha pasado: las señales a las salidas de los OP tenían el voltaje adecuado pero la respuesta de los amplificadores no era adecuada para el ADC (adquiría valores aleatorios entorno al real)... creo que es porque está especificado para cargas de menos de 2Kohm... aunque no sabría asegurarlo a ciencia cierta.

Elegí estos OP porque son RR in/out (lo necesito) y son muy baratos. Ahora he cambiado un prototipo a MAX4020, el problema es que estos sólo son RR out y son muy caros.

Si no es mucho pedir... alguien podría recomendarme un OP que cumpla:

- Vs = +-4V to +-5V
- RR = IN/OUT
- Especificado para cargas muy altas
- Económico

Gracias!

Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: ADC-PIC32: Resistencia limitadora de corriente en Avdd.
« Respuesta #2 en: 28 de Octubre de 2010, 16:30:39 »
Hola Manwenwe, justo ahora estoy operando un LMC6484 RR. Lo estoy alimentando sólo a 3.3V y GND y le estoy metiendo una señal bipolar.

Lo quise emplear para sumar un offset positivo a la señal bipolar y convertirla en monopolar, pero el resultado es desastroso. El sumador no funciona correctamente ya que este ampli forzosamente necesita un voltaje de alimentación negativo para tolerar entradas negativas.

Imagino que tú estás alimentando el tuyo bipolarmente, por lo que mi problema no tendría que ver.

Si es el caso, mejor checa con un osciloscopio que la señal de salida del ampli sea correcta. Yo estoy trabajando con cargas de 20kohm en un dsPIC y la señal se mide sin errores.

También checa que el tiempo en que dejas el capacitor S&H del PIC32 sea suficiente. En los PIC32 1us es ideal, y si tienes cargas con alta impedancia, dale como 5us. Después verifica que el TAD del ADC sea el mínimo recomendado en la datasheet. Para un dsPIC es de 115ns aprox.

Desconectado manwenwe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2211
Re: ADC-PIC32: Resistencia limitadora de corriente en Avdd.
« Respuesta #3 en: 29 de Octubre de 2010, 10:26:50 »
Migsantiag, utilizo los LMC6484 como buffers de corriente y como acondicionadores de señal (desplazador + amplificador).

Te explico los 3 casos que tengo:

- Como seguidor de tensión con alimentación bipolar (+-5V) me funcionan bastante bien. Les meto señales de +-50mV y +-100mV a través de un trimmer. La salida es más que aceptable.
- Como seguidor de tensión con alimentación unipolar(0V-5V)  no me han ido nada bien. La salida se va casi 100mV.
- Como desplazador+amplificador. Parece que la salida es correcta pero es donde he tenido el problema con el ADC.

Si te fijas en el datasheet verás que no hay ni un sólo ejemplo real con alimentación bipolar (solamente un seguidor de tensión), así que es dificil saber como va a responder en este caso. Además si te fijas bien verás que el voltaje en las entradas no debe superar los 0.3V más allá de los "railes"; puede que ahí resida el problam de tu sumador, migsantiago.

En cuanto a la config del ADC del PIC32... estoy super perdido. Probé lo que me dijiste: subí al máximo el tiempo de sampleo y bajé al máximo el del de conversión. Funcionó durante un rato pero despues ya no. De hecho me he dado cuenta que tp era problema del LMC6484 porque con los MAX4020 tb ha dejado de funcionarme. Realmente no tengo ni idea de que pasa: siempre he utilizado amplificadores para acondicionar señales antes del ADC y con PIC16, PIC18 y PIC24 siempre me funcionó sin problemas. Ahora el ADC de PIC32 sólo me coge señales directamente de los sensores que utilizo.

Estoy seguro de que el ADC funciona bien. He probado con varios micros diferentes , además empezé en base a la config de la librería gráfica y el touchscreen funciona genial. Dejo el código por si veis algo raro:

Código: [Seleccionar]
float GetSample (int32 adcChannel, int8 muxChannel, float range){

int32 aux;

switch (adcChannel){

case MUX_CELLS_0to15:
break;
case MUX_CELLS_16to30:
break;
case MUX_CELLS_31to44:
break;
case MUX_SENSORS:
if(muxChannel&0b001)
MUX_SENSORS_ADDA = 1;
else
MUX_SENSORS_ADDA = 0;
if(muxChannel&0b010)
MUX_SENSORS_ADDB = 1;
else
MUX_SENSORS_ADDB = 0;
if(muxChannel&0b100)
MUX_SENSORS_ADDC = 1;
else
MUX_SENSORS_ADDC = 0;
break;
case MUX_ENERGY:
break;

}

    // Initialize ADC
    AD1CON1 = 0x080E0;      // Turn on, auto-convert
    AD1CON2 = 0;            // AVdd, AVss, int every conversion, MUXA only
    AD1CON3 = 0x1FFF;       // 31 Tad auto-sample, Tad = 256*Tcy
    AD1PCFG = 0;            // All inputs are analog
    AD1CSSL = 0;            // No scanned inputs

AD1CHS = adcChannel; 
    AD1CON1bits.SAMP = 1;   
while(!AD1CON1bits.DONE);

return  ((((float) ADC1BUF0)/ADC_BITS) * range);

}

Para la config que sugiere migsantiago habría que cambiar AD1CON3 = 0x1FFF;  por AD1CON3 = 0x1F00;. La frecuencia de reloj es 64Mhz y la de perifericos 8Mhz así que el mínimo TAD es 125ns que es mayor que el mínimo para el ADC de PIC32 (83ns).

También dejo un ejemplo de los acondicionadores de señal:



Las señales acondicionadas van a un MAX4051 y de ahí a una entrada analógica del PIC32.

Cualquier sugerencia es buena ;-). Muchas gracias.
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: ADC-PIC32: Resistencia limitadora de corriente en Avdd.
« Respuesta #4 en: 29 de Octubre de 2010, 11:36:37 »
Hola

En los ADC de pics avanzados debes controlar 2 cosas: la carga del S&H y la conversión.

Para cargar el S&H debes poner el bit SAMP en 1. Esperar 1us.

Una vez cargado el S&H, debes desconectarlo poniendo SAMP en 0. Ahí es cuando arranca la conversión ADC. Debes esperarla mediante lectura del bit DONE.

Te dejo un trozo de código que funciona con un dsPIC33...

Código: [Seleccionar]
AD1CON1bits.FORM = 0; //entero sin signo
AD1CHS0bits.CH0SA = canal;
AD1CON1bits.SAMP = 1; //carga S&H
DelayUs(1); //S&H
AD1CON1bits.SAMP = 0; //arranca conversión desconectando S&H
while(AD1CON1bits.DONE == 0); //espera
return ADC1BUF0;

Carga S&H con SAMP=1
Espera
Arranca conversión con SAMP=0
Espera leyendo DONE

Nota: Yo no usaría el auto-convert, mejor habilita la carga S&H manual y la conversión manual, que todo dependa de ti.

Desconectado manwenwe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2211
Re: ADC-PIC32: Resistencia limitadora de corriente en Avdd.
« Respuesta #5 en: 29 de Octubre de 2010, 17:25:07 »
Gracias migsantiago. Lo probaré cuando llegue al trabajo. Cuando pasé de PIC18F a PIC24F hice mal y directamente empecé usando el ADC con ejemplos de librerías: nunca llegué a entender lo de controlar el condensador de carga (en PIC18 espera un tiempo y punto) ni que TAD valiese tanto para samplear como para convertir..

Por lo que me has comentado creo que ahora sí que lo entiendo. Yo tenía este código:

Código: [Seleccionar]
    // Initialize ADC
    AD1CON1 = 0x080E0;      // Turn on, auto-convert
    AD1CON2 = 0;            // AVdd, AVss, int every conversion, MUXA only
    AD1CON3 = 0x1FFF;       // 31 Tad auto-sample, Tad = 256*Tcy
    AD1PCFG = 0;            // All inputs are analog
    AD1CSSL = 0;            // No scanned inputs

    AD1CHS = adcChannel; 
    AD1CON1bits.SAMP = 1;   
    while(!AD1CON1bits.DONE);

    return  ((((float) ADC1BUF0)/ADC_BITS) * range);


Se supone que al tener habilitado el auto-sample cuando llegaba a while(!AD1CON1bits.DONE) el bit AD1CON1bits.SAMP todavía no se había puesto a 0 ya que tenía configurado el tiempo en 31Tad y sólo había pasado 1 instrucción, por tanto el while resultaba positivo y se pasaba a la siguiente instrucción (leer ADC1BUF0). Con lo que estaba sampleando durante una única instrucción, unos 125nS. Con lo que a veces el resultado era bueno y otras no ¿Me equivoco?

Creo que una rutina buena sería la siguiente ¿no?:

Código: [Seleccionar]
    // Initialize ADC
    AD1CON1 = 0x08000;      // Conversión manual, sampleo manual
    AD1CON2 = 0;            // AVdd, AVss,
    AD1CON3 = 0x1F00;       //Tad = 256*Tcy
    AD1PCFG = 0;            // All inputs are analog
    AD1CSSL = 0;            // No scanned inputs

    AD1CHS = adcChannel; 
    AD1CON1bits.SAMP = 1; 
    DelayUs(5);
    AD1CON1bits.SAMP = 0; 
    while(!AD1CON1bits.DONE);

    return  ((((float) ADC1BUF0)/ADC_BITS) * range);


He apagado el auto-sample y he cambiado TAD a 1Tpb = 125ns (el mínimo 83.3ns).

Saludos.

Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: ADC-PIC32: Resistencia limitadora de corriente en Avdd.
« Respuesta #6 en: 29 de Octubre de 2010, 17:32:54 »
Me gusta lo que veo, sólo que no me sé de memoria los AD1XXXX, esos te tocan a ti.

En efecto, debes cargar el S&H, esperar y luego desconectarlo, automáticamente el ADC arranca la conversión al desconectar el S&H.

Nos cuentas cómo te va.

Desconectado manwenwe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2211
Re: ADC-PIC32: Resistencia limitadora de corriente en Avdd.
« Respuesta #7 en: 02 de Noviembre de 2010, 17:17:00 »
Mi gozo en un pozo: vamos que no consigo adquirir bien en el ADC si la entrada viene de un operacional  :-)

Como no tengo tiempo para seguir "investigando" he puenteado todos los acondicionadores de señal y ahora tomo las señales directamente desde los sensores con lo que ahora todo funciona OK...pero con menos precisión:-). Eso sí, he tenido que atenuar algunas  señales: por lo visto la resistencia de entrada del ADC no es muy alta ya que no consigo divisores de tensión precisos con resistencias mayores de unidades de K (algo que nunca me pasó con PIC16F, PIC18F y PIC24F).

Bueno volviendo al tema de los OAMPS+ADC: sería de gran ayuda si alguien me confirmase que se pueden realizar conversiones correctas cuando la fuente es un OAMP (baja impedancia).

Esto es lo que dice la hoja de errata de PIC32 sobre el ADC.

Module:ADC
When the ADC is in operation, the current channel
is shorted to VREF during the conversion period
(12TAD) after sampling. The impact on high-
impedance sources is that they may not have time
to recover between conversions. The impact on
low-impedance sources is a high current draw,
which may damage either the source or the
device.
Work around
Place a 5k resistor between the device and any
external capacitance on the board to limit current
draw.


El problema es que no entiendo lo de la resistencia....

Por cierto: muchas gracias migsantiago por aclararme como se controla la carga del S&H

Saludos
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: ADC-PIC32: Resistencia limitadora de corriente en Avdd.
« Respuesta #8 en: 02 de Noviembre de 2010, 17:34:52 »
No hay de qué Manwenwe.

Si quieres te ayudo con el ADC del PIC32. Yo no he usado ese módulo en mi PIC32MX440F512H.

Mándame un diagrama electrónico y código fuente para probar el PIC32. También tengo un LMC6484.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: ADC-PIC32: Resistencia limitadora de corriente en Avdd.
« Respuesta #9 en: 04 de Noviembre de 2010, 13:38:56 »
Manwenwe, este código funciona al 100%. Lo probé con un MCP9701 (no requiere ajuste de impedancia) y entregó la salida correcta. Después lo conecté a la salida de una señal de audio que está procesando el LMC6484, y todo bien. Dale una revisada a los registros de configuración del ADC, le hice cambios a los que me enviaste. La medición la obtengo desde la UART del PIC32 porque no tengo depurador para este PIC32.

Código: [Seleccionar]
#include <p32mx440f512h.h>
#include <plib.h>

//Entrada de cristal a 4MHz
//Para CPU será elevada a 64Mhz

//CPU
//XT es de 8MHz y hay que elevarlo a 64MHz
#pragma config FPLLIDIV = DIV_2, FPLLMUL = MUL_16, FPLLODIV = DIV_1
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_8
#pragma config FSOSCEN = OFF //sin oscilador secundario

// Let compile time pre-processor calculate the PR1 (period)
#define SYS_FREQ               (64000000L)
#define PB_DIV                 8

//Delays
#define GetInstructionClock()  (64000000L)
#include "TimeDelay.c"

#define TRIS_RX  TRISDbits.TRISD2
#define TRIS_TX  TRISDbits.TRISD3
#define TRIS_AD4 TRISBbits.TRISB4 //adc
#define TRIS_LED TRISBbits.TRISB0
#define LED      LATBbits.LATB0

//////////////////////////////////////////////////////////////////////////////////////////
int main()
{
char dato[10];
int i;

   //Habilita la caché de lectura ROM
   SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);

   //Deshabilita los pines de programación JTAG
   //Hace que las terminales RB10, RB11, RB12 y RB13 sean I/O
   DDPCONbits.JTAGEN = 0;

   TRIS_RX = 1;
   TRIS_TX = 0;
   TRIS_AD4 = 1;
   TRIS_LED=0;

U1BRG=51;//9600
U1STA=0;
U1MODE=0x8000;//Enable UART for 8-bit data
//no parity, 1 Stop bit
U1STASET = 0x1400;     //Enable Transmit and Receive

    AD1CON2 = 0;
    AD1CON3 = 0x000F; //512 Tpb
    AD1PCFG = 0xFFFF; //todo digital
    AD1PCFGbits.PCFG4 = 0; //menos AN4
    AD1CSSL = 0;          
    AD1CHS=0;
    AD1CHSbits.CH0SA = 4;
    AD1CON1 = 0x8000; //adc on

   while(1)
      {
      AD1CON1bits.SAMP = 1;  
      Delay10us(1);
      AD1CON1bits.SAMP = 0;  
      while(!AD1CON1bits.DONE);

      LED^=1;

      sprintf(dato, "%u \n\r", ADC1BUF0);

      for(i=0; i<10; ++i)
         DelayMs(50);

      //putsUART1(dato); /* Write data into Tx. */
      for(i=0; i<5; ++i)
         putcUART1(dato[i]);
      }
}
//////////////////////////////////////////////////////////////////////////////////////////

Desconectado manwenwe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2211
Re: ADC-PIC32: Resistencia limitadora de corriente en Avdd.
« Respuesta #10 en: 04 de Noviembre de 2010, 16:03:02 »
Muchas gracias migsantiago,

mañana en cuento llegue al trabajo lo pruebo. Por lo pronto te dejo un par de dudas acerca de tu código:

1. ¿Si no desabilitas el puerto JTAG sus pines no valen como entrada analógica?. ¿Y cómo IO?. Mi PIC es de 100 pines y los del JTAG no están compartidos con el ADC pero sí con otras IO que tengo para utilizar en el futuro.

2. Has configurado el TAD al máximo, 64uS, ¿no se supone que TAD debe ser cuanto más pequeño mejor?... pero mayor que el mínimo: en este PIC son 83.3nS.

Muchas gracias de nuevo!
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: ADC-PIC32: Resistencia limitadora de corriente en Avdd.
« Respuesta #11 en: 04 de Noviembre de 2010, 16:19:33 »
Muchas gracias migsantiago,

mañana en cuento llegue al trabajo lo pruebo. Por lo pronto te dejo un par de dudas acerca de tu código:

1. ¿Si no desabilitas el puerto JTAG sus pines no valen como entrada analógica?. ¿Y cómo IO?. Mi PIC es de 100 pines y los del JTAG no están compartidos con el ADC pero sí con otras IO que tengo para utilizar en el futuro.

2. Has configurado el TAD al máximo, 64uS, ¿no se supone que TAD debe ser cuanto más pequeño mejor?... pero mayor que el mínimo: en este PIC son 83.3nS.

Muchas gracias de nuevo!

Hola, siempre deshabilito el JTAG para recuperar pines, sin importar si son analógicos.

Configuré el TAD al máximo, sólo para asegurar que funcione. Si tus periodos de muestreo ADC deben ser menores, ajústalo como lo veas conveniente. Mi muestreo fue de 0.5s.

Desconectado manwenwe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2211
Re: ADC-PIC32: Resistencia limitadora de corriente en Avdd.
« Respuesta #12 en: 06 de Noviembre de 2010, 21:34:43 »
Mig, el viernes no pude probar tú código: me metieron el "tipico marrón de final de samana". Espero solucionar este problema entre lunes y martes xq miercoles salgo de viaje... Lo digo xq realmente aprecio el esfuerzo que hiciste en intentar ayudarme y parece poco serio no haber contestado ya con  las pruebas...

Gracias. Saludos.
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: ADC-PIC32: Resistencia limitadora de corriente en Avdd.
« Respuesta #13 en: 07 de Noviembre de 2010, 12:02:02 »
Sale, no te preocupes.


 

anything