Ich benutze arm gcc (CooCox), um eine STM32F4-Entdeckung zu programmieren, und ich habe mit einem Endian-Problem gerungen
Ich probiere mit einem 24-Bit-ADC über SPI. Da drei Bytes eingehen, hatte MSB zuerst die Idee, sie in eine Union zu laden, um sie (ich hoffte jedenfalls!) Ein wenig benutzerfreundlicher zu machen.
typedef union
{
int32_t spilong;
uint8_t spibytes [4];
uint16_t spihalfwords [2];} spidata;
spidata analogin0;
Ich lade die Daten mit spi-Lesevorgängen in analogin0.spibytes [0] - [2] mit [0] als MSB und spucke sie dann über USART mit einer Megabaud aus, jeweils 8 Bit. Keine Probleme.
Die Probleme begannen, als ich versuchte, die Daten an einen 12-Bit-DAC weiterzuleiten. Dieser SPI-DAC möchte 16-Bit-Wörter, die aus einem 4-Bit-Präfix bestehen, das beim MSB beginnt, gefolgt von 12 Datenbits.
Anfängliche Versuche waren, das Zweierkomplement zu konvertieren, das der ADC mir gab, um Binär zu versetzen, indem analogin0.spihalfwords [0] mit 0x8000 xoriert, das Ergebnis auf die unteren 12 Bits verschoben und dann das Präfix arithmetisch hinzugefügt wurde.
Unglaublich frustrierend, bis ich bemerke, dass für analogin0.spibytes [0] = 0xFF und und analogin0.spibytes [1] = 0xB5 analogin0.halfwords [0] gleich 0xB5FF und nicht 0xFFB5 war !!!!!
Nachdem ich dies bemerkt hatte, hörte ich auf, arithmetische Operationen und das Halbwort zu verwenden, und hielt mich an die bitweise Logik und die 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)
... und das hat gut funktioniert. Wenn ich nach der ersten Codezeile auf temp schaue, ist es 0xFFB5 und nicht 0xB5FF, also ist alles gut
Also, für Fragen ...
Cortex ist neu für mich. Ich kann mich nicht erinnern, dass PIC jemals in Int16-Bytes ausgetauscht wurde, obwohl beide Plattformen Little Endian sind. Ist das richtig?
Gibt es eine elegantere Möglichkeit, damit umzugehen? Es wäre großartig, wenn ich den ARM7 einfach in den Big-Endian-Modus versetzen könnte. Ich sehe viele Hinweise darauf, dass Cortex M4 bi-endian ist, aber alle Quellen scheinen nicht mehr zu sagen, wie . Genauer gesagt, wie versetze ich den STM32f407 in den Big-Endian-Modus , noch besser, wenn dies in gcc möglich ist. Geht es nur darum, das entsprechende Bit im AIRCR-Register zu setzen? Gibt es Konsequenzen, z. B. dass der Compiler so eingestellt werden muss, dass er übereinstimmt, oder dass es später zu mathematischen Problemen mit inkonsistenten Bibliotheken kommt?