我使用 LIS3DH 传感器和 ATmega128 来获取运动的加速度值。我浏览了数据表,但它似乎不够充分,所以我决定将其发布在这里。从其他帖子中我确信传感器分辨率是 12 位而不是 16 位。我需要知道,当从x轴输出寄存器中查找g值时,我们是否仅在OUT_X_H(高位寄存器)的符号位MSB为1时才计算寄存器值的2'2补码,或者每次即使这样位为0。
根据我的计算,我认为只有当 OUT_X_H 寄存器的 MSB 为 1 时,我们才计算二进制补码。
但是数据表说我们每次都需要计算 OUT_X_L 和 OUT_X_H 的二进制补码。
有人可以告诉我这个吗?
示例代码
int main(void)
{
stdout = &uart_str;
UCSRB=0x18; // RXEN=1, TXEN=1
UCSRC=0x06; // no parit, 1-bit stop, 8-bit data
UBRRH=0;
UBRRL=71; // baud 9600
timer_init();
TWBR=216; // 400HZ
TWSR=0x03;
TWCR |= (1<<TWINT)|(1<<TWSTA)|(0<<TWSTO)|(1<<TWEN);//TWCR=0x04;
printf("\r\nLIS3D address: %x\r\n",twi_master_getchar(0x0F));
twi_master_putchar(0x23, 0b000100000);
printf("\r\nControl 4 register 0x23: %x", twi_master_getchar(0x23));
printf("\r\nStatus register %x", twi_master_getchar(0x27));
twi_master_putchar(0x20, 0x77);
DDRB=0xFF;
PORTB=0xFD;
SREG=0x80; //sei();
while(1)
{
process();
}
}
void process(void){
x_l = twi_master_getchar(0x28);
x_h = twi_master_getchar(0x29);
y_l = twi_master_getchar(0x2a);
y_h = twi_master_getchar(0x2b);
z_l = twi_master_getchar(0x2c);
z_h = twi_master_getchar(0x2d);
xvalue = (short int)(x_l+(x_h<<8));
yvalue = (short int)(y_l+(y_h<<8));
zvalue = (short int)(z_l+(z_h<<8));
printf("\r\nx_val: %ldg", x_val);
printf("\r\ny_val: %ldg", y_val);
printf("\r\nz_val: %ldg", z_val);
}
我将 CTRL_REG4 写为 0x10(4g),但是当我读取它们时,我得到了 0x20(8g)。这看起来有点奇怪。
最佳答案
不计算 2s 补码。这会导致结果变为负数。
相反,数据表告诉我们结果已经是一个带符号的值。也就是说,0不是最低值;它位于刻度的中间。 (0xffff 只是比零小一点,不是最高值。)
此外,结果始终是 16 位,但结果并不意味着那么准确。您可以设置一个控制寄存器值来生成更准确的值,但会消耗电流,但仍然不能保证精确到最后一位。
关于avr - 如何从 LIS3DH 传感器计算 g 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22496993/