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); //显示清屏 } }