MMA7455加速度传感器測量角度

使用加速度传感器应该注意几点:

第一:确保你的IIC是正确的;

第二,首先必须校准系统,校准方法,例如以下:将7455平放,保证z轴向下,这是假设系统是Ok的,那么x轴输出为0,y轴输出为0,z轴输出为63左右,假设不为以上參数,应该做例如以下调整:測量值比实际值小的情况下,往校准寄存器里面写入一个2*误差值;假设測量值假设大于实际值,应该写入一个值为相应误差的负值的ASCII码,比方假设測出值为70,那么应该写入-16,即(0xf0);

下面就是我调试mma7455的代码:

#include "msp430f5438.h"
#include "public.h"
#include "simulate_iic.h"
#include <stdbool.h>

#include "init.h"

#include "mma7455.h"
#include "lcd1602.h"
#include<math.h>
typedef unsigned int uint;
typedef unsigned char uchar;
char mma7455write_byte(unsigned char reg,unsigned char data)//寄存器地址,数据
{
  char flag;
 // WDTCTL = WDTPW + WDTHOLD; // 禁止看门狗定时器
  iic_start();//起始信号
  write_byte(0x3a);//数据发送
  flag=get_ack();//接受应答位,即数据成功发送后,接受到的应答
  if(flag)
  {
    flag=0;
    write_byte(reg);//数据发送
  }

  flag=get_ack();//接受应答位,即数据成功发送后,接受到的应答
  if(flag)
  {
    flag=0;
    write_byte(data);
  }

  flag=get_ack();
  if(flag)
  {
    flag=0;
    iic_stop();
    return 0;
  }

  return 1;

}

 char readMMA7455Byte(unsigned char regadd)
{
  char flag;
  char z;
  z=0;
  iic_start();
  write_byte(0x3a);//先写入器件地址
  flag=get_ack();
  if(flag)
  {
    write_byte(regadd);//有应答之后再写寄存器地址
    flag=0;
  }

  flag=get_ack();
  if(flag)
  {
    flag=0;
    iic_start();//继续等应答之后写入该地址和读命令,但是认为这不必要这么做
    write_byte(0x3b);//但是时间的原因,仅仅有找着实例的操作先写着,以后再改动
  }

  flag=get_ack();
  if(flag)
  {
    flag=0;
    z=read_byte();
  }

  send_ack();

  iic_stop();

  return z;

}
// X:255 1.65V -1.00g
// 012345678901234567
void Cvt_Str(char zifu[], char V1)
{
  char characters[17]="0123456789ABCDEF";
   char tv=0;

  tv=V1/100;
  zifu[2] = characters[tv];
  tv=(V1%100)/10;
  zifu[3] = characters[tv];
  tv=V1%10;
  zifu[4] = characters[tv];

  zifu[5] = ‘ ‘;

  zifu[6] = ‘0‘;
  zifu[7] = ‘x‘;
  tv=V1/16;
  zifu[8] = characters[tv];
  tv=V1%16;
  zifu[9] = characters[tv];

  zifu[10] = ‘ ‘;

  if(V1>127)
  {
    zifu[11] = ‘-‘;
    tv=255-V1;
    zifu[12] = characters[tv/63];
    zifu[13] = ‘.‘;
    zifu[14] = characters[((tv*100/63)%100)/10];
    zifu[15] = characters[(tv*100/63)%10];
  }
  else
  {
    zifu[11] = ‘+‘;
    tv=V1;
    zifu[12] = characters[tv/63];
    zifu[13] = ‘.‘;
    zifu[14] = characters[((tv*100/63)%100)/10];
    zifu[15] = characters[(tv*100/63)%10];
  }
  zifu[16] = ‘g‘;
}
uint	arc_tan2(uchar Ax,uchar Ay)
{
	int	diat_t;
	float		m;
	m=atan2(Ay,Ax);
	diat_t=(int)(m*1800/3.14);
	return	diat_t;
}
uint measure()
{
	uchar x;
	uchar y;
	uint x1,y1;
	uchar	xsign,ysign;
	uint angle;
	angle=0;
		x=readMMA7455Byte(0x06);
		y=readMMA7455Byte(0x07);
		x=x+0x2C;
		y=y+0x25;
		if(x>127)
		{
			x=255-x;
			x1=((float)x*100)/63.0;
			xsign=0x2b;
		}
		else
		{
			x1=((float)x*100)/63.0;
			xsign=0x2d;
		}
		if(y>127)
		{
			y=255-y;
			y1=((float)y*100)/63.0;
			ysign=0x2b;
		}
		else
		{
			y1=((float)y*100)/63.0;
			ysign=0x2d;
		}
	angle = arc_tan2(x1,y1);
	/*if(xsign==0x2b&&ysign==0x2b)
	{
		angle = arc_tan2(x1,y1);
	}
	else	if(xsign==0x2b&&ysign==0x2d)
	{
		angle = 900+arc_tan2(y1,x1);;
	}
	else	if(xsign==0x2d&&ysign==0x2d)
	{
		angle = 2700-angle;
	}
	else	if(xsign==0x2d&&ysign==0x2b)
	{
		angle = 2700+angle;
	}*/
	return angle;
}
void main()
{
	  char txtbuf[16]="X:255 -1.00g";
	  //uchar x,y,x2,y2;
	  //volatile uint x1,y1;
	 // uchar j,k;
	  clk_init();
	  lcd1602_pin_init();
	  lcd_init();
	  delay_ms(50);
	  while(mma7455write_byte(0x16,0x005));
	  while(mma7455write_byte(0x10,0xff));//校正X值
	  while(mma7455write_byte(0x11,0x07));
	  while(mma7455write_byte(0x12,0x18));//校正Y值
	  while(mma7455write_byte(0x14,0xDC));//校正Z值
	  while(mma7455write_byte(0x15,0xFF));
	  while(1)
	  {
		/*lcd_pos(0,0);
		  lcd_wdat(‘a‘);
		  lcd_wdat(‘n‘);
		  lcd_wdat(‘g‘);
		  lcd_wdat(‘l‘);
		  lcd_wdat(‘e‘);
		  lcd_wdat(‘:‘);

		  lcd_printf(measure());//x
		  //delay_ms(1000);
		  //lcd_wcmd(0x01);	*/		//显示清屏

			/*x=readMMA7455Byte(0x06);
			y=readMMA7455Byte(0x07);
			x2=x+0x2C;
			y2=y+0x25;
			x=x+0x2C;
			y=y+0x25;
			if(x>0x7f)
			{
				x=255-x;
				j=1;
				x1=((float)x*100)/63.0;
			}
			else
			{
				x1=((float)x*100)/63.0;
				j=0;
			}
			if(y>0x7f)
			{
				y=255-y;
				y1=((float)y*100)/63.0;
				k=1;
			}
			else
			{
				y1=((float)y*100)/63.0;
				k=0;
			}
			lcd_pos(0,0);
			if(j==1) lcd_wdat(‘-‘);
			else lcd_wdat(‘+‘);
			lcd_char(x1);
			lcd_pos(0,1);
			if(k==1) lcd_wdat(‘-‘);
			else lcd_wdat(‘+‘);
			lcd_char(y1);
			delay_ms(1000);
			lcd_wcmd(0x01);

			  lcd_pos(0,0);
			  Cvt_Str(txtbuf,x2);
			  txtbuf[0]=‘X‘;
			  lcd_string(txtbuf);
			  lcd_pos(0,1);
			  Cvt_Str(txtbuf,y2);
			  txtbuf[0]=‘Y‘;
			  lcd_string(txtbuf);
			  delay_ms(1000);
			  lcd_wcmd(0x01);*/			//显示清屏
			  lcd_pos(0,0);
			  Cvt_Str(txtbuf,readMMA7455Byte(0x08));
			  txtbuf[0]=‘Z‘;
			  lcd_string(txtbuf);
			  lcd_pos(0,1);
			  lcd_printf(arc_tan2(readMMA7455Byte(0x08),readMMA7455Byte(0x06)));
			  delay_ms(1000);
			  lcd_wcmd(0x01);			//显示清屏

			  lcd_pos(0,1);
			  Cvt_Str(txtbuf,readMMA7455Byte(0x06));
			  txtbuf[0]=‘X‘;
			  lcd_string(txtbuf);
			  lcd_pos(0,0);
			  Cvt_Str(txtbuf,readMMA7455Byte(0x07));
			  txtbuf[0]=‘Y‘;
			  lcd_string(txtbuf);
			  delay_ms(1000);
			  lcd_wcmd(0x01);			//显示清屏
	  }
}
时间: 2024-12-13 03:54:07

