一. 简介mpu6050 是 invensense 公司推出的整合性 6 轴运动处理组件,其内部整合了 3 轴陀螺仪和 3 轴加速度传感器,并且含有一个iic 接口, 可用于连接外部磁力传感器,并利用自带的数字运动处理器(dmp: digital motion processor) 硬件加速引擎,通过主 iic 接口,向应用端输出完整的 9 轴融合演算数据。
invensense 公司提供了一套基于dmp的运动处理驱动库,可大大降低单片机对动处理运算的负荷,同时也大大降低了编程难度。
mpu6050配合官方提供的运动处理驱动库,可以容易地获取出飞控系统融合演算数据; 同时也可以计步传感器,通过调用驱动库相应的函数,获取运动步数、运动时间等数据。
二. mpu6050原理及参数1.芯片内部框图mpu内部自带有7路16bit的adc转换电路,其中3路为陀螺仪、3路为加速度计、1路为内部温度传感器。 adc转换后的数据通过dmp处理后,存储在fifo里。 单片机通过对芯片内部寄存器进行读写操作,完成对mpu的控制。
2.芯片引脚说明mpu6050的接线比较简单,使用3.3v的工作电源,通过iic接口(mpu6000还可用spi接口)与mcu通信。
3.模块电路图模块原理图如下,其中使用了spx3810m稳压芯片,将5v电源转换为3.3v电压给mpu6050芯片供电,p-mos管q1、q2作为电平转换电路,将芯片的iic电平转化为5.0v电平,可兼容51单片机和stm32单片机的控制电平(注:stm32引脚需要配置为开漏状态,且需要所用引脚能兼容5.0v电压,引脚标志为ft)。 采用3.3v的单片机控制,如果不想要或者无法兼容5v电压,可将电平转换电路去掉,将iic接口直接接单片机iic引脚。
4.单片机与模块接线图单片机iic接口采用模拟iic通信。
三. mpu6050编程及控制因为mpu6050内部带有dmp处理单元,加上官方提供了比较完整的运动处理驱动库,大大降低了我们的编程和对数据的处理难度。 我们可以将各个运动的参数计算,如旋转矩阵、四元数(quaternion)、欧拉角格式(euler angle forma)的融合演算数据,通过调用运动处理驱动库函数,直接读取出数据来。 以下程序是基于正点原子atk-mpu6050模块的开发例程为例。 在完成标准的iic驱动程序后,先实现读寄存器和写寄存器操作;
(1)读寄存器操作
//iic读一个字节 //reg:寄存器地址 //返回值:读到的数据u8 mpu_read_byte(u8 reg){ u8 res; mpu_iic_start(); mpu_iic_send_byte((mpu_addr<<1)|0);//发送器件地址+写命令 mpu_iic_wait_ack(); //等待应答 mpu_iic_send_byte(reg); //写寄存器地址 mpu_iic_wait_ack(); //等待应答 mpu_iic_start(); mpu_iic_send_byte((mpu_addr<<1)|1);//发送器件地址+读命令 mpu_iic_wait_ack(); //等待应答 res=mpu_iic_read_byte(0);//读取数据,发送nack mpu_iic_stop(); //产生一个停止条件 return res; }(2)写寄存器操作
//iic写一个字节 //reg:寄存器地址//data:数据//返回值:0,正常// 其他,错误代码u8 mpu_write_byte(u8 reg,u8 data) { mpu_iic_start(); mpu_iic_send_byte((mpu_addr<<1)|0);//发送器件地址+写命令 if(mpu_iic_wait_ack()) //等待应答 { mpu_iic_stop(); return 1; } mpu_iic_send_byte(reg); //写寄存器地址 mpu_iic_wait_ack(); //等待应答 mpu_iic_send_byte(data);//发送数据 if(mpu_iic_wait_ack()) //等待ack { mpu_iic_stop(); return 1; } mpu_iic_stop(); return 0;}实现这个两个函数后,就可实现对mpu6050的各种操作了; 但是无法调用官方自带的运动处理驱动库。 首先我们在keil工程里面增入文件“inv_mpu_dmp_motion_driver.h”、“inv_mpu_dmp_motion_driver.c”、“inv_mpu.h”、“inv_mpu.c”、“dmpkey.h”、“dmpmap.h。
然后将在两个实现驱动库里两个基本操作函数,最后映射到驱动库的inv_mpu.h文件里面后,便可直接调用运动处理库的api了。
(3)首先实现iic连续读取数据函数/iic连续读//addr:器件地址//reg:要读取的寄存器地址//len:要读取的长度//buf:读取到的数据存储区//返回值:0,正常// 其他,错误代码u8 mpu_read_len(u8 addr,u8 reg,u8 len,u8 *buf){ mpu_iic_start(); mpu_iic_send_byte((addr<<1)|0);//发送器件地址+写命令 if(mpu_iic_wait_ack()) //等待应答 { mpu_iic_stop(); return 1; } mpu_iic_send_byte(reg); //写寄存器地址 mpu_iic_wait_ack(); //等待应答 mpu_iic_start(); mpu_iic_send_byte((addr<<1)|1);//发送器件地址+读命令 mpu_iic_wait_ack(); //等待应答 while(len) { if(len==1)*buf=mpu_iic_read_byte(0);//读数据,发送nack else *buf=mpu_iic_read_byte(1); //读数据,发送ack len--; buf++; } mpu_iic_stop(); //产生一个停止条件 return 0; }(4)实现iic连续写数据函数//iic连续写//addr:器件地址 //reg:寄存器地址//len:写入长度//buf:数据区//返回值:0,正常// 其他,错误代码u8 mpu_write_len(u8 addr,u8 reg,u8 len,u8 *buf){ u8 i; mpu_iic_start(); mpu_iic_send_byte((addr<<1)|0);//发送器件地址+写命令 if(mpu_iic_wait_ack()) //等待应答 { mpu_iic_stop(); return 1; } mpu_iic_send_byte(reg); //写寄存器地址 mpu_iic_wait_ack(); //等待应答 for(i=0;i
设置完成后,便可使用官方的运动处理驱动库。 其他功能性函数就不一一列出;
(5)最后实现mpu6050的初始化。//初始化mpu6050//返回值:0,成功// 其他,错误代码u8 mpu_init(void){ u8 res; mpu_iic_init();//初始化iic总线 mpu_write_byte(mpu_pwr_mgmt1_reg,0x80); //复位mpu6050 delay_ms(100); mpu_write_byte(mpu_pwr_mgmt1_reg,0x00); //唤醒mpu6050 mpu_set_gyro_fsr(3); //陀螺仪传感器,±2000dps mpu_set_accel_fsr(0); //加速度传感器,±2g mpu_set_rate(50); //设置采样率50hz mpu_write_byte(mpu_int_en_reg,0x00); //关闭所有中断 mpu_write_byte(mpu_user_ctrl_reg,0x00); //i2c主模式关闭 mpu_write_byte(mpu_fifo_en_reg,0x00); //关闭fifo mpu_write_byte(mpu_intbp_cfg_reg,0x80); //int引脚低电平有效 res=mpu_read_byte(mpu_device_id_reg); if(res==mpu_addr)//器件id正确 { mpu_write_byte(mpu_pwr_mgmt1_reg,0x01); //设置clksel,pll x轴为参考 mpu_write_byte(mpu_pwr_mgmt2_reg,0x00); //加速度与陀螺仪都工作 mpu_set_rate(50); //设置采样率为50hz }else return 1; return 0;}四. mpu6050的控制及数据采集在单片机进行初始化时,先需要调用mpu_init函数初始化后,还要调用mpu_dmp_init函数对模块进行初始化。 代码如下:
int main(void) { float pitch,roll,yaw; //欧拉角 short aacx,aacy,aacz; //加速度传感器原始数据 short gyrox,gyroy,gyroz; //陀螺仪原始数据 short temp; //温度 mpu_init(); //初始化mpu6050 while(mpu_dmp_init()); while(1) { if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0) { temp=mpu_get_temperature(); //得到温度值 mpu_get_accelerometer(&aacx,&aacy,&aacz); //得到加速度传感器数据 mpu_get_gyroscope(&gyrox,&gyroy,&gyroz); //得到陀螺仪数据 } } }
嫦娥光学焦度计10周年盛典:联合线下经销商,巨惠回馈新老客户!
小狗电器D-512 全面提升立式吸尘器清洁体验
什么是子网掩码?如何根据掩码来确定ip地址网段?
锂离子电池负极材料的研究现状、发展及产业化
全面解析全新北斗三号的那些技术方案
基于单片机的MPU6050六轴传感器设计
陕西联通完成首次5G工业机器人巡检,全面助力陕煤集团数字化转型升级
通过采用热敏电阻实现周期转换电路的应用设计
传苹果有意打造更便宜的手机,欲与小米竞争
华为海思进退维谷,何去何从?
数百名开发人员的Git源代码库被删除,并被要求支付赎金
升哲科技与Graphcore合作,打造基于IPU的城市ESG方案
买手机选择大存储空间还是考虑云存储
NXP推出汽车车锁IMMO/RKE/PKE解决方案
物联网工作的流程及步骤介绍
华为荣耀v9怎么样?荣耀v9和小米5c测评对比,谁更值得买?
2020到2025年全球中小尺寸TFT LCD出货量分析
或将斥巨资建立芯片工厂?三星如何解决产能吃紧问题?
哈工智能的非公开发行募资计划即将收官
独立显卡怎么安装