将原始加速度计值转换为 12 位数

Converting raw Accelerometer values to 12 bit number

我正在编写一个内置在微控制器(TZ1000 系列)中的加速度计。我正在尝试将数据 BLE 发送到 PC 应用程序。我必须以 2 个字节发送数字并在应用程序端接收它并将它组合成一个 12 位数字。我在将实际的原始加速度计值转换为 12 位数时遇到问题。我正在按以下格式阅读它。

acc->ReadAcceleration((uint16_t*)buf);  
ChannelX[M] = (buf[0].acceleration << 4) & 0xFFF0;
ChannelY[M] = (buf[1].acceleration << 4) & 0xFFF0;
ChannelZ[M] = (buf[2].acceleration << 4) & 0xFFF0;

其中变量的类型和大小如下,

int16_t ChannelX[4] = {0,0,0,0};
int16_t ChannelY[4] = {0,0,0,0};
int16_t ChannelZ[4] = {0,0,0,0};

bufstatic ACCEL_ACCELERATION buf[12];类型,其结构如下,

  typedef struct _ACCEL_ACCELERATION {
       uint16_t updated      : 1;
      uint16_t reserved     : 3;
      int16_t  acceleration :12;
    } ACCEL_ACCELERATION;

现在,当我将此数据转换为两个字节并通过 BLE 传输时,我遵循以下逻辑。

uart_tx_data[i]   = (uint8_t) (ChannelX[j] & 0xFF);
uart_tx_data[i+1] = (uint8_t) ((ChannelX[j]>>12) & 0x0F) ;

uart_tx_data[i+2] = (uint8_t) (ChannelY[j] & 0xFF);
uart_tx_data[i+3] = (uint8_t) ((ChannelY[j]>>12) & 0x0F) ;

uart_tx_data[i+4] = (uint8_t) (ChannelZ[j] & 0xFF);
uart_tx_data[i+5] = (uint8_t) ((ChannelZ[j]>>12) & 0x0F) ;

其中变量的类型为static uint8_t uart_tx_data[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

在接收端,我将其转换为 12 位数字,如下所示,

X[i]= (num[2] & 0xFF) | ((num[3] & 0x0F) << 12);

其中 int[] X= new int[2];

我得到的值是错误的,我通过在加速度计上进行 1g 测试来检查它。例如,当它平坦时,它应该给出一个接近于零的数字。在 1g 时,它应该根据我设置的灵敏度给出一个数字(在我的例子中它是 8G,值为 256)。

难道我用的逻辑有问题??我请求有人帮助我解决这个问题。

提前谢谢你。

你的轮班都结束了。使用常量来查看发生了什么。示例:将 0x1234 放入结构中(注意我假设 16 位变量并且不关心结构中的位字段会稍微改变一些但不是它不起作用的原因)

ChannelX[M] = (buf[0].acceleration << 4) & 0xFFF0;

这将导致 0x2340。不确定为什么要将最低四位设为零,但让我们继续吧。然后你发送它:

uart_tx_data[i]   = (uint8_t) (ChannelX[j] & 0xFF);
uart_tx_data[i+1] = (uint8_t) ((ChannelX[j]>>12) & 0x0F) ;

第一部分将是 0x2340 & 0xff == 0x40,因此您总是从最低位开始发送四个零。第二部分将是 0x2340 >> 12 == 0x02,所以你错过了整个 3 部分。

为什么不简单地取 acceleration 的值并在不使最低四位为零的情况下发送它呢?位字段将使其变成 12 位值。并且发送班次时为 8,而不是 12。

ChannelX[M] = buf[0].acceleration;
uart_tx_data[i]   = (uint8_t) (ChannelX[j] & 0xFF);
uart_tx_data[i+1] = (uint8_t) ((ChannelX[j]>>8) & 0x0F);