Estoy usando arm gcc (CooCox) para programar un descubrimiento STM32F4, y he estado luchando con un problema endiano
Estoy muestreando con un ADC de 24 bits a través de SPI. Ya que ingresan tres bytes, MSB primero tuve la idea de cargarlos en una unión para hacerlos (¡espero que de todos modos!) Un poco más fácil de usar.
typedef union
{
int32_t spilong;
uint8_t spibytes [4];
uint16_t spihalfwords [2];} spidata;
spidata analogin0;
Carga los datos usando lecturas spi en analogin0.spibytes [0] - [2], con [0] como MSB, luego los escupo a través de USART a un megabaud, 8 bits a la vez. No hay problemas.
Los problemas comenzaron cuando intenté pasar los datos a un DAC de 12 bits. Este SPI DAC quiere palabras de 16 bits, que consisten en un prefijo de 4 bits que comienza en el MSB, seguido de 12 bits de datos.
Los intentos iniciales fueron convertir los dos complementos que el ADC me proporcionó para compensar el binario, mediante la analogía analógica0.spihalfwords [0] con 0x8000, cambiando el resultado a los 12 bits inferiores y luego agregando el prefijo aritméticamente. / p>
Increíblemente frustrante, hasta que me di cuenta de que para analogin0.spibytes [0] = 0xFF y y analogin0.spibytes [1] = 0xB5, analogin0.halfwords [0] era igual a 0xB5FF y no 0xFFB5 !!!!!
Después de darme cuenta de esto, dejé de usar las operaciones aritméticas y la media palabra, y me quedé con la lógica bitwise y los bytes
uint16_t temp=0;
.
.
.
// work on top 16 bits
temp= (uint16_t)(analogin0.spibytes[0])<<8|(uint16_t)(analogin0.spibytes[1]);
temp=temp^0x8000; // convert twos complement to offset binary
temp=(temp>>4) | 0x3000; // shift and prepend with bits to send top 12 bits to DAC A
SPI_I2S_SendData(SPI3,temp); //send to DACa (16 bit SPI words)
... y esto funcionó bien. Cuando miro a temp después de la primera línea de código, su 0xFFB5, y no 0xB5FF, todo está bien
Entonces, para preguntas ...
-
Cortex es nuevo para mí. No puedo recordar el intercambio de bytes de PIC en int16, a pesar de que ambas plataformas son poco endian. ¿Es correcto?
-
¿Hay una manera más elegante de manejar esto? Sería genial si pudiera poner el ARM7 en modo big-endian. Estoy viendo muchas referencias a que Cortex M4 es bi-endian, pero todas las fuentes parecen no poder realmente decirme cómo . Más específicamente, cómo coloco el STM32f407 en modo big-endian , incluso mejor si se puede hacer en gcc. ¿Es solo una cuestión de establecer el bit apropiado en el registro AIRCR? ¿Hay alguna ramificación, como tener que configurar el compilador para que coincida, o errores de matemáticas más adelante con bibliotecas inconsistentes?