Conversión analógica a digital

2

Estoy usando un microcontrolador Atmega32-A y un AD7798 ADC externo. Puedo establecer los registros de ADC y leer los valores de ADC. He escrito el siguiente código:

  statusreg = AD7798_8(0x40, 0xFF);          // read STATUS register default value
  Id = AD7798_8(0x60, 0xFF);                 // read ID register  default value
  mode = AD7798_16(0x48, 0xFFFF);            // read MODE register default value
  conf = AD7798_16(0x50, 0xFFFF);            // read conf register default value

   AD7798_16(0x10, 0x0010);            // write Configuration reg = 0x0010.  2.5V range  
   value = AD7798_16(0x50, 0xFFFF);         // read Configration register 

   if (value != 0x0010) 
   printf("unexpected conf setting %04x\r\n", value);

   while ((statusreg & 0x80) != 0);                         // wait till ADC is ready 
   adc = AD7798_16(0x58, 0xFFFF);                           // read register 
   printf("ADC value is %04d\r\n", adc);    

Desde el código anterior, estoy leyendo los valores de ADC. De acuerdo con la hoja de datos AD7798 y de acuerdo con la configuración de mi registro de configuración, tengo que averiguar el voltaje de entrada analógica usando la siguiente fórmula:

  

Cuando el ADC está configurado para operación bipolar, el código de salida es   Binario de compensación, con un voltaje de escala total negativo que resulta en un código   de 000 ... 000, una tensión de entrada diferencial cero que resulta en un código   de 100 ... 000, y un voltaje de entrada de escala completa positivo que resulta en un   codigo de 111 ... 111. El código de salida para cualquier voltaje de entrada analógica puede   ser representado como

     

Código = 2 N - 1 × [( AIN × GAIN / VREF ) + 1]

     

donde:
AIN es el voltaje de entrada analógica.
N = 16 para el AD7798, y N = 24 para el AD7799.

Estoy obteniendo un valor de ADC de 1EF2 (hex) para una entrada analógica de 0.6V. He medido utilizando un osciloscopio. He calculado el voltaje de entrada analógica utilizando la fórmula anterior y obtengo 0.15V. Aquí GAIN es 1, VREF = 2.5V. Lo cual está mal porque tengo que conseguir 0.6V. He convertido el valor ADC hexadecimal resultante en decimal 7922 y también en binary 0001111011110010 . Mi voltaje de entrada analógica varía de 0V a 0.6V. Según mi voltaje de entrada analógica, mi salida ADC también está cambiando de 0002 a 1EF2 .

Si cambio la configuración del registro de configuración a cualquier otra configuración como bipolar a unipolar (de 0x0010 a 0x1010 ), en ese momento obtengo un valor de ADC de 0000 siempre. Está dando un valor de ADC de 0000 para cualquier configuración que no sea 0x0010 en el registro de configuración.

Más allá, no puedo entender lo que significa la siguiente oración:

  

con un voltaje de escala total negativo que da como resultado un código de 000 ... 000,   una tensión de entrada diferencial cero que da como resultado un código de 100 ... 000,   y un voltaje de entrada positivo a gran escala que resulta en un código de   111 ... 111.

¿Cómo convierto correctamente la señal digital resultante a una tensión analógica?
¿Mis lecturas de ADC son correctas o incorrectas?
¿Por qué mi código no funciona para ninguna otra configuración?

    
pregunta verendra

2 respuestas

1

El AD7798 es un ADC diferencial. Tiene una entrada negativa y una entrada positiva. Cuando se configura para la operación bipolar:

  • Cuando la tensión entre in e e es positiva (en + > in-) en su totalidad escala la salida será todo uno.

  • Cuando el voltaje entre en + y en es 0 (en + == en) la salida será 1000 ... 0000.

  • Y cuando la tensión entre + e in- es negativa (en + < in-) a a escala completa, la salida será cero.

respondido por el Blup1980
0

Como mencionó Blup1980, el AD7798 es un ADC differential . Eso significa que toma la difference de las dos entradas y convierte ese valor.

Tienes:

AIN (+) = + 0.6V con referencia a GND
AIN (-) = + 2.5V con referencia a GND

Pero la diferencia entre las dos es:

$$ AIN = 0.6 - 2.5 = -1.9 $$

Tenemos lo siguiente:

$$ Código = 2 ^ {N - 1} × [(AIN × GAIN / VREF) + 1] $$ $$ 7922 = 32768 × [(AIN × 1 / 2.5) + 1] $$ $$ 0.24176025390625 = (AIN × 1 / 2.5) + 1 $$ $$ - 0.75823974609375 = AIN × 1 / 2.5 $$ $$ - 1.895599365234375 = AIN $$

Lo que es correcto.

Convertido en código C, tenemos:

int      code_dec;
float    code_flt;
float    ain_valu;

/* Initialize variables */
code_dec = 0U;
code_flt = 0.0F;
ain_valu = 0.0F;

code_dec = AD7798_16(0x58, 0xFFFF);                   /* Get Code from ADC */ 
code_flt = (float)code_dec;                           /* Cast Code into float */ 
ain_valu = ((code_flt / 32768.0F) - 1.0F) / 0.4F;     /* Perform calculation */

printf("Voltage is: %f\n", ain_valu);                 /* Print voltage value */

Convertir el valor del código en un float y luego usar los valores de float durante cada parte del cálculo es una buena práctica. Luego necesita el %f especificador de formato para asegurarse de que el valor se imprima como un punto flotante Número que incluirá el signo negativo si el valor es negativo. Si desea incluir el signo positivo para los valores positivos, utilice %+f en su lugar.

    
respondido por el embedded.kyle

Lea otras preguntas en las etiquetas