一、BMA220模块参数
- BMA220作为BOSCH博世生产的加速度传感器,具有x,y,z三轴加速度采样的功能。可以通过IIC和SPI与 MCU连接。其加速度范围可调,分别为±2g,4g,8g,16g四档加速度范围。BMA220的灵敏度为16LSB/g,8LSB/g,4LSB/g,2LSB/g四档可调,带宽为32Hz~1kHz。标准的BMA220芯片的工作电压为1.62V~3.6V(我这里以DFRobot的BMA220模块为例本身具有稳压芯片,可以用5V作为电压)。
- BMA220的具体芯片数据手册地址:BMA220_data_sheet-102_rev.1.10_13April2011.doc (dfrobot.com.cn)
DF出品的BMA220模块的使用手册地址:Triple_Axis_Accelerometer_BMA220_Tiny__SKU_SEN0168-DFRobot
二、对官方数据中寄存器配置解释
以DFRobot给出的英文文档为例
BMA220的模块配置寄存器如下:(紫色部分可读写,黄色部分只写,绿色部分只读)
寄存器的配置——通过寄存器的配置,BMA220提供了如下一些功能
1.实现低功耗模式(可选配置)
通过配置寄存器0x0F(SPI)/0x1E(IIC)可以实现BMA220的低功耗,由寄存器图可知,bit6的sleep_en用来使能中断睡眠模式,bit3~bit5的sleep_duration可以配置具体的BMA220的低功耗睡眠时间。
(同时,官方文档中提出,通过之后的带宽和采样频率的设置是实现低功耗的主导。)
同时也可以可以通过激活或者关闭x,y,z中的任一一个或多个通道,来实现低功耗:
通过配置寄存器0x0F(SPI)/0x1E(IIC),将bit0~bit2的三个位根据需要至为0,可以关闭通道。
2.实现加速度范围和灵敏度的配置(必要配置)
通过配置寄存器0x11(SPI)/0x22(IIC),可以配置BMA220的加速度范围和灵敏度。由寄存器图可知,bi0~bit1的range位可以用来配置其加速度范围。具体如图:
3.实现滤波器和带宽的配置(必要配置)
通过配置寄存器0x10(SPI)/0x20(IIC)可以实现这一功能。由寄存器图对应地址的bit0~bit3的filter_config来配置。配置具体如图:
同时官方文档指出,BMA220能够自动调整采样的频率。
4.实现加速度数据的读出(当然必要)
通过读取寄存器的0x02,0x04,0x06(IIC),可以读取加速度的原始数据,官方文档指出,这一数据为2的补码,在实际的代码中,需要对原始数据的处理。
官方给出了BMA220的中断功能,以实现内部和外部的中断,具体参考官方文档的第五章。
三、BAM220的代码实现
根据上文中的寄存器配置,我们已经知道了关于BAM220的初始化必须的一些配置,包括加速度范围灵敏度和滤波器带宽的配置两方面,下面以DFrobot给出的程序作为参考
Arduino端代码实现(摘自DFrobot的示例解释):
#include <Wire.h>
byte Version[3];
int8_t x_data;
int8_t y_data;
int8_t z_data;
byte range=0x00;
float divi=16;
float x,y,z;
void setup()
{
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(0x0A); // BMA220的iic地址
// range settings
Wire.write(0x22); //加速度范围配置寄存器地址
Wire.write(range); //can be set at"0x00""0x01""0x02""0x03", 0x00 2g; 0x01 4g; 0x03 8g; 0x04 16g
// low pass filter
Wire.write(0x20); //过滤器和带宽配置寄存器地址
Wire.write(0x05); //can be set at"0x05""0x04"......"0x01""0x00",可参考手册
Wire.endTransmission();
}
void AccelerometerInit()
{
Wire.beginTransmission(0x0A); // BMA220iic地址
// 重设要读取的寄存器地址
Wire.write(0x04); // Y data
Wire.endTransmission();
Wire.requestFrom(0x0A,1); // request 6 bytes from slave device
while(Wire.available()) // slave may send less than requested
{
Version[0] = Wire.read(); // 接收一字节
}
x_data=(int8_t)Version[0]>>2; //加速度数据为2的补码
Wire.beginTransmission(0x0A); // BMA220iic地址
Wire.write(0x06); // Y data
Wire.endTransmission();
Wire.requestFrom(0x0A,1);
while(Wire.available())
{
Version[1] = Wire.read();
}
y_data=(int8_t)Version[1]>>2;
Wire.beginTransmission(0x0A);
Wire.write(0x08); // Y data
Wire.endTransmission();
Wire.requestFrom(0x0A,1);
while(Wire.available())
{
Version[2] = Wire.read();
}
z_data=(int8_t)Version[2]>>2;
x=(float)x_data/divi;
y=(float)y_data/divi;
z=(float)z_data/divi;
Serial.print("X=");
Serial.print(x); // print the character
Serial.print(" ");
Serial.print("Y=");
Serial.print(y); // print the character
Serial.print(" ");
Serial.print("Z="); // print the character
Serial.println(z);
}
void loop()
{
switch(range) //通过更改range值来更改分辨率
{
case 0x00:divi=16; break;
case 0x01:divi=8; break;
case 0x02:divi=4; break;
case 0x03:divi=2; break;
default: Serial.println("range setting is Wrong,range:from 0to 3.Please check!");while(1);
}
AccelerometerInit();
delay(100);
}
树莓派端的python代码实现:
#coding:utf-8
import smbus
import math
import time
bus = smbus.SMBus(1)
address = 0x0A
def bma220_init():
bus.write_byte_data(address,0x22,0)
bus.write_byte_data(address,0x00,0)
bus.write_byte_data(address,0x20,0)
bus.write_byte_data(address,0x05,0)
# 读取一个字长度的数据
def readWord(adr):
val = bus.read_byte_data(address,adr)
return val
def getx():
return (readWord(0x04)>>2)/16
def gety():
return (readWord(0x06)>>2)/16
def getz():
return (readWord(0x08)>>2)/16
bma220_init()
while True:
time.sleep(0.5)
print("X轴数加速度据:",getx())
print("Y轴加速度数据:",gety())
print("Z轴加速度数据:",getz())
鸣谢:本博客中部分的资料和代码来源,本人只做补充不做修改!Triple_Axis_Accelerometer_BMA220_Tiny__SKU_SEN0168-DFRobot