ฉันกำลังใช้ arm gcc (CooCox) เพื่อเขียนโปรแกรม STM32F4 การค้นพบและฉันได้รับการต่อสู้กับปัญหา endian
ฉันสุ่มตัวอย่างด้วย ADC 24 บิตผ่าน SPI เนื่องจากสามไบต์กำลังเข้ามา MSB ครั้งแรกที่ฉันมีความคิดในการโหลดมันลงในกลุ่มเพื่อให้พวกเขา (ฉันหวังว่าต่อไป!) ใช้งานง่ายขึ้นเล็กน้อย
typedef union
{
int32_t spilong;
uint8_t spibytes [4];
uint16_t spihalfwords [2];} spidata;
spidata analogin0;
ฉันโหลดข้อมูลโดยใช้ spi อ่านเป็น analogin0.spibytes [0] - [2], ด้วย [0] ในฐานะ MSB จากนั้นฉันพ่นมันออกทาง USART ที่ megabaud ครั้งละ 8 บิต ไม่มีปัญหา.
ปัญหาเริ่มต้นขึ้นเมื่อฉันพยายามส่งข้อมูลไปยัง DAC 12 บิต SPI DAC นี้ต้องการคำ 16 บิตซึ่งประกอบด้วยคำนำหน้า 4 บิตเริ่มต้นที่ MSB ตามด้วยข้อมูล 12 บิต
ความพยายามเริ่มแรกคือการแปลง twos ที่ ADC มอบให้ฉันเพื่อชดเชยไบนารีโดย xor-ing analogin0.spihalfwords [0] ด้วย 0x8000 เปลี่ยนผลลัพธ์เป็น 12 บิตด้านล่างจากนั้นเพิ่มคำนำหน้าบนเลขคณิต
น่าผิดหวังอย่างไม่น่าเชื่อจนกระทั่งฉันสังเกตเห็นว่าสำหรับ analogin0.spibytes [0] = 0xFF และและ analogin0.spibytes [1] = 0xB5, analogin0.halfwords [0] เท่ากับ 0xB5FF และไม่ใช่ 0xFFB5 !!!!!
หลังจากสังเกตเห็นสิ่งนี้ฉันหยุดใช้การดำเนินการทางคณิตศาสตร์และครึ่งคำและติดอยู่กับตรรกะระดับบิตและไบต์
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)
... และมันก็ใช้ได้ดี เมื่อฉันดูที่ temp หลังจากบรรทัดแรกของรหัส 0xFFB5 ของมันและไม่ใช่ 0xB5FF ดังนั้นทั้งหมดเป็นสิ่งที่ดี
ดังนั้นสำหรับคำถาม ...
Cortex นั้นใหม่สำหรับฉัน ฉันจำไม่ได้ว่า PIC ใช้ไบต์สลับกันใน int16 ได้แม้ว่าทั้งสองแพลตฟอร์มจะเป็น endian น้อยก็ตาม ถูกต้องหรือไม่
มีวิธีที่สง่างามกว่านี้ในการจัดการกับเรื่องนี้หรือไม่? มันจะดีมากถ้าฉันสามารถใส่ ARM7 เข้าสู่โหมด big-endian ฉันเห็นการอ้างอิงจำนวนมากเพื่อ Cortex M4 เป็นสอง endian แต่แหล่งที่มาทั้งหมดดูเหมือนจะหยุดสั้นของจริงบอกฉันว่า โดยเฉพาะอย่างยิ่งฉันจะวาง STM32f407 ในโหมด big-endianได้ดียิ่งขึ้นถ้าสามารถทำได้ใน gcc นี่เป็นเพียงการตั้งค่าบิตที่เหมาะสมในการลงทะเบียน AIRCR หรือไม่? มี ramifications เช่นต้องตั้งคอมไพเลอร์ให้ตรงกันหรือ math screwups ภายหลังด้วยไลบรารีที่ไม่สอดคล้องกันหรือไม่?