Convertir el complemento de 32 bits 2 al número decimal

3

Tengo datos provenientes de un chip de medición de energía V9261F ( enlace a la hoja de datos ), que lo envía Datos a través de un UART a mi microcontrolador Arduino. Cuando leí el registro 0x0119, leí la potencia activa medida por el chip. Pero el problema es que esta retroalimentación está en el complemento de 32 bits 2 y no puedo descodificarla.

A partir del 4to byte en la ruta están los bytes de datos en los que se almacenan las variables medidas (vea la hoja de datos pág. 56 - 57). Para el registro de lectura 0x0119, debe estar en el databyte 10 - 11 - 12 y 13 (D1) respectivamente 0x55, 0xE7, 0x0E y para el databyte 13 0x00.

Entonces, la retroalimentación para la potencia activa de todos los bytes combinados que tengo es 0x000EE755 - > restar 1 (para 1 complemento) = 0x000EE754 - > inviértalo para que se convierta en un número decimal = 0xFFF118AB (4293990571 dec). Pero este gran número solo debería representar una potencia activa de 6.2 vatios.

¿Qué hago mal al convertir el complemento de 2 al decimal? ¿Cómo debe esto representar 6.2 vatios?

    
pregunta Bert

3 respuestas

4

Creo que tienes una mala interpretación de lo que significa "complemento de 2". Un número de complemento positivo 2 es idéntico a un número binario positivo (el bit más significativo debe ser cero). Entonces para 8 bits tenemos 0x00 (cero) a 0x7F (127). Los números menores que cero van de 0xFF (-1) a 0x80 (-128). Para hacer que un número negativo sea positivo, de modo que pueda mostrarlo como un signo menos delante de un número positivo, puede calcular el complemento de 2 como se muestra arriba. Tenga en cuenta el caso especial de 0x80.

Entonces, con 0x000EE754 tienes un número positivo de 976724 decimal. Hay un factor de escala entre eso y 6.2 de 6.3478E-6.

Probablemente lo que quieres hacer es convertir el número en un número de punto flotante y hacer los cálculos en punto flotante. Es ya en formato entero enteros de 32 bits.

    
respondido por el Spehro Pefhany
5

El complemento de Two es un formato para describir números negativos . Se aplica cuando el número es negativo. Tus cálculos no tienen ningún sentido. enlace

De acuerdo con RTFM, el formato de datos del dispositivo es 32 bit 2 complemento little endian. Entonces, dado que su MCU es little endian (que es el caso de AVR), no necesita convertir nada. Simplemente almacene el resultado en un int32_t .

El formato de datos para UART es LSB primero y la herramienta que creó la imagen parece ser consciente. Entonces, si tiene algunos datos como 55e70e00, entonces esa es la información real leída. Ya que es little endian, corresponde al hexadecimal 0x000ee755, decimal 976725. Este es el valor con el que debe terminar después de leer el registro de UART rx. Si este número tiene sentido, no tengo idea.

El complemento de

2 no importa ya que el número es positivo en este caso. Un número negativo tendría un 1 binario en el MSB.

    
respondido por el Lundin
2

La forma en que me gusta pensar acerca de los números del complemento de dos es pensar qué pasa con los bits más bajos de un número binario al restar. Si los 4 bits inferiores de x son 0000 y los cuatro bits inferiores de y son 0001, entonces los cuatro bits inferiores de x-y serán 1111 independientemente de qué bits estén por encima de ellos. Esto se puede generalizar fácilmente para cualquier número particular de bits (restando un número cuyos bits inferiores expresan el valor 1 de un número cuyos bits inferiores expresan el valor 0 producirá un número cuyos bits inferiores están todos configurados). Como eso funcionará para cualquier número de bits, puede generalizarse aún más para decir que al restar uno de cero se obtendrá un número con un número infinito de bits establecido.

En la práctica, almacenar un número infinito de bits no es práctico. Para cualquier N & gt = 1, sin embargo, todos los números dentro del rango - (2 ^ N) a (2 ^ N) -1, sin embargo, todos los bits a la izquierda del bit Nth (contando a la izquierda) tendrán el mismo valor que el Nth bit en sí, y por lo tanto no necesita ser almacenado. Por lo tanto, cuando se utilizan valores de complemento a dos de 8 bits, el valor -1 no es "realmente" 10000000, sino que es [número infinito de 1s] 0000000, y el valor 127 no es 01111111, sino [número infinito de 0s] 1111111. Ver las cosas de esta manera dejará en claro cómo deberían funcionar las conversiones entre diferentes tamaños de valores.

Por ejemplo, convertir el valor de 8 bits a 16 bits simplemente implicaría copiar parte de la cadena inifinita de 1s o ceros, mientras que la conversión de un valor de 16 bits en el rango -128..127 a 8 bits implicaría dejando caer algunos bits duplicados. Si un número de 16 bits está fuera de ese rango, convertirlo a 8 bits generaría el valor que resultaría de copiar el bit retenido más singular.

PS: aplicando la fórmula de suma de potencia 1 + 2 + 4 + 8 ... produce -1. Eso puede parecer absurdo, pero encaja perfectamente con el funcionamiento de las matemáticas de dos. Para cualquier valor de N, si todos los N bits inferiores de un número están configurados, la adición de 1 dará como resultado un número cuyos N bits inferiores están claros. El único número para el que se borrarán los N bits inferiores para todos los valores de N es cero, y el único número que dará 0 cuando se le agregue 1 es, por supuesto, -1.

    
respondido por el supercat

Lea otras preguntas en las etiquetas