Sto usando arm gcc (CooCox) per programmare una scoperta STM32F4, e ho lottato con un problema di endian
Sto campionando con un ADC a 24 bit tramite SPI. Dato che arrivano tre byte, MSB per prima cosa mi è venuta l'idea di caricarli in un sindacato per renderli (speravo comunque!) Un po 'più facili da usare.
typedef union
{
int32_t spilong;
uint8_t spibytes [4];
uint16_t spihalfwords [2];} spidata;
spidata analogin0;
Carico i dati usando spi read in analogin0.spibytes [0] - [2], con [0] come MSB, quindi li sputo via USART a un megabaud, 8 bit alla volta. Nessun problema.
I problemi sono iniziati quando ho provato a passare i dati a un DAC a 12 bit. Questo DAC SPI richiede parole a 16 bit, che consistono in un prefisso a 4 bit a partire dall'MSB, seguito da 12 bit di dati.
I primi tentativi sono stati di convertire il complemento a due che l'ADC mi ha dato per compensare binario, xoring analogin0.spihalfwords [0] con 0x8000, spostando il risultato sui 12 bit inferiori e quindi aggiungendo il prefisso su aritmetica.
Incredibilmente frustrante, fino a quando non noto che per analogin0.spibytes [0] = 0xFF ee analogin0.spibytes [1] = 0xB5, analogin0.halfwords [0] era uguale a 0xB5FF e non 0xFFB5 !!!!!
Dopo aver notato questo, ho smesso di usare le operazioni aritmetiche e la mezza parola e mi sono bloccato sulla logica bit a bit e sui byte
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)
... e questo ha funzionato bene. Quando sbircio a temp dopo la prima riga di codice, è 0xFFB5 e non 0xB5FF, quindi tutto va bene
Quindi, per domande ...
Cortex è nuovo per me. Non riesco a ricordare che PIC abbia mai scambiato byte in int16, anche se entrambe le piattaforme sono poco endian. È corretto?
Esiste un modo più elegante per gestirlo? Sarebbe bello se potessi semplicemente mettere l'ARM7 in modalità big-endian. Sto vedendo molti riferimenti a Cortex M4 come bi-endian, ma tutte le fonti sembrano smettere di dirmi davvero come . Più specificamente, come posso mettere STM32f407 in modalità big-endian , ancora meglio se può essere fatto in gcc. È solo questione di impostare il bit appropriato nel registro AIRCR? Ci sono delle ramificazioni, come la necessità di impostare il compilatore affinché corrisponda, o problemi di matematica in seguito con librerie incoerenti?