本文共 6892 字,大约阅读时间需要 22 分钟。
版权归如下公司,禁止非授权转载:
熟悉陀螺仪工作原理,了解不同种类陀螺仪之间的差异;
熟悉MPU6050的输出形式,熟悉MPU6050的通信方法; 掌握STM32F10xx系列微控制器上陀螺仪的接口配置与数据采集过程;陀螺仪(gyroscope)是角运动检测装置,传统陀螺仪是通过检测高速回转体的动量矩敏感壳体相对惯性空间绕正交于自转轴的一个或两个轴的角运动的装置。通俗的来讲,一个旋转物体的旋转轴所指的方向在不受外力影响时,是不会改变的。人们根据这个道理,用它来保持方向。然后用多种方法读取轴所指示的方向,并自动将数据信号传给控制系统。利用其他原理制成的角运动检测装置起同样功能的也称陀螺仪。
传统陀螺仪为机械式陀螺仪,然而机械式陀螺仪制造工艺要求高,而且精度低,体积大。于是,人们开始寻找更好的办法,利用物理学上的进步,发展出激光陀螺仪,光纤陀螺仪,以及微机电陀螺仪(MEMS)。这些东西虽然还叫陀螺仪,但是它们的原理和传统的机械陀螺仪已经完全是两码事了。目前,传统上的机械陀螺仪正在被淘汰,有高精度需求的地方用的是激光陀螺仪,而普及方面则是微机电陀螺仪。
本实验采用的是MPU6050运动传感器,它是一款整合性6轴运动传感器,集成了3轴MEMS陀螺仪,3轴MEMS加速度计,以及一个可拓展的数字运动处理器DMP(Digital Motion Processor)。MPU6050传输可透过最高至400kHz的IIC通信,也可以通过其I2C接口连接其他非惯性的数字传感器。IIC通信协议要求每一个挂载在总线上的设备都要有一个独有的7位设备地址,用以区分信号传递的对象。MPU6050的设备地址前六位在出场时已经由厂商决定为(110100B),而MPU6050提供一个AD0引脚用以确定第7位电平,若AD0接地,则其设备地址为0x68H(1101000B),再加上第8位读写方向位,构成了IIC传输的器件地址0xD0(11010000B)。
硬件连接图和库函数介绍
I2C_ReadOneByte函数,该函数的参数含义如下:
图1.2 程序流程示意图
双轮自平衡机器人。如图1.3所示,在平衡车上电路板上已经集成了MPU6050模块。
ST-Link下载器(包含USB线与下载线)。如图1.4所示。 操作系统: Windows7/8/10,32bit/64bitKeil 5
打开已经建立好的工程模板,在新建立的工程模板中已经添加五个文件夹,分别命名为USER、HARDWARE、SYSTEM、CORE、FWLib文件夹,如图1.5所示。其中USER文件夹存放的是主函数,HARDWARE文件夹存放的是本实验对应的硬件设备函数,SYSTEM存放的是本课程所有实验通用的函数,CORE文件夹存放的是启动文件,FWLib文件夹存放的是底层驱动函数。
打开程序中的mpu6050.c文件,首先将mpu6050.h和IOI2C.h文件包含进来。其次编写MPU6050的时钟源配置函数MPU6050_setClockSource。
#include "MPU6050.h"#include "IOI2C.h"/****************************************************************函数功能:设置MPU6050的时钟源入口参数:时钟源参数返回值:无****************************************************************/void MPU6050_setClockSource(uint8_t source){ IICwriteBits(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_CLKSEL_BIT, MPU6050_PWR1_CLKSEL_LENGTH, source);}
同理,编写陀螺仪加速度计量程设置函数、睡眠唤醒函数、主从机设置函数
/****************************************************************函数功能:设置MPU6050的陀螺仪最大量程入口参数:陀螺仪最大量程参数返回值:无****************************************************************/void MPU6050_setFullScaleGyroRange(uint8_t range) { IICwriteBits(devAddr, MPU6050_RA_GYRO_CONFIG, MPU6050_GCONFIG_FS_SEL_BIT,MPU6050_GCONFIG_FS_SEL_LENGTH, range);}/****************************************************************函数功能:设置MPU6050的加速度计最大量程入口参数:加速度计最大量程参数返回值:无****************************************************************/void MPU6050_setFullScaleAccelRange(uint8_t range) { IICwriteBits(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_AFS_SEL_BIT,MPU6050_ACONFIG_AFS_SEL_LENGTH, range);}/****************************************************************函数功能:设置MPU6050是否进入睡眠模式入口参数:0否 1是返回值:无****************************************************************/void MPU6050_setSleepEnabled(uint8_t enabled) { IICwriteBit(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_SLEEP_BIT, enabled);}/****************************************************************函数功能:设置MPU6050是否为主机模式入口参数:0否 1是返回值:无****************************************************************/void MPU6050_setI2CMasterModeEnabled(uint8_t enabled) { IICwriteBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_I2C_MST_EN_BIT, enabled);}/****************************************************************函数功能:设置MPU6050是否允许IIC通信入口参数:0否 1是返回值:无****************************************************************/void MPU6050_setI2CBypassEnabled(uint8_t enabled) { IICwriteBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_I2C_BYPASS_EN_BIT, enabled);}
编写MPU6050初始化函数,在初始化函数中调用以上定义的函数完成初始化。
/*************************************************************函数功能:初始化MPU6050以进入可用状态入口参数:无返回值:无************************************************************/void MPU6050_initialize(void) { //设置时钟 MPU6050_setClockSource(MPU6050_CLOCK_PLL_YGYRO); //陀螺仪最大量程+-1000度每秒 MPU6050_setFullScaleGyroRange(MPU6050_GYRO_FS_2000); //加速度计最大量程+-2G MPU6050_setFullScaleAccelRange(MPU6050_ACCEL_FS_2); //进入工作状态 MPU6050_setSleepEnabled(0); //不让MPU6050控制AUX IIC MPU6050_setI2CMasterModeEnabled(0); //主控制器的IIC与MPU6050的AUX IIC 直通 MPU6050_setI2CBypassEnabled(0);}
打开encoder.h,设置MPU6050设备地址宏定义。
#ifndef __MPU6050_H#define __MPU6050_H#include "sys.h"#define devAddr 0xD0……
将工程编译需要用到的头文件包含进来,并预定义显示函数和全局变量。
#include "mpu6050.h" //包含mpu6050函数头文件#include "sys.h" //包含系统头文件#include "stm32f10x.h" //包含系统寄存器定义声明的头文件void oled_show(void);int Gyro_X,Gyro_Z; // X、Z轴的陀螺仪变量
在主函数中调用延时函数、显示函数、IIC函数和MPU6050的初始化函数。
int main(void){ delay_init(); //延时函数初始化delay_ms(500); OLED_Init(); //OLED初始化 IIC_Init (); //IIC初始化 MPU6050_initialize (); //MPU6050初始化//在主循环中调用超声波读取函数和显示函数 while(1) { Gyro_X=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_XOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_XOUT_L); //读取X轴陀螺仪数据Gyro_Z=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_ZOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_ZOUT_L); //读取Z轴陀螺仪数据 if(Gyro_X>32768) Gyro_X-=65536; //数据类型转换 if(Gyro_Z>32768) Gyro_Z-=65536; //数据类型转换 oled_show(); //显示屏打开 delay_ms(50); }
编写OLED显示函数
void oled_show(void){ //显示右侧编码器返回值 OLED_ShowString(0,10," Gyro_X "); if(Gyro_X >=0)OLED_ShowString(20,20," "), OLED_ShowNumber(45,20, Gyro_X,4,12); else OLED_ShowString(20,20,"-"), OLED_ShowNumber(45,20,4- Gyro_X,4,12);//显示左侧编码器返回值 OLED_ShowString(0,40," Gyro_Z "); if(Gyro_Z >=0)OLED_ShowString(10,50," "), OLED_ShowNumber(45,50, Gyro_Z,4,12); else OLED_ShowString(10,50,"-"), OLED_ShowNumber(45,50,- Gyro_Z,4,12); //=============刷新======================// OLED_Refresh_Gram(); }
本实验采用仿真器为STLink V2,将仿真器与小车相连,注意正负极不要接反,如图1.7所示。
题目1:若AD0引脚接高电平,MPU6050的7位设备地址是(B)
A:0x68 B:0x69 C:0xD0 D:0xD1 题目2:同一条IIC总线上最多挂在几个MPU6050设备(B) A:1 B:2 C:127 D:128题目1:简要阐述机械陀螺仪的工作原理。
一个旋转物体的旋转轴所指的方向在不受外力影响时,是不会改变的。人们根据这个道理,用它来保持方向,制造出来的东西就叫做陀螺仪。陀螺仪在工作时要给它一个力,使它快速旋转起来,一般能达到每分钟几十万转,可以工作很长时间。然后用多种方法读取轴所指示的方向,并自动将数据信号传给控制系统。