У меня есть встроенный проект с USART HAL.Этот USART может передавать или принимать только 8 или 16 битов за раз (в зависимости от выбранного нами регистра usart, т.е. одиночный / двойной вход / выход).Поскольку это 32-битный MCU, я подумал, что мог бы также обойти 32-битные поля, поскольку (из того, что я уже понял), это более эффективное использование битов для MPU.То же самое относится и к 64-битному MPU, то есть к 64-битным целым числам.Возможно, это неверный совет или совет, вырванный из контекста.
Имея это в виду, я упаковал 8 бит в 32-битное поле с помощью сдвига битов.Я делаю это как для TX, так и для RX на Usart.
Код только для 8-битного регистра следующий (16-битный регистр имеет только половину количества циклов для сдвига битов):
int zg_usartTxdataWrite(USART_data* MPI_buffer,
USART_frameconf* MPI_config,
USART_error* MPI_error)
{
MPI_error = NULL;
if(MPI_config != NULL){
zg_usartFrameConfWrite(MPI_config);
}
HPI_usart_data.txdata = MPI_buffer->txdata;
for (int i = 0; i < USART_TXDATA_LOOP; i++){
if((USART_STATUS_TXC & usart->STATUS) > 0){
usart->TXDATAX = (i == 0 ? (HPI_usart_data.txdata & USART_TXDATA_DATABITS) : (HPI_usart_data.txdata >> SINGLE_BYTE_SHIFT) & USART_TXDATA_DATABITS);
}
usart->IFC |= USART_STATUS_TXC;
}
return 0;
}
РЕДАКТИРОВАТЬ: RE-ВВОДНАЯ ЛОГИКА ВЫШЕГО КОДА С ДОБАВЛЕННЫМИ ОПРЕДЕЛЕНИЯМИ ДЛЯ ЯСНОСТИ ПРОБЛЕМЫ НЕЗАКОННОГО ПРОДВИЖЕНИЯ ТЕРНАРНОГО ОПЕРАТОРА, ОБСУЖДЕННОЙ В РАЗДЕЛЕ КОММЕНТАРИЙ
(структуры HPI_usart и USART_data - это те же самые разные уровни, с тех пор я удалил слой HPI_usart, норади этого примера я оставлю его в этом)
#define USART_TXDATA_LOOP 4
#define SINGLE_BYTE_SHIFT 8
typedef struct HPI_USART_DATA{
...
uint32_t txdata;
...
}HPI_usart
HPI_usart HPI_usart_data = {'\0'};
const uint8_t USART_TXDATA_DATABITS = 0xFF;
int zg_usartTxdataWrite(USART_data* MPI_buffer,
USART_frameconf* MPI_config,
USART_error* MPI_error)
{
MPI_error = NULL;
if(MPI_config != NULL){
zg_usartFrameConfWrite(MPI_config);
}
HPI_usart_data.txdata = MPI_buffer->txdata;
for (int i = 0; i < USART_TXDATA_LOOP; i++){
if((USART_STATUS_TXC & usart->STATUS) > 0){
usart->TXDATAX = (i == 0 ? (HPI_usart_data.txdata & USART_TXDATA_DATABITS) : (HPI_usart_data.txdata >> SINGLE_BYTE_SHIFT) & USART_TXDATA_DATABITS);
}
usart->IFC |= USART_STATUS_TXC;
}
return 0;
}
Однако теперь я понимаю, что это потенциально вызывает больше проблем, чем решает, потому что я по сути внутренне кодирую эти биты, которые затем должны быть декодированы почти немедленнокогда они передаются в / из разных слоев данных.Я чувствую, что это умное и сексуальное решение, но сейчас я пытаюсь решить проблему, которую я не должен был создавать в первую очередь.Например, как извлечь переменные битовые поля, когда есть смещение, то есть в предложениях gps nmea, где первые 8 битов могут быть одним релевантным полем, а затем остальные являются 32-битными полями.В итоге получается так:
32-битный член массива 0:
bits 24-31 bits 15-23 bits 8-15 bits 0-7
|8-битное значение |32-битное значение A, биты 24-31 |32-битное значение A, биты 16-23 |32-битное значение A, биты 8-15 |
32-битный элемент массива 1:
bits 24-31 bits 15-23 bits 8-15 bits 0-7
|32-битное значение A, биты 0-7 |32-битное значение B, биты 24-31 |32-битное значение B, биты 16-23 |32-битное значение B, биты 8-15 |
32-битный элемент массива 2:
bits 24-31 15-23 8-15 ...
|32-битное значение B, биты 0-7 |и т.д ... |.... |.... |
Приведенный выше пример требует ручного декодирования, что, я думаю, хорошо, но оно отличается для каждого предложения nmea и кажется более ручным, чем программным.
У меня такой вопрос: битовое смещение против индексации массива, что более уместно?
Должен ли я просто назначить каждое входящее / исходящее значение 32-битному элементу массива, а затем просто индексировать таким образом?Я чувствую, что это решение, так как оно не только облегчит прохождение данных на других уровнях, но я смогу устранить всю эту логику сдвига битов, и тогда единственная разница между функцией rx или tx будетнаправление данных идет.
Это означает небольшую переписку интерфейса и получающегося слоя модуля gps, но это похоже на меньшую работу, а также дешевый урок в начале моего проекта.
Также любые мысли и общий опыт по этому поводу были бы великолепны.