Używam arm gcc (CooCox) do programowania odkrycia STM32F4 i walczyłem z problemem endian
Próbuję z 24-bitowym ADC przez SPI. Ponieważ nadchodzą trzy bajty, MSB najpierw wpadłem na pomysł załadowania ich do unii, aby uczynić je (w każdym razie mam nadzieję!) Nieco łatwiejszymi w użyciu.
typedef union
{
int32_t spilong;
uint8_t spibytes [4];
uint16_t spihalfwords [2];} spidata;
spidata analogin0;
Ładuję dane przy użyciu odczytów SPI do analogin0.spibytes [0] - [2], z [0] jako MSB, a następnie wypluwam je za pośrednictwem USART z megabudem, 8 bitów na raz. Bez problemów.
Problemy zaczęły się, gdy próbowałem przekazać dane do 12-bitowego przetwornika cyfrowo-analogowego. Ten SPI DAC chce 16-bitowych słów, które składają się z 4-bitowego przedrostka rozpoczynającego się od MSB, po którym następuje 12 bitów danych.
Początkowe próby polegały na przekształceniu dwójki uzupełnień, które ADC dał mi, aby skompensować dane binarne, poprzez xor-analogię0. Słowa-klucze [0] z 0x8000, przesunięcie wyniku do dolnych 12 bitów, a następnie dodanie przedrostka arytmetycznie.
Niesamowicie frustrujące, dopóki nie zauważę, że dla analogin0.spibytes [0] = 0xFF i i analogin0.spibytes [1] = 0xB5, analogin0.halfwords [0] było równe 0xB5FF, a nie 0xFFB5 !!!!!
Po zauważeniu tego przestałem używać operacji arytmetycznych i półsłówka, i utknąłem w logice bitowej i bajtach
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)
... i to działało dobrze. Kiedy zerkam w temp po pierwszym wierszu kodu, to 0xFFB5, a nie 0xB5FF, więc wszystko jest dobrze
W przypadku pytań ...
Kora jest dla mnie nowa. Nie pamiętam, żeby PIC zamieniał bajty w int16, mimo że obie platformy są małymi endianami. Czy to jest poprawne?
Czy istnieje bardziej elegancki sposób, aby sobie z tym poradzić? Byłoby wspaniale, gdybym mógł po prostu ustawić ARM7 w tryb big-endian. Widzę wiele odniesień do tego, że Cortex M4 jest bi-endianem, ale wszystkie źródła wydają się przestać mówić o tym, jak to zrobić . Mówiąc dokładniej, jak ustawić STM32f407 w trybie big-endian , nawet lepiej, jeśli można to zrobić w gcc. Czy to po prostu kwestia ustawienia odpowiedniego bitu w rejestrze AIRCR? Czy są jakieś konsekwencje, takie jak konieczność ustawienia kompilatora w celu dopasowania lub matematyczne błędy później z niespójnymi bibliotekami?