基于msp430f5529的MPU6050测角度 2.docx

上传人:b****5 文档编号:7759533 上传时间:2023-01-26 格式:DOCX 页数:18 大小:18.61KB
下载 相关 举报
基于msp430f5529的MPU6050测角度 2.docx_第1页
第1页 / 共18页
基于msp430f5529的MPU6050测角度 2.docx_第2页
第2页 / 共18页
基于msp430f5529的MPU6050测角度 2.docx_第3页
第3页 / 共18页
基于msp430f5529的MPU6050测角度 2.docx_第4页
第4页 / 共18页
基于msp430f5529的MPU6050测角度 2.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

基于msp430f5529的MPU6050测角度 2.docx

《基于msp430f5529的MPU6050测角度 2.docx》由会员分享,可在线阅读,更多相关《基于msp430f5529的MPU6050测角度 2.docx(18页珍藏版)》请在冰豆网上搜索。

基于msp430f5529的MPU6050测角度 2.docx

基于msp430f5529的MPU6050测角度2

  这个程序完成的功能为:

使用msp430f5529在12864上串行显示GY-521,MPU6050所测量的角度。

  在IAR亲测成功。

  注意:

我只给出了C文件,h文件自己去建立就好了。

  ////*******主函数******///

  #include

  #include"stdio.h"

  #include"math.h"

  #include"6050.h"

  #include"LCD12864.h"

  voidDelays(uchari)

  {

  unsignedintj;

  while(i--)

  {

  j=2000;

  while(j--);

  }

  }

  voidmain(void)

  {

  WDTCTL=WDTPW+WDTHOLD;//关闭看门狗

  charsum1[10],sum2[10],sum3[10];//串口发送缓存

  floata_x,a_y,a_z;

  int_port();//管脚初始化

  lcdinit();

  InitMPU6050();//初始化模块

  display(1,1,"角度X:

");

  display(2,1,"角度Y:

");

  display(3,1,"角度Z:

");

  while

(1)

  {

  //Delays

(2);

  a_x=mpu6050_Angle

(2);

  a_y=mpu6050_Angle

(1);

  a_z=mpu6050_Angle(0);

  sprintf(sum1,"%.2f",a_x);//将测量倾角值转换为字符串

  sprintf(sum2,"%.2f",a_y);

  sprintf(sum3,"%.2f",a_z);

  display(1,4,sum1);

  display(2,4,sum2);

  display(3,4,sum3);

  }

  }

  ////************6050IIC******////

  /*

  ***************************************************************************

  **文件名:

Mpu-6050.c

  **编写者:

黄建军

  **描述:

三轴加速度,三轴陀螺仪传感器Mpu-6050的驱动程序,此处用于149系列。

  **注意-此处MCLK:

8Mhz

  **版本:

2013-6V1.0

  ****************************************************************************

  */

  #include"msp430f5529.h"

  //#include"mytype.h"

  #include"6050.h"

  staticvoidI2C_Start();

  staticvoidI2C_Stop();

  staticvoidI2C_SendACK(ucharack);

  staticucharI2C_RecvACK();

  staticvoidI2C_SendByte(uchardat);

  staticucharI2C_RecvACK();

  shortaccData[3]={0};

  //**************************************

  //I2C起始信号

  //**************************************

  voidI2C_Start()

  {

  MPU_SCL_OUT();//SCL设置为输出

  MPU_SDA_OUT();//SDA设置为输出

  MPU_SDA_H();//拉高数据线

  MPU_SCL_H();//拉高时钟线

  DELAY_US(5);//延时

  MPU_SDA_L();//产生下降沿

  DELAY_US(5);//延时

  MPU_SCL_L();//拉低时钟线

  }

  //**************************************

  //I2C停止信号

  //**************************************

  voidI2C_Stop()

  {

  MPU_SCL_OUT();//SCL设置为输出

  MPU_SDA_OUT();//SDA设置为输出

  MPU_SDA_L();//拉低数据线

  MPU_SCL_H();//拉高时钟线

  DELAY_US(5);//延时

  MPU_SDA_H();//产生上升沿

  DELAY_US(5);//延时

  }

  //**************************************

  //I2C发送应答信号

  //入口参数:

ack(0:

ACK1:

NAK)

  //**************************************

  voidI2C_SendACK(ucharack)

  {

  MPU_SCL_OUT();//SCL设置为输出

  MPU_SDA_OUT();//SDA设置为输出

  if(ack)

  MPU_SDA_H();

  else

  MPU_SDA_L();

  //SDA=ack;//写应答信号

  MPU_SCL_H();//拉高时钟线

  DELAY_US(5);//延时

  MPU_SCL_L();//拉低时钟线

  DELAY_US(5);//延时

  }

  //**************************************

  //I2C接收应答信号

  //**************************************

  ucharI2C_RecvACK()

  {

  ucharcy;

  MPU_SCL_OUT();//SCL设置为输出

  MPU_SDA_IN();//SDA设置为输入

  MPU_SCL_H();//拉高时钟线

  DELAY_US(5);//延时

  if(MPU_SDA_DAT())

  {

  cy=1;

  }

  else

  {

  cy=0;

  }

  //cy=SDA;//读应答信号

  MPU_SCL_L();//拉低时钟线

  DELAY_US(5);//延时

  MPU_SDA_OUT();//SDA设置为输出

  returncy;

  }

  //**************************************

  //向I2C总线发送一个字节数据

  //**************************************

  voidI2C_SendByte(uchardat)

  {

  uchari;

  MPU_SCL_OUT();//SCL设置为输出

  MPU_SDA_OUT();//SDA设置为输出

  for(i=0;i<8;i++)//8位计数器

  {

  if((dat<

  {

  MPU_SDA_H();

  }

  else

  {

  MPU_SDA_L();

  }

  //SDA=cy;//送数据口

  MPU_SCL_H();//拉高时钟线

  DELAY_US(5);//延时

  MPU_SCL_L();//拉低时钟线

  DELAY_US(5);//延时

  }

  I2C_RecvACK();

  }

  //**************************************

  //从I2C总线接收一个字节数据

  //**************************************

  ucharI2C_RecvByte()

  {

  uchari;

  uchardat=0,cy;

  MPU_SCL_OUT();//SCL设置为输出

  MPU_SDA_OUT();//SDA设置为输出

  MPU_SDA_H();//使能内部上拉,准备读取数据,

  MPU_SDA_IN();//SDA设置为输入,准备向主机输入数据

  for(i=0;i<8;i++)//8位计数器

  {

  dat<<=1;

  MPU_SCL_H();//拉高时钟线

  DELAY_US(5);//延时

  if(MPU_SDA_DAT())

  {

  cy=1;

  }

  else

  {

  cy=0;

  }

  dat|=cy;//读数据

  MPU_SCL_L();//拉低时钟线

  DELAY_US(5);//延时

  }

  MPU_SDA_OUT();

  returndat;

  }

  //**************************************

  //向I2C设备写入一个字节数据

  //**************************************

  voidByteWrite6050(ucharREG_Address,ucharREG_data)

  {

  I2C_Start();//起始信号

  I2C_SendByte(SlaveAddress);//发送设备地址+写信号

  I2C_SendByte(REG_Address);//内部寄存器地址,

  I2C_SendByte(REG_data);//内部寄存器数据,

  I2C_Stop();//发送停止信号

  }

  //**************************************

  //从I2C设备读取一个字节数据

  //**************************************

  ucharByteRead6050(ucharREG_Address)

  {

  ucharREG_data;

  I2C_Start();//起始信号

  I2C_SendByte(SlaveAddress);//发送设备地址+写信号

  I2C_SendByte(REG_Address);//发送存储单元地址,从0开始

  I2C_Start();//起始信号

  I2C_SendByte(SlaveAddress+1);//发送设备地址+读信号

  REG_data=I2C_RecvByte();//读出寄存器数据

  I2C_SendACK

(1);//接收应答信号

  I2C_Stop();//停止信号

  returnREG_data;

  }

  //**************************************

  //合成数据

  //**************************************

  intGet6050Data(ucharREG_Address)

  {

  charH,L;

  H=ByteRead6050(REG_Address);

  L=ByteRead6050(REG_Address+1);

  return(H<<8)+L;//合成数据

  }

  //**************************************

  //初始化MPU6050

  //**************************************

  voidInitMPU6050()

  {

  ByteWrite6050(PWR_MGMT_1,0x00);//解除休眠状态

  ByteWrite6050(SMPLRT_DIV,0x07);//陀螺仪采样率设置(125HZ)

  ByteWrite6050(CONFIG,0x06);//低通滤波器频率设置(5HZ)

  ByteWrite6050(GYRO_CONFIG,0x18);//陀螺仪自检及检测范围设置(不自检,16.4LSB/DBS/S)

  ByteWrite6050(ACCEL_CONFIG,0x01);//加速计自检、测量范围及高通滤波频率(不自检,2G(16384LSB/G),5Hz)

  }

  /*

  **********************************************

  **函数名:

floatMpu6050AccelAngle(int8dir)

  **函数功能:

输出加速度传感器测量的倾角值

  **范围为2g时,换算关系:

16384LSB/g

  **角度较小时,x=sinx得到角度(弧度),deg=rad*180/3.14

  **因为x>=sinx,故乘以1.2适当放大

  **返回参数:

测量的倾角值

  **传入参数:

dir-需要测量的方向

  **ACCEL_XOUT-X方向

  **ACCEL_YOUT-Y方向

  **ACCEL_ZOUT-Z方向

  **********************************************

  */

  floatMpu6050AccelAngle(uchardir)

  {

  floataccel_agle;//测量的倾角值

  floatresult;//测量值缓存变量

  result=(float)Get6050Data(dir);//测量当前方向的加速度值,转换为浮点数

  accel_agle=(result+MPU6050_ZERO_ACCELL);//去除零点偏移,计算得到角度(弧度)

  //accel_agle=accel_agle*1.2*180/3.14;//弧度转换为度

  returnaccel_agle;//返回测量值

  }

  /*

  **********************************************

  **函数名:

floatMpu6050GyroAngle(int8dir)

  **函数功能:

输出陀螺仪测量的倾角加速度

  **范围为2000deg/s时,换算关系:

16.4LSB/(deg/s)

  **返回参数:

测量的倾角加速度值

  **传入参数:

dir-需要测量的方向

  **GYRO_XOUT-X轴方向

  **GYRO_YOUT-Y轴方向

  **GYRO_ZOUT-Z轴方向

  **********************************************

  */

  floatMpu6050GyroAngle(uchardir)

  {

  floatgyro_angle;

  //floatAngle_gy;

  gyro_angle=(float)Get6050Data(dir);//检测陀螺仪的当前值

  gyro_angle=-(gyro_angle+MPU6050_ZERO_GYRO)/16.4;//去除零点偏移,计算角速度值,负号为方向处理

  //Angle_gy+=gyro_angle*0.005;

  returngyro_angle;//返回测量值

  }

  //采样10次去掉两个最大最小值求平均

  voidMPU6050ReadAcc()

  {

  inti=0,j=0;

  intx_buf[10];

  inty_buf[10];

  intz_buf[10];

  inttemp=0;

  longtemp2=0;

  for(i=0;i<10;i++)

  {

  x_buf[i]=Get6050Data(ACCEL_XOUT);

  y_buf[i]=Get6050Data(ACCEL_YOUT);

  z_buf[i]=Get6050Data(ACCEL_ZOUT);

  }

  for(i=0;i<9;i++)

  {

  for(j=i+1;j<10;j++)

  {

  if(x_buf[j]>x_buf[i])

  {

  temp=x_buf[j];

  x_buf[j]=x_buf[i];

  x_buf[i]=temp;

  }

  if(y_buf[j]>y_buf[i])

  {

  temp=y_buf[j];

  y_buf[j]=y_buf[i];

  y_buf[i]=temp;

  }

  if(z_buf[j]>z_buf[i])

  {

  temp=z_buf[j];

  z_buf[j]=z_buf[i];

  z_buf[i]=temp;

  }

  }

  }

  temp2=0;

  for(i=2;i<8;i++)

  {

  temp2=temp2+x_buf[i];

  }

  accData[0]=temp2/6;

  temp2=0;

  for(i=2;i<8;i++)

  {

  temp2=temp2+y_buf[i];

  }

  accData[1]=temp2/6;

  temp2=0;

  for(i=2;i<8;i++)

  {

  temp2=temp2+z_buf[i];

  }

  accData[2]=temp2/6;

  }

  //得到角度

  //x,y,z:

x,y,z方向的重力加速度分量(不需要单位,直接数值即可)

  //dir:

要获得的角度.0,与x轴的角度;1,与Y轴的角度;2,与Z轴的角度.

  //返回值:

角度值.单位0.1°.

  floatmpu6050_Angle(uchardir)

  {

  floattemp,x,y,z;

  floatres=0;

  MPU6050ReadAcc();//得到accData[]值

  x=accData[0];

  y=accData[1];

  z=accData[2];

  switch(dir)

  {

  case0:

//与自然Z轴的角度

  temp=sqrt((x*x+y*y))/z;

  res=atan(temp);

  break;

  case1:

//与自然X轴的角度

  temp=x/sqrt((y*y+z*z));

  res=atan(temp);

  break;

  case2:

//与自然Y轴的角度

  temp=y/sqrt((x*x+z*z));

  res=atan(temp);

  break;

  }

  return(res*180/3.14)+0;//设置平放的基础角度值

  }

  ////******LCD12864*****///

  #include

  #include"LCD12864.h"

  #defineucharunsignedchar

  #defineuintunsignedint

  externunsignedcharADS1256_buf[9];

  voidint_port(void)//管脚初始化

  {

  P2SEL&=~BIT4;//P2.4模拟SID,设置为i/o口输出方向

  P2DIR|=BIT4;

  P2OUT&=~BIT4;

  P2SEL&=~BIT5;//P2.5模拟SCLK,设置为i/o口输出方向

  P2DIR|=BIT5;

  P2OUT&=~BIT5;

  }

  /********************************************************************

  *名称:

delay()

  *

  *输入:

t

  *输出:

  ***********************************************************************/

  voiddelay(uintt)//延时函数

  {//粗略延时,满足时序要求

  uinti,j;

  for(i=0;i

  for(j=0;j<10;j++);

  }

  /********************************************************************

  *名称:

sendbyte()

  *功能:

按照液晶的串口通信协议,发送数据

  *输入:

zdata

  *输出:

  ***********************************************************************/

  voidsendbyte(ucharzdata)//数据传送函数

  {

  ucharcode_seg7;

  ucharserial_clk;

  ucharserial_shift;

  code_seg7=zdata;

  serial_shift=0x80;

  for(serial_clk=0;serial_clk<8;serial_clk++)

  {

  if(code_seg7&serial_shift)

  {

  P2OUT|=BIT4;//SID为1

  }

  else

  {

  P2OUT&=~BIT4;//SID为0

  }

  P2OUT&=~BIT5;//产生时钟信号下沿

  P2OUT|=BIT5;//产生时钟信号上沿

  serial_shift=serial_shift>>1;//准备发送下一位数据

  }

  }

  /********************************************************************

  *名称:

write_com()

  *功能:

写串口指令

  *输入:

cmdcode

  *输出:

  ***********************************************************************/

  voidwrite_com(unsignedcharcmdcode)//写命令函数

  {

  //串口控制格式(11111AB0)

  //A数据方向控制,A=H时读,A=L时写

  //B数据类型选择,B=H时为显示数据,B=L时为命令

  sendbyte(0xf8);//MCU向LCD发命令

  sendbyte(cmdcode&0xf0);//发高四位数据(数据格式D7D6D5D4_0000)

  sendbyte((cmdcode<<4)&0x

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 演讲主持

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1