Saya menggunakan arm gcc (CooCox) untuk memprogram penemuan STM32F4, dan saya sudah bergulat dengan masalah endian
Saya mengambil sampel dengan ADC 24 bit melalui SPI. Karena tiga byte datang, MSB pertama-tama saya punya ide memuat mereka ke dalam serikat untuk membuat mereka (saya berharap, bagaimanapun!) Sedikit lebih mudah digunakan.
typedef union
{
int32_t spilong;
uint8_t spibytes [4];
uint16_t spihalfwords [2];} spidata;
spidata analogin0;
Saya memuat data menggunakan spi yang dibaca dalam analogin0.spibytes [0] - [2], dengan [0] sebagai MSB, kemudian saya memuntahkannya melalui USART pada megabaud, 8 bit sekaligus. Tidak ada masalah.
Masalah dimulai ketika saya mencoba meneruskan data ke DAC 12 bit. SPI DAC ini membutuhkan 16 bit kata, yang terdiri dari awalan 4 bit mulai dari MSB, diikuti oleh 12 bit data.
Upaya awal adalah untuk mengkonversi dua-dua komplemen yang diberikan ADC saya untuk mengimbangi biner, dengan xor-ing analogin0.spihalfwords [0] dengan 0x8000, menggeser hasilnya ke 12 bit bagian bawah, dan kemudian menambahkan awalan pada aritmatika.
Sangat membuat frustrasi, sampai saya perhatikan bahwa untuk analogin0.spibytes [0] = 0xFF dan dan analogin0.spibytes [1] = 0xB5, analogin0.halfwords [0] sama dengan 0xB5FF dan bukan 0xFFB5 !!!!!
Setelah memperhatikan ini, saya berhenti menggunakan operasi aritmatika dan kata setengahnya, dan menempel pada logika bitwise dan 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)
... dan ini bekerja dengan baik. Ketika saya mengintip temp setelah baris kode pertama, 0xFFB5, dan bukan 0xB5FF, jadi semuanya baik-baik saja
Jadi, untuk pertanyaan ...
Cortex baru bagi saya. Saya tidak ingat PIC pernah bertukar byte di int16's, meskipun kedua platform sedikit endian. Apakah ini benar?
Apakah ada cara yang lebih elegan untuk menangani ini? Akan lebih bagus jika saya bisa memasukkan ARM7 ke mode big-endian. Saya melihat banyak referensi bahwa Cortex M4 adalah bi-endian, tetapi semua sumber tampaknya berhenti untuk memberi tahu saya caranya . Lebih khusus lagi, bagaimana cara menempatkan STM32f407 ke mode big-endian , bahkan lebih baik lagi jika itu dapat dilakukan dalam gcc. Apakah ini HANYA masalah pengaturan bit yang sesuai dalam register AIRCR? Apakah ada konsekuensi, seperti harus mengatur kompiler agar sesuai, atau matematika kemudian dikacaukan dengan pustaka yang tidak konsisten ??
__REV()
dan__REV16()
untuk membalikkan byte.Jawaban:
Sistem tertanam akan selalu memiliki masalah big-endian / little-endian. Pendekatan pribadi saya adalah selalu menyandikan memori internal dengan endianiness asli dan membuat swap yang benar ketika data masuk atau pergi.
Dengan memuat [0] sebagai MSB, Anda menyandikan nilainya sebagai big-endian.
Ini menunjukkan bahwa prosesornya adalah little-endian.
Jika sebaliknya, Anda memuat nilai pertama ke [2] dan bekerja kembali ke [0], maka Anda telah menyandikan angka yang masuk sebagai little-endian, yang pada dasarnya menjadikan swap saat nomor tersebut masuk. Setelah Anda bekerja dengan representasi asli, Anda dapat kembali ke pendekatan awal menggunakan operasi aritmatika. Pastikan untuk membalikkannya kembali ke big-endian ketika Anda mengirimkan nilainya.
sumber
Mengenai karunia "Benar-benar ingin tahu tentang mode big endian srm32f4", tidak ada mode endian besar pada chip ini. STM32F4 melakukan semua akses memori di little endian.
Panduan pengguna http://www.st.com/web/en/resource/technical/document/programming_manual/DM00046982.pdf menyebutkan ini di halaman 25. Tetapi ada lebih banyak. Pada halaman 93 Anda dapat melihat ada instruksi bertukar endian. REV dan REVB untuk mundur dan mundur sedikit. REV akan mengubah endianess untuk 32 bit dan REV16 akan melakukannya untuk data 16 bit.
sumber
Berikut ini adalah cuplikan kode untuk korteks M4, dikompilasi dengan gcc
Dari C, panggilan dapat:
Tidak tahu bagaimana melakukan lebih cepat dari ini :-)
sumber
Untuk CooCox STM32F429 ini tidak masalah:
...
sumber