来自加速度计的数据转换

时间:2014-06-10 05:04:39

标签: c embedded accelerometer

大家好我正在研究加速度计bma220,它的数据表说数据是2的补码形式。所以我要做的就是在任何8位有符号字符中获取8位数据并完成。 bma220有一个8位寄存器,其中前6位是数据,后两位是零。

void properdata(int16_t *msgData)
{
    printf("\nin proper data\n");
    int16_t temp, i;
    for(i=0; i<3; i++)
    {
        temp = *(msgData + i);
        printf("temp = %d sense = %d\n", temp, sense);
        temp = temp >> 2;    // only 6 bits data
        temp = temp / sense; //decimal value * .0625 = value in g
        printf("temp = %d\n", temp);            
    }    
}

在这个程序中,我在无符号变量msgdata中获取数据并对有符号变量进行所有计算。我只需要知道这是否是转换数据的正确方法?


经过一些建议后,我将代码更改为

  void properdata(uint16_t *msgData)
  {
    int arr[3];
    arr[0] = msgData[0];
    arr[1] = msgData[1];
    arr[2] = msgData[2];
    arr[0] = arr[0]/4;
    arr[1] = arr[1]/4;
    arr[2] = arr[2]/4;
    printf("x = %d y = %d z = %d\n", arr[0], arr[1], arr[2]);
 }

现在处于静止状态我得到61,60和17的数据。如果我认为数据应该在31到-32的范围内,但是这里它超出了范围?

3 个答案:

答案 0 :(得分:2)

  

在这个程序中我正在使用无符号变量msgdata

中的数据

不,你不是。 msgdata是一个签名变量。

  

我只需要知道这是否是转换数据的正确方法?

对已签名变量使用逐位运算符几乎总是一个错误。您对已签名变量执行右移,这是实现定义的行为,符号位将发生什么取决于编译器。

答案 1 :(得分:2)

我在你的代码中看到两个问题:

1)正如Lundin所说,将负值向右移动是危险的,因为行为是编译器特定的。

2)根据数据表,加速剂的范围是1.94 ...- 2.00 g。您尝试将值存储为普通整数。这里至少需要定点算术(或浮点数)。或者你的结果只有1,0,-1或-2。

以下代码应考虑这些要点(未经测试):

int16_t  raw;       // the 8 bit raw value from the chip
int32_t  accel;     // acceleration in mg

raw =  (int16_t) read_value_from_chip();   // get 8 bits raw value from chip

accel = (int32_t)(raw / 4) * 625;  // to avoid to shift to right, use division here
if ( accel >= 0 )
  accel = ( accel + 5 ) / 10;
else
  accel = ( accel - 5 ) / 10;

printf("%ld\n", accel);

说明:

根据数据表,分辨率为62.5毫克,最重要的6位保留有符号原始值。

为避免在将位置于位置时明确处理符号,此处使用除法而不是右移。使用除以4代替&gt;&gt;这样就可以根据需要保留标志。

如果编译器/ MCU在负值向右移位时设置左侧1的位,则优化编译器将通过位移替换该除法。如果编译器/ MCU不支持,则使用除法。

* 625用于获得所需分辨率为1/10 mg的加速度(1位数为0.1 mg)。 625是0.0625 * 10000的缩写形式。(更新

为了得到毫克,加速度除以10(我这里这样做只是因为mg比0.1毫克更方便)。要正确舍入,必须根据分割前的符号加上/减去一半的被除数,这里是10/2 = 5.

现在的结果是mg。

如果要避免除法,则必须在将有效位置于适当位置时明确处理负值/正值。

答案 2 :(得分:0)

通常,规格表将有一个或两个示例转换。它可能显示值0000 0000(二进制)为零,0100 0000为47.25 g。通过代码运行示例值进行验证。