Как обрабатывать 20-битные данные датчика

У меня есть датчик ускорения (ADXL355), который возвращает 20-битные данные в трех байтах, отформатированные как дополнение 2s:

  • acc3 (биты 19-12) в байтовом регистре 3 (сопоставлен битам 7-0)
  • acc2 (биты 11-4) в байтовом регистре 2 (сопоставлен битам 7-0)
  • acc1 (биты 3-0) в байтовом регистре 1 (сопоставляется битам 7-4, пока 3-0 не используются)

значение ускорения берется как 32 - разрядное целое число со знаком из вышеуказанных 3 регистров следующим образом :

int32_t acc32 = ((uint32_t)acc3 << 12) | ((uint16_t)acc2 << 4) | (acc1 >> 4);

if (acc32 & (1UL << 19)) acc32 -= 1UL << 20;

Затем я провожу некоторый статистический анализ значений ускорения, чтобы вычислить обрезку смещения как 32-битное целое число со знаком.

int32 off32;

Это смещение должно быть записано обратно в датчик в виде 16 - битного дополнительного значения 2s следующим образом :

  • старший байт смещения (биты 15-8)
  • младший байт смещения (биты 7-0)

В техническом описании указано, что "Значение битов смещения 15-0 соответствует значению битов ускорения 19-4".

Я нашел это довольно сложным, поэтому я спрашиваю, как преобразовать это подписанное 32-битное целое число со смещением в 16-битное целое число со смещением, которое соответствует приведенной выше спецификации.

У меня была такая идея, но я не знаю, правильна ли она:

int16_t off16[i] = (int16_t)(off32[i] / 16);

sendSPI((uint8_t)(off16 >> 8));
sendSPI((uint8_t)off16);

Любой комментарий должен быть высоко оценен!

, 👍2


1 ответ


Лучший ответ:

2

За исключением нижнего индекса [i], который выглядит подозрительно, то, что вы сделали , кажется мне совершенно правильным. Теперь, если я начну придираться, я могу предложить:

  • используйте битовый сдвиг, так как это намного дешевле, чем деление
  • округлять до ближайшего, а не до нуля или минус бесконечности.

Это дает:

int16_t off16 = (off32 + 8) >> 4;

Обратите внимание, что битовый сдвиг ведет себя как деление, которое округляется в сторону −∞ (обычное деление округляется до нуля). Добавление 8 приводит к округлению до ближайшего, с округлением связей в большую сторону.

,

Большое спасибо за ваш ответ! Да, подстрочного [i] там быть не должно! Что касается битового сдвига, я не был уверен, работает ли он как деление в целых числах со знаком, поэтому вместо этого я выбрал деление., @Vassilis Papanikolaou