Cálculo de fórmulas e impresión de valor negativo.

Estoy leyendo con éxito el valor ADC externo usando ATmega32-A.

 Unsigned int adc;
 adc = AD7798_16(0x58, 0xFFFF);                           // read register 
       printf("ADC value is %d\r\n", adc);   

Obtengo el valor ADC como un rango de números decimales entre "0 y 65535". Quiero convertirlo en voltaje analógico usando la siguiente fórmula.

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

donde:
AIN es la tensión de entrada analógica.
N = 16 para el AD7798 y N = 24 para el AD7799.

He simplificado la fórmula y calculando

// fórmula para calcular el voltaje analógico de la salida digital: Código = 2N – 1× [(AIN × GAIN/VREF) + 1] // GAIN / VREF = 1 / 2.5 => 0.4 // 0.4 Ain = ((adc /
32768 ) - 1)

flotar Ain;

Ain=(((((float) adc) / 32768) - 1) / 0.416);

printf("valor:%.2f [v]\r\n", Ain);

La fórmula anterior devuelve siempre un valor negativo. Quiero imprimir ese valor negativo. He intentado como arriba pero no funciona. ¿Cómo imprimir el valor de Ain? aquí adc es un valor sin firmar, así que lo estoy convirtiendo en flotante.

He probado así también

Ain = (((adc / 32768.0) - 1) / 0.416);

printf("value:%.2f [v]\r\n", Ain);

pero no soy capaz de imprimir ese valor.

Agregué un código de ejemplo a mi respuesta a su otra pregunta. Si eso no ayuda, infórmenos qué está imprimiendo el código que proporcionó anteriormente. Si podemos ver lo que se está emitiendo, podemos ayudar a descubrir qué está mal con la entrada.

Respuestas (1)

Las bibliotecas AVR no se compilan para admitir la impresión de valores de punto flotante de forma predeterminada. Esto es para ahorrar espacio en sus entornos de recursos limitados. Debe indicarle al compilador y al enlazador que habiliten la compatibilidad con esta característica.

De la documentación de avr-libc en vfprintf():

Dado que la implementación completa de todas las características mencionadas se vuelve bastante grande, se vfprintf()pueden seleccionar tres sabores diferentes usando las opciones del enlazador. El valor predeterminado vfprintf()implementa todas las funciones mencionadas, excepto las conversiones de punto flotante. Hay disponible una versión minimizada de vfprintf()que solo implementa las funciones muy básicas de conversión de enteros y cadenas, pero solo se puede especificar la opción adicional # usando indicadores de conversión (estos indicadores se analizan correctamente desde la especificación de formato, pero luego simplemente se ignoran). Esta versión se puede solicitar utilizando las siguientes opciones del compilador:

-Wl,-u,vfprintf -lprintf_min

Si se requiere la funcionalidad completa, incluidas las conversiones de punto flotante, se deben usar las siguientes opciones:

-Wl,-u,vfprintf -lprintf_flt -lm

(énfasis mío)

Dado que está utilizando CodeVisionAVR como discutimos en el chat , tienen esta opción integrada en su ventana de configuración como se ve en la página 4, paso 9 de este tutorial :

ingrese la descripción de la imagen aquí