前言
上一篇,给大家介绍了平衡小车的硬件资源及其小车底层硬件介绍篇
平衡小车学习教程1——硬件资源及其小车底层硬件介绍篇
这篇来教大家如何快速的使用MPU6050自带的DMP库读取陀螺仪数据,读取翻滚角(Roll)、俯仰角(Pitch)、航向角(Yaw)这三个角的数据。
而我们平衡小车的直立环
就是通过读取Roll角的数据
根据Roll角的变化,通过PID算法,得到实际值和期望值,从而得到所计算出的值传递给PWM。从而使小车达到直立状态。
所以,如何使用单片机读取陀螺仪的数据就是一个非常重要的点
本篇文章的教程采用的是STM32单片机,读取这三个角
一、认识MPU6050
1、基础认识
MPU6050,一般是下面这个小模块,通常来说,分为6脚和8脚的,6脚和8脚的区别
就是8脚的有一个XDA和一个XCL接口,这两个接口可以外接磁力计。下图就是8脚的MPU6050。
2、引脚介绍
由于MPU6050是IIC通信的,所以要使用IIC通信初始化MPU6050,读取其内部的寄存器,从而获取小车的实时状态。
所以其重要的两个引脚就是SCL引脚和SDA引脚
。
此外,MPU6050还有一个中断引脚INT,可以配置寄存器,让其产生中断,读取陀螺仪数据可放在中断内部进行。
引脚 | 引脚介绍 |
---|---|
VCC | 3.3V/5V电源输入 |
GND | 接地 |
SDA | IIC通信数据线 |
SCL | IIC通信时钟线 |
XDA | IIC外接通信数据线 |
XCL | IIC外接通信时钟线 |
AD0 | IIC从机设置引脚(悬空或接GND时为0x68 / 接高电平为0x69 ) |
INT | MPU6050中断引脚 |
二、移植方法
在这里不深究MPU6050的内部寄存器的原理,这里其实我也没弄明白
大家可以先从实操出发,首先知道如何快速使用,其实太过深究其内部原理也没太大意义,后面想深入研究也是没问题的。
所以这里我将会带着大家一步一步的如何快速移植MPU6050其内部自带的DMP库,如何使用自带的数字运动处理器(DMP库)读取完整的 6轴或9 轴姿态融合演算数据。
1、什么是DMP
我们可以通过IIC通信读取MPU6050其内部的寄存器,从而得到加速度传感器数据或者角速度传感器数据
但是我们做平衡小车,不是要这六个数据,而是欧拉角,即Roll、Pitch、Yaw角这三个角度
要得到欧拉角,其实要进行姿态解算,自己来姿态解算有点困难,但是使用DMP就不一样了,使用DMP,可以将原始数据直接转换为四元数输出,得到四元数之后,就可以很方便的计算出欧拉角,从而得到Roll、Pitch、Yaw角。
2、如何移植DMP
下载原子的百度网盘资料
正点原子MPU6050资料下载
-
首先点击上方链接,点进去之后把这个资料下载下来
-
然后下载下来捏 旧资料–>程序源码–>随便选一个压缩包文件解压
我这里选择(库函数版本,适合MiniSTM32开发板)扩展实验16 ATK-MPU6050六轴传感器实验
移植对应文件添加进我们自己的工程当中
- 这个工程里,我们需要的就是啥捏,需要的就只是
六轴传感器模块ATK-MPU6050资料(旧资料)\2,程序源码\移植\(库函数版本,适合MiniSTM32开发板)扩展实验16 ATK-MPU6050六轴传感器实验\HARDWARE
这个文件夹里的MPU6050文件夹
- 复制这整个文件到自己的工程文件夹里,然后在Keil里添加相应的文件,如何在keil里添加对应文件我就不多说了
然后,大家可以看见,最终我们需要的文件就是mpuiic.c
、mpu6050.c
、inv_mpu.c
、inv_mpu_dmp_motion_driver.c
,将这四个文件添加进Keil里的驱动文件中,最终效果如下图
- 然后捏修改自己板子对应的引脚或者使用杜邦线来连接6050
- 然后Keil里项目文件如下图所示
就是这四个文件,我们需要的就是这四个文件
3、移植注意事项
1、mpuiic.c
和mpuiic.h
第一个要注意的地方,修改初始化引脚
找到
void MPU_IIC_Init(void)
可以看到这是MPU6050对应的SCL和SDA的初始化引脚,MPU6050是使用IIC通信来获得欧拉角的
所以我们要对这个IO进行修改
下方是源文件中的初始化
我们根据PCB中引出的GPIO,进行修改,由于我们板载引脚是
引脚 | 对应GPIO |
---|---|
AD0 | GND |
INT | PB5 |
SCL | PB4 |
SDA | PB3 |
做出以下修改
// 初始化IIC SCL PB4 SDA PB3
void MPU_IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 先使能外设IO PORTC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 使能AFIO 复用时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); // 失能JTAG调试端口 这样PB3 pB4 就是作为一个普通的IO口使用
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); // 根据设定参数初始化GPIO
GPIO_SetBits(GPIOB, GPIO_Pin_3 | GPIO_Pin_4); // PB3 PB4 输出高
}
至于为什么在初始化的过程中会失能JTAG呢?
可以看引脚对应的功能,PB3和PB4是JTAG试端口,我们需要失能JTAG端口才可以把这两个IO当作GPIO使用
第二个要注意的地方,修改SCL和SDA的宏定义
打开mpuiic.h
文件
可以看到这里定义了很多宏定义,这是源程序
第一个IO设置是啥意思呢?
我们知道IIC通信中,SDA是数据线,肯定是有输入和输出的,这里的IO方向设置,就是设置SDA的输入模式和输出模式,大家可以看库函数手册,如下图,这是对应的引脚数高八位的端口的寄存器 端口配置高寄存器(GPIOx_CRH) (x=A..E)
我们先根据源程序,分析一下,首先他使用的是
SCL-->PC12
SDA-->PC11
IO方向,就是对端口的寄存器进行操作,所以
#define MPU_SDA_IN() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}
这一句前面就是重新清零PC11的端口模式位,后面就是再把PC11的端口寄存器的第15-12位设置为1000
这个图好理解了叭,总结能力满分
我们做出以下修改
#define MPU_SDA_IN() \
{ \
GPIOB->CRL &= 0XFFFF0FFF; \
GPIOB->CRL |= 8 << 12; \
}
#define MPU_SDA_OUT() \
{ \
GPIOB->CRL &= 0XFFFF0FFF; \
GPIOB->CRL |= 3 << 12; \
}
// IO操作函数
#define MPU_IIC_SCL PBout(4) // SCL
#define MPU_IIC_SDA PBout(3) // SDA
#define MPU_READ_SDA PBin(3) // 输入SDA
2、查看一下,自己移植的正点原子的代码,有没有用到INT引脚
如果用到了INT引脚,一般是中断读取欧拉角,肯定初始化了IO,把那部分去掉,我们并没有使用到INT引脚(使用的是主程序中循环读取
)
他初始化的IO可能会导致程序错误
所以还请注释掉,保证后面操作的正确性
4.在主程序中初始化MPU6050
1、在主程序中初始化MPU6050
delay_ms(500); // 延时0.5s 使MPU6050初始化稳定
MPU_Init(); // 初始化MPU6050
mpu_dmp_init();
2、在主程序中不断获取DMP处理后的数据
while( mpu_dmp_get_data(&pitch, &roll, &yaw)!=0 ){}//返回值:0,正常 // 其他,失败1
u1_printf("\n\r pitch=%0.2f roll=%0.2f yaw=%0.2f \n\r", pitch, roll, yaw);
3、连接串口查看角度变化
一般要等个几秒钟,等待MPU6050初始化成功!
然后使用串口查看数据
可以看到,读取数据成功,三个角都成功的被读取,我们的目的实现
四、Roll、Pitch、Yaw角的区分
1、手动旋转MPU6050进行区分
这个呢,大家可以根据自己读取到的角度进行区分,把MPU6050进行旋转,查看角度的变化
左右就是偏航角(沿X轴)
上下就是俯仰角(沿Z轴)
左侧右侧偏就是翻滚角(沿Y轴)
大家可以去找大佬讲的,网上有很多资料的
2、使用vofa+控件进行区分(未实现)
本来想用vofa+,来直观的显示一下角度的变换的,可是没搞出来,这个控件不知道咋玩,等啥时候弄出来了补上
五、总结
这一篇主要是软件篇,教大家如何移植并且读取到MPU6050的数据,毕竟平衡小车的所有都是基于角度来实现直立的,这是软件篇的第一步。
大家在学会这个之后,就可以快速移植官方文件,得到自己想要的功能
文章还是有很多没有讲的很清楚的地方,我也是粗略的将移植步骤交给大家,有一些原理还是不够深入
希望大家,还是要先了解原理,再深入,再做项目,在项目中二次深入理解
好啦,下一节将会给大家带来
小车的底层驱动的软件篇——小车底层驱动(电机、编码器)
大家可以再次期待一下下,嘿嘿,加油加油!