MMA7455加速度传感器測量角度的相关文章

Atmega16驱动三轴加速度传感器MMA7455

最近做一个设计G-Sense的设备,需要一个三轴加速度传感器,最终选择飞思卡尔的MMA7455,因为看起来似乎比博士的三轴加速度芯片简单一些,哈哈.原本是准备应用在ARM上的,首先在比较熟悉的AVR单片机的环境下做个测试. 来个MMA7455模块的近照: 考虑到7455工作在3.3V,所以用宽电压工作的Atmega16L,这样就不存在电压冲突的问题.电路图参考7455的Datasheet: 在这里,中断INT1和INT2我都没有用,ACC_CS接3.3采用I2C模式,IADDR0接3.3,设置7

三轴加速度传感器原理及应用

三轴加速度传感器原理 目前的加速度传感器有多种实现方式,主要可分为压电式.电容式及热感应式三种,这三种技术各有其优缺点.以电容式3轴加速度计的技术原理为例.电容式加速度计能够感测不同方向的加速度或振动等运动状况.其主要为利用硅的机械性质设计出的可移动机构:由于加速度使得机械悬臂与两个电极之间的距离发生变化,从而改变了两个电容的参数.通过集成的开关电容放大电路量测电容参数的变化,形成了与加速度成正比的电压输出.因此3轴加速度传感器必然包含一个单纯的机械性MEMS传感器和一枚ASIC接口芯片两部分,

android 三轴加速度传感器【转】

一.手机中常用的传感器 在Android2.3 gingerbread系统中,google提供了11种传感器供应用层使用,具体如下:(Sensor类) #define SENSOR_TYPE_ACCELEROMETER 1 //加速度#define SENSOR_TYPE_MAGNETIC_FIELD 2 //磁力#define SENSOR_TYPE_ORIENTATION 3 //方向#define SENSOR_TYPE_GYROSCOPE 4 //陀螺仪#define SENSOR_TY

android 加速度传感器妙用与自定义View

本节的实例是一个倾斜角度测量应用,它可以准确的测量出你手机与水平面的倾斜角度,使用的是android传感器里面的加速传感器.巧妙的运用了加速度传感器各个值所代表的物理意义,加上一个很简单的算法,就能测出倾斜角度. 角度值会随着手机的倾斜而准确显示,效果如图: 废话不多说直接上代码,上面有清楚的说明 package sina.CreAmazing.angle_view; import android.app.Activity; import android.content.Context; imp

OneNET麒麟座应用开发之五:获取加速度传感器ADXL345数据

由于数据采集站基本都安装在野外或者楼顶,安装位置以及震动对检测数据的准确性有一定影响.所以想要有一个位置状态数据,正好发现麒麟作上有ADXL345,这样一个数字输出的加速度传感器.如图中红框所示: 1.ADXL345概述 ADXL345是ADI公司推出的基于iMEMS技术的3轴.数字输出加速度传感器.该加速度传感器的特点如下: 分辨率高.最高13位分辨率. 量程可变.具有+/-2g,+/-4g,+/-8g,+/-16g可变的测量范围. 灵敏度高.最高达3.9mg/LSB,能测量不到1.0°的倾斜

工程师向你展示手机加速度传感器如何工作,有影片辅助说明

作者: BIN CHEN  2012 年 5 月 23 日, 晚上 10:3412 一些手机玩家和发烧友对一些手机的元器件感兴趣,甚至想知道它们是如何工作的.而现在,无论是手机和平板电脑,基本上都内置了加速传感器,用来识别设备的转动方向.来自 Illinois 大学的一位工程师 Bill Hammack 向我们介绍了这种加速传感器是如何工作的,并且不是枯燥的说教,而是有动画影片来辅助说明. 影片中 Bill Hammack 用到了 Android 和 iPhone 手机来演示,不过还是以 iPh

加速度传感器的原理和应用-手机翻转、失重检测、运动检测、位置识别

本文介绍可穿戴设备加速度传感器-Lis3dh的特性原理和应用场景.意法半导体研发的Lis3dh广泛应用在智能手环.智能计步鞋等智能穿戴产品中. Lis3dh有两种工作方式,一种是其内置了多种算法来处理常见的应用场景(如静止检测.运动检测.屏幕翻转.失重.位置识别.单击和双击等等),用户只需简单配置算法对应的寄存器即可开始检测,一旦检测到目标事件,Lis3dh的外围引脚INT1会产生中断.另一种是支持用户通过SPI/I2C来读取底层加速度数据,并自行通过软件算法来做进一步复杂的处理,如计步等等.

Android加速度传感器的使用:摇一摇功能的实现

一.原理介绍: Android手机中摇一摇的功能已经很常见了,最近接触到了这个功能,原理很简单:使用加速度传感器,在晃动手机时,监听加速度在各个方向的变化,当加速度值超过设定的灵敏度时,则触发摇一摇功能. 二.使用到的类: SensorManager SensorEventListener 三.功能实现: 1.摇一摇功能:我将摇一摇功能封装成了一个类ShakeUtils,在使用时按照注释中的说明使用即可,ShakeUtils.java如下(差的包请CTRL+SHIFT+O导入): /** * 摇

Android 使用加速度传感器实现摇一摇功能及优化

如有转载,请声明出处: 时之沙: http://blog.csdn.net/t12x3456 目前很多应用已经实现了摇一摇功能,这里通过讲解该功能的原理及实现回顾一下加速度传感器的使用: 1.首先获得传感器管理器的实例 sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 2.通过传感器管理器获得加速传感器 accelerateSensor = getSensorManager(cont