Я использую arm gcc (CooCox) для программирования STM32F4 обнаружения, и я борюсь с проблемой endian
Я использую 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 с мегабодом, 8 бит за раз. Нет проблем.
Проблемы начались, когда я попытался передать данные в 12-битный ЦАП. Этот ЦАП SPI хочет 16-битные слова, которые состоят из 4-битного префикса, начиная с MSB, за которым следуют 12 бит данных.
Первоначальные попытки состояли в том, чтобы преобразовать два дополнения, которые АЦП дал мне для смещения двоичного кода, путем перехвата аналога аналога 0.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, хотя обе платформы имеют младший порядок байтов. Это верно?
Есть ли более элегантный способ справиться с этим? Было бы здорово, если бы я мог просто перевести ARM7 в режим с прямым порядком байтов. Я вижу много ссылок на то, что Cortex M4 является bi-endian, но, похоже, все источники не дают понять, как это сделать . Более конкретно, как мне перевести STM32f407 в режим с прямым порядком байтов , даже лучше, если это можно сделать в gcc. Это просто вопрос установки соответствующего бита в регистре AIRCR? Есть ли какие-либо последствия, такие как необходимость настройки соответствия компилятора, или математические ошибки позже с несовместимыми библиотеками?
__REV()
и__REV16()
для реверсирования байтов.Ответы:
Встраиваемые системы всегда будут иметь проблему с прямым порядком байтов / прямым порядком байтов. Мой личный подход состоял в том, чтобы всегда кодировать внутреннюю память с присущим ей порядком байтов и делать любые перестановки прямо при входе или выходе данных.
Загружая [0] как MSB, вы кодируете значение как big-endian.
Это указывает на то, что процессор имеет младший порядок.
Если вместо этого вы загружаете первое значение в [2] и возвращаетесь к [0], то вы закодировали входящий номер как little-endian, по сути, делая своп при вводе числа. Как только вы работаете с нативным представлением, вы можете вернуться к исходному подходу использования арифметических операций. Просто убедитесь, что вы перевернули его в обратный порядок при передаче значения.
источник
Что касается награды "Действительно хочу знать о режиме с прямым порядком байтов srm32f4", на этом чипе нет режима с прямым порядком байтов. STM32F4 делает весь доступ к памяти в порядке байтов.
В руководстве пользователя http://www.st.com/web/en/resource/technical/document/programming_manual/DM00046982.pdf это упоминается на странице 25. Но это еще не все. На странице 93 вы можете увидеть инструкции по обмену порядком байтов. REV и REVB для обратного и обратного битов. REV изменит порядок байтов на 32 бита, а REV16 сделает это для 16-битных данных.
источник
Вот фрагмент кода для коры M4, скомпилированный с gcc
От C вызов может быть:
Не знаю, как сделать быстрее, чем это :-)
источник
Для CooCox STM32F429 это нормально:
...
источник