【实验原理】
一、陀螺仪简介
陀螺仪(gyroscope)是角运动检测装置,传统陀螺仪是通过检测高速回转体的动量矩敏感壳体相对惯性空间绕正交于自转轴的一个或两个轴的角运动的装置。通俗的来讲,一个旋转物体的旋转轴所指的方向在不受外力影响时,是不会改变的。人们根据这个道理,用它来保持方向。然后用多种方法读取轴所指示的方向,并自动将数据信号传给控制系统。利用其他原理制成的角运动检测装置起同样功能的也称陀螺仪。
传统陀螺仪为机械式陀螺仪,然而机械式陀螺仪制造工艺要求高,而且精度低,体积大。于是,人们开始寻找更好的办法,利用物理学上的进步,发展出激光陀螺仪,光纤陀螺仪,以及微机电陀螺仪(MEMS)。这些东西虽然还叫陀螺仪,但是它们的原理和传统的机械陀螺仪已经完全是两码事了。目前,传统上的机械陀螺仪正在被淘汰,有高精度需求的地方用的是激光陀螺仪,而普及方面则是微机电陀螺仪。
二、MPU6050简介
本实验采用的是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)。
硬件连接图和库函数介绍
图1.1 硬件连接示意图
在本实验中所使用的库函数包括IICwriteBits函数,该函数的参数含义如下:
dev,设备地址,这里为MPU6050设备地址(在mpu6050.h中给出宏定义);
reg,目标寄存器地址,这里指PWR电池管理寄存器地址0x6B;
bitStart,寄存器上功能标志位起始地址,由于配置时钟源的标志位为寄存器上的[2:0]位,因此这里的值为2;
length,功能标志位长度,由于配置时钟源的标志位为寄存器上的[2:0]位,长度为3,因此这里的值为3;
data,将要在寄存器标志位储存的值,这里由函数入口的时钟源参数给出。
I2C_ReadOneByte函数,该函数的参数含义如下:
I2C_Addr ,目标设备地址,这里为MPU6050设备地址(在mpu6050.h中给出宏定义);
addr,寄存器地址
四、软件流程图
由于MPU6050通过IIC通信,因此可以通过IIC访问各个数据寄存器对应的地址,就能得到相应的陀螺仪加速度计信息。各个功能寄存器的寄存器地址已经在mpu6050.h中给出,程序中已经预给出的库函数还有:oled.c显示屏库函数、delay.c延时库函数、IOI2C模拟IIC库函数等,程序流程的简要说明图如图1.2所示:
图1.2 程序流程示意图
【实验环境】
硬件设备:
双轮自平衡机器人。如图1.3所示,在平衡车上威廉希尔官方网站
板上已经集成了MPU6050模块。
ST-Link下载器(包含USB线与下载线)。如图1.4所示。
操作系统:
Windows7/8/10,32bit/64bit
软件环境:
Keil 5
【实验步骤】
第一步 配置工程环境
打开已经建立好的工程模板,在新建立的工程模板中已经添加五个文件夹,分别命名为USER、HARDWARE、SYSTEM、CORE、FWLib文件夹,如图1.5所示。其中USER文件夹存放的是主函数,HARDWARE文件夹存放的是本实验对应的硬件设备函数,SYSTEM存放的是本课程所有实验通用的函数,CORE文件夹存放的是启动文件,FWLib文件夹存放的是底层驱动函数。
图1.5 工程模板对应的文件夹
在HARDWARE文件夹下新建一个文件,命名为mpu6050.c,并加载已经编写好的在工程目录下HARDWARE文件夹里的MPU6050文件夹内的MPU6050.h文件,该文件存放MPU6050寄存器地址已经相应数据位的宏定义。mpu6050.c则存放MPU6050的配置文件,如图1.6所示。
图1.6 在HARDWARE文件夹下建立mpu6050.c与mpu6050.h文件
第二步 陀螺仪寄存器读取函数和初始化函数
打开程序中的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
……
第三步 编写main.c文件
将工程编译需要用到的头文件包含进来,并预定义显示函数和全局变量。
#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.8所示的编译按键。
图1.8Keil编译环境下的编译按键
当编译完成后,如果没有问题,Build Output栏会出现无错误、无警告的提示,如图1.9所示。
图1.9 编译通过后Build Output栏提示信息
下载程序:点击如图所示的下载按键,程序就会下载到STM32的芯片中。下载按键如图1.10所示。
图1.10 Keil编译环境下的下载按键
观察实验现象,OLED显示屏上显示出当前陀螺仪的读数,用手轻轻晃动车身,观察数值的变化。
【实验原理】
一、陀螺仪简介
陀螺仪(gyroscope)是角运动检测装置,传统陀螺仪是通过检测高速回转体的动量矩敏感壳体相对惯性空间绕正交于自转轴的一个或两个轴的角运动的装置。通俗的来讲,一个旋转物体的旋转轴所指的方向在不受外力影响时,是不会改变的。人们根据这个道理,用它来保持方向。然后用多种方法读取轴所指示的方向,并自动将数据信号传给控制系统。利用其他原理制成的角运动检测装置起同样功能的也称陀螺仪。
传统陀螺仪为机械式陀螺仪,然而机械式陀螺仪制造工艺要求高,而且精度低,体积大。于是,人们开始寻找更好的办法,利用物理学上的进步,发展出激光陀螺仪,光纤陀螺仪,以及微机电陀螺仪(MEMS)。这些东西虽然还叫陀螺仪,但是它们的原理和传统的机械陀螺仪已经完全是两码事了。目前,传统上的机械陀螺仪正在被淘汰,有高精度需求的地方用的是激光陀螺仪,而普及方面则是微机电陀螺仪。
二、MPU6050简介
本实验采用的是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)。
硬件连接图和库函数介绍
图1.1 硬件连接示意图
在本实验中所使用的库函数包括IICwriteBits函数,该函数的参数含义如下:
dev,设备地址,这里为MPU6050设备地址(在mpu6050.h中给出宏定义);
reg,目标寄存器地址,这里指PWR电池管理寄存器地址0x6B;
bitStart,寄存器上功能标志位起始地址,由于配置时钟源的标志位为寄存器上的[2:0]位,因此这里的值为2;
length,功能标志位长度,由于配置时钟源的标志位为寄存器上的[2:0]位,长度为3,因此这里的值为3;
data,将要在寄存器标志位储存的值,这里由函数入口的时钟源参数给出。
I2C_ReadOneByte函数,该函数的参数含义如下:
I2C_Addr ,目标设备地址,这里为MPU6050设备地址(在mpu6050.h中给出宏定义);
addr,寄存器地址
四、软件流程图
由于MPU6050通过IIC通信,因此可以通过IIC访问各个数据寄存器对应的地址,就能得到相应的陀螺仪加速度计信息。各个功能寄存器的寄存器地址已经在mpu6050.h中给出,程序中已经预给出的库函数还有:oled.c显示屏库函数、delay.c延时库函数、IOI2C模拟IIC库函数等,程序流程的简要说明图如图1.2所示:
图1.2 程序流程示意图
【实验环境】
硬件设备:
双轮自平衡机器人。如图1.3所示,在平衡车上威廉希尔官方网站
板上已经集成了MPU6050模块。
ST-Link下载器(包含USB线与下载线)。如图1.4所示。
操作系统:
Windows7/8/10,32bit/64bit
软件环境:
Keil 5
【实验步骤】
第一步 配置工程环境
打开已经建立好的工程模板,在新建立的工程模板中已经添加五个文件夹,分别命名为USER、HARDWARE、SYSTEM、CORE、FWLib文件夹,如图1.5所示。其中USER文件夹存放的是主函数,HARDWARE文件夹存放的是本实验对应的硬件设备函数,SYSTEM存放的是本课程所有实验通用的函数,CORE文件夹存放的是启动文件,FWLib文件夹存放的是底层驱动函数。
图1.5 工程模板对应的文件夹
在HARDWARE文件夹下新建一个文件,命名为mpu6050.c,并加载已经编写好的在工程目录下HARDWARE文件夹里的MPU6050文件夹内的MPU6050.h文件,该文件存放MPU6050寄存器地址已经相应数据位的宏定义。mpu6050.c则存放MPU6050的配置文件,如图1.6所示。
图1.6 在HARDWARE文件夹下建立mpu6050.c与mpu6050.h文件
第二步 陀螺仪寄存器读取函数和初始化函数
打开程序中的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
……
第三步 编写main.c文件
将工程编译需要用到的头文件包含进来,并预定义显示函数和全局变量。
#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.8所示的编译按键。
图1.8Keil编译环境下的编译按键
当编译完成后,如果没有问题,Build Output栏会出现无错误、无警告的提示,如图1.9所示。
图1.9 编译通过后Build Output栏提示信息
下载程序:点击如图所示的下载按键,程序就会下载到STM32的芯片中。下载按键如图1.10所示。
图1.10 Keil编译环境下的下载按键
观察实验现象,OLED显示屏上显示出当前陀螺仪的读数,用手轻轻晃动车身,观察数值的变化。
举报