MMA7260是飞思卡尔半导体公司生产的三轴加速度传感器,下面是网友的一段原话….
加速度传感器测的是什么?
我觉得很多时候大家都被它的名字给误导了 我觉得准确的来说它测的不是加速度 至少对于mma7260这类的片子 它检测的是它受到的惯性力(包括重力!重力也是惯性力)。那又有人要问了 F=ma 惯性力不就是加速度么? 差矣 加速度传感器实际上是用MEMS技术检测惯性力造成的微小形变 注意 检测的是微小形变 所以 你把加速度传感器 水平静止放在桌子上 它的Z轴输出的是1g的加速度 因为它Z轴方向被重力向下拉出了一个形变 可是你绝对不会认为它在以1g的加速度往下落吧 你如果让它做自由落体 它的Z轴输出应该是0 给个形象的说法 可以把它看成是一块弹弹胶 它检测的就是自己在三个方向被外力作用造成的形变。从刚才的分析可以发现 重力这个东西实际是个很恶心的东西 它能隔空打牛,在不产生加速度的情况下对加速度传感器造成形变,在产生加速度的时候不造成形变,而其他力都做不到。可惜的是,加速度传感器不会区分重力加速度与外力加速度。
所以,当系统在三维空间做变速运动时,它的输出就不正确了 或者说 它的输出不能表明物体的姿态和运动状态 举个例子 当一个物体在空间做自由落体时 在X轴受到一个外力作用 产生g的加速度 这时候x y z 轴的输出分别是 g,0,0 如果这个物体被x轴朝下静止放在水平面上 它x y z 轴的输出也分别是 g,0,0 所以说 只靠加速度传感器 来估计自己的姿态 是 很危险而不可取的
且不管它是怎么制造的,我只知道它的三个轴在不同的加速度环境下会给出不同的电压信号,这个电压信号即是当前状态不用对它积分(有别与陀螺仪)知道这个就可以侧角度了.
由图可知可知三个轴的正负方向,这里参考的芯片本身,而我们在使用时一般使用的是该模块的一个扩展板,所以要看清扩展板上芯片的方向. 好了,明确这一点后我们就需要找一个扩展板来测角度了,市面上的扩展板接口基本相同,这里以实验室现有的扩展模块为例简要说明。
1
板子的各个引脚定义已经在图中标上了,
3.3V可以不接,因为模块上有电源管理芯片,当右边的接上5V电后,板子上会产生3.3V的电压。
Enable端接5V就行了。这个是芯片睡眠模式控制,我们上电就让它工作,手机为了功耗才考虑它,我们不管它。
Z、Y、X是芯片给出的三轴模拟电压值,这个值最大也不会大于3.3V,所以对于A/D采样电路的参考电压最好选3.3V,例如同样采用10位的A/D来转换该模拟值,对于3.3V的来说其数字量分布在0—1024,而对于5V的来说最大也不会超过675,所以其精度就不如3.3V的高。还有该传感器灵敏度很高,有一点点震动都会引起数值的变化,这种变化时大时小,在软件设计上不好滤波,所以在使用时将该模拟电压加一个电压跟随器比较好。 g-select1/g-select2就是芯片的灵敏度量程选择,
这里选择的1.5g 800mv/g 的灵敏度,假设我们测量X平面和Z平面的夹角。
如图重力g会在x轴和z轴上有个分量,通过芯片测回这两个分量,就可以知道α角了, 还有一点要注意,由芯片的手册可知各轴在不受外力的情况下其输出电压是1.65V 所以测回值要减去1.65V,
2
/************************************************************* function: MMA7260角度测量 version: V1.0
date: 2011-8-27
note: 三轴加速度测量可以测量x面、y面以及整个平面与水平面
的夹角, 这里简化使用,仅测得x面与水平面的夹角(有正负)-90~~+90 返回一个三位数个位是小数位。 0通道:X 2通道:Z
**************************************************************/ int angle_measure(void) {
float angle_temp;
X_g =(float)AD0[7]*4.85/1024; Z_g =(float)AD2[7]*4.85/1024; X_g = (X_g-1.65)*1.25; Z_g = (Z_g-1.65)*1.25;
angle_temp = atan(X_g / Z_g);
angle_x_hd = angle_temp ; //保存摆面的 弧度 angle_temp = angle_temp * 60.95; // 57.2957
if(angle_temp>=90) //最后的弧度值转化中含有修正因子 会使所测得角度大于90度 angle_temp = 90; else if(angle_temp<=-90) angle_temp = -90;
return (int)(angle_temp*10); }
上面的AD0[7]是中值滤波后X轴的采样值 AD2[7]是Z轴 1.25 = 1/0.8 片内选用的是10位A/D. 板上实测参考电压小于5.0V 这里用4.85V
这里正角度和负角度乘的修正因子是同一个含在60.95中 不同的模块最后的修正可能不一样,有时正、负角度需要分别修正。
下面的AD_check(void) 是AD采样函数,放在中断里周期采样就可以了。 AD_message(void) 是中值滤波
2011-12-24 郭震
3
/************************************************ function: AD采样 version: V1.0 date: 2011-8-27
note: 每一行代表一个传感器 每一次采样8个值 ADvalue[][]里的值是原始值
**************************************************/ void AD_check(void) {
int AD_0,AD_1,AD_2,AD_3; //暂存读回的值
byte i; AD_0 = 0; AD_1 = 0; AD_2 = 0; AD_3 = 0; for(i=0;i<8;i++)
{ //取五次传感器值 ATD0CTL5=0x30; //重新开始 while(!ATD0STAT2_CCF0 && !ATD0STAT2_CCF1 &&!ATD0STAT2_CCF2 && !ATD0STAT2_CCF3) //0--3
{ //转换完成 CCF【5:0】置位 AD_0 = 4*ATD0DR0H+ATD0DR0L/64; AD_1 = 4*ATD0DR1H+ATD0DR1L/64; AD_2 = 4*ATD0DR2H+ATD0DR2L/64; AD_3 = 4*ATD0DR3H+ATD0DR3L/64; }
ADvalue[0][i] = AD_0; //将读回的值入库 ADvalue[1][i] = AD_1; ADvalue[2][i] = AD_2; ADvalue[3][i] = AD_3; } }
/************************************************ function: AD采样的值初处理 version: V1.0 date: 2011-8-27
note: ADvalue[3][8]的每一行代表每个传感器本次采样的
4
8个值 对其减去最大的和最小的然后取中间的六个 值的均值作为本次的采样值 并存入ADn[]中 **************************************************/ void AD_message(void) {
int i = 0, j = 0,lg = 0,sm = 0,max = 0,min = 1300,sum = 0; for(i=0;i<4;i++) {
max=0; min=1300;
for(j=0;j<8;j++)
{ //第一大/小 if(ADvalue[i][j]>=max) {
max=ADvalue[i][j]; lg=j; }
if(ADvalue[i][j]<=min) {
min=ADvalue[i][j]; sm=j; }
sum=0; }
for(j=0;j<8;j++) {
sum += ADvalue[i][j]; }
sum=sum-ADvalue[i][lg]-ADvalue[i][sm]; //减去本行的最大值和最小值 switch(i) {
case 0: {
for(j=0;j<7;j++) {
AD0[j] = AD0[j+1]; //0---3的值被替换 }
AD0[7] = sum/6; break; }
case 1: {
for(j=0;j<7;j++) {
AD1[j] = AD1[j+1]; //0---3的值被替换
5
}
AD1[7] = sum/6; break; }
case 2: {
for(j=0;j<7;j++) {
AD2[j] = AD2[j+1]; //0---3的值被替换 }
AD2[7] = sum/6; break; }
case 3: {
for(j=0;j<7;j++) {
AD3[j] = AD3[j+1]; }
AD3[7] = sum/6; break; } } } }
//0---3的值被替换 6
因篇幅问题不能全部显示,请点此查看更多更全内容