1. 简介
(1)MPU6050
MPU-60X0是全球首例9轴运动处理器。它集成了3轴MEMS陀螺仪,3轴MEMS加速计,以及1个可扩展的数字运动处理器DMP,可用I2C接口连接一个第三方的数字传感器,比如磁力计。扩展之后就可以通过其I2C或SPI接口输出一个9轴的信号。MPU-60X0也可以通过其I2C接口连接非惯性的数字传感器,比如压力传感器等,在做嵌入式开发中,我们经常用它做运动检测,姿态识别,平衡控制等应用。
(2)DMP
MPU6050 自带了数字运动处理器,即 DMP,并且InvenSense 提供了一个 MPU6050 的嵌入式运动驱动库,结合 MPU6050 的 DMP,可以将我们的原始数据,直接转换成四元数输出,而得到四元数之后,就可以很方便的计算出欧拉角,从而得到 yaw、roll 和 pitch。使用内置的 DMP,大大简化了四轴的代码设计,且 MCU 不用进行姿态解算过程,大大降低了 MCU 的负担,从而有更多的时间去处理其他事件,提高系统实时性。
2. 下载例程
Gitee下载:STM32ExampleCode-04-MPU6050
3. IIC驱动
由于模块采用IIC通信,我们先写一个软件IIC的驱动文件,大家可以参考目录.\05-MPU6050陀螺仪模块\MPU6050\MPU6050示例工程\HARDWARE\IIC下的myiic.h文件,根据需要修改自己的引脚,由于这里使用的是CRL和CRH寄存器来配置的输入输出方向,所以我们在修改时需要注意寄存器的正确使用,示例中IIC的SDA引脚为PB0,SCL引为PB1,在本手册中涉及的所有IIC的相关模块,使用的都是这个IIC文件。
4. MPU6050驱动
在目录"\HARDWARE\MPU6050"下,有MPU6050 驱动文件:
5. 使用方法
1) 基本初始化
IIC_Init(); //IIC初始化
MPU6050_initialize();//MPU6050初始化
DMP_Init(); //DMP初始化
2) 定时器初始化
由于我们使用DMP,这里我们开启定时中断来读取DMP的数据
main.c中定义TIM2_Init函数:
/*
*********************************************************************************************************
* 函 数 名: TIM2_Init
* 功能说明: 定时器2初始化
* 形 参:u16 arr,u16 psc
* arr:重载系数 psc:预分频系数
* 返 回 值: 无
*********************************************************************************************************
*/
void TIM2_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能
TIM_TimeBaseStructure.TIM_Period= arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms
TIM_TimeBaseStructure.TIM_Prescaler=psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率
TIM_TimeBaseStructure.TIM_ClockDivision= 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode= TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_ITConfig( TIM2,TIM_IT_Update|TIM_IT_Trigger,ENABLE); //使能定时器2更新触发中断
TIM_Cmd(TIM2, ENABLE); //使能TIMx外设
NVIC_InitStructure.NVIC_IRQChannel= TIM2_IRQn; //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);
}
3) 定时器中断
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)//溢出中断
{
Read_DMP(&Pitch,&Roll,&Yaw);
printf("\n\r 俯仰角=%.2f 横滚角=%.2f 偏航角=%.2f \n\r",Pitch,Roll,Yaw);
}
TIM_ClearITPendingBit(TIM2,TIM_IT_Update); //清除中断标志位
}
4) 主函数
/*
*********************************************************************************************************
* 函 数 名: main
* 功能说明: 主函数,定时读取并打印陀螺仪姿态信息与芯片温度
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
int main(void)
{
delay_init(); //delay初始化
uart_init(115200); //串口初始化
printf("uart ok!\r\n");
IIC_Init(); //IIC初始化
MPU6050_initialize(); //MPU6050初始化
DMP_Init(); //DMP初始化
TIM2_Init(1999,719); //定时器初始化,完成MPU6050定时采集DMMP数据
TIM_Cmd(TIM2,ENABLE); //启动定时器
while(1)
{
//定时读取并打印陀螺仪姿态信息并每1s读取MPU6050芯片温度
printf("tempuare is %.1f\r\n",(float)Read_Temperature()/10);
delay_ms(1000);
}
}
6. 编译烧录运行
烧录运行,查看运行结果: