STM32基于HAL库(CUBEMX)MPU6050 DMP的移植(新手一看必会)_mpu6050移植
前言
刚学了STM32的HAL库,想拿个东西练练手,发现手里有个大一之前玩的平衡小车,于是就想用HAL库写一个平衡小车的代码
下面是我移植MPU6050的过程,用的是硬件I2C(用CUBEMX自动生成)
一、使用CUBE建立工程(基于STM32F103C8T6)
1.RCC时钟配置
选择外部高速晶振
时钟树:
2.配置I2C和USART1
根据c8t6 IO功能表,能用的硬件I2C有2个,大家根据自己MPU6050的I2C接口自己选择I2C,我自己选择的是I2C1(SCL是PB8,SDA是PB9)
注意:要先选择引脚B8 B9 ,再选择I2C1如果直接点I2C1会默认成B6 B7
这里我配置了一个串口,用来打印6050角度信息
C8T6烧录时要配置一下sys,Debug要选择Serial Wire,否则烧入不进去
工程生成
然后点击
打开工程
二、基础代码配置
1.首先编写一下串口重定向,这样就可以直接用printf直接打印我们的角度信息
打开usart.c
加入下面代码
/** * 函数功能: 重定向c库函数printf到DEBUG_USARTx * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */#include #include int fputc(int ch, FILE *f){ HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff); return ch;} /** * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */int fgetc(FILE *f){ uint8_t ch = 0; HAL_UART_Receive(&huart1, &ch, 1, 0xffff); return ch;}
主函数也要包含头文件
#include \"stdio.h\"
要勾上Micro LIB,不然串口打印不出来
然后主函数whilie循环打印一下,编译看看有没有问题
三、移植DMP库(重要)
官方的DMP库还有2个自写文件(MPU6050.c和MPU6050.h)
移植文件免费下载链接:DMP移植文件-CSDN博客https://download.csdn.net/download/m0_73823991/89805842
将它移植入刚才创建的工程文件
新建DMP文件
将移植文件复制进来
然后在keil5添加进来
接下来是DMP文件的修改,先编译一下
1.先打开inv_mpu.c文件
把第39行到161行的代码删了
就是下面这样
然后加入下面代码
#define MPU6050#include \"main.h\"extern I2C_HandleTypeDef hi2c1;#define i2c_write(dev_addr,reg_addr,data_size,p_data) \\HAL_I2C_Mem_Write(&hi2c1,dev_addr,reg_addr,I2C_MEMADD_SIZE_8BIT,p_data,data_size,0x100)#define i2c_read(dev_addr,reg_addr,data_size,p_data) \\HAL_I2C_Mem_Read(&hi2c1,dev_addr,reg_addr,I2C_MEMADD_SIZE_8BIT,p_data,data_size,0x100)#define delay_ms HAL_Delay#define get_ms(p) do{*p = HAL_GetTick();}while(0)#define log_i(...) do {} while (0)#define log_e(...) do {} while (0)/* labs is already defined by TI\'s toolchain. *//* fabs is for doubles. fabsf is for floats. */#define fabs fabsf#define min(a,b) ((a<b)?a:b)
继续找到下面代码然后删了
#ifndef EMPL_TARGET_STM32F4 if (int_param) reg_int_cb(int_param);#endif
继续找到.addr并改为0xd0
2.打开inv.mpu.h
删掉下面代码
加入下面代码
struct int_param_s { void *arg;};
3.打开inv_mpu_dmp_motion_driver.c文件
删掉27到77行的代码
加入下面代码
#include \"main.h\"extern I2C_HandleTypeDef hi2c1;#define delay_ms HAL_Delay#define get_ms(p) do{*p = HAL_GetTick();}while(0)#define log_i(...) do {} while (0)#define log_e(...) do {} while (0)
找到并修改
__NOP();
然后编译一下,
到这里就移植好了,现在驱动一下MPU6050
四、驱动MPU6050
根据指定IO接入F103c8t6
1.在主函数加入头文件
#include \"mpu6050.h\"
2.在mian函数里面加入下面代码
int ret=0;do{ ret=MPU6050_DMP_init(); printf(\"ret=%d\\n\",ret);}while(ret);
代码作用:初始化mpu6050,如果初始化不通过就一直初始化直到成功:
可以用串口看一下ret的值,如果是0,就说明初始化成功,如果是其他值,说明不成功,根据返回值然后修改
3.定义变量
float pitch,yaw,roll;
4.获取角度信息打印
MPU6050_DMP_Get_Date(&pitch,&roll,&yaw); printf(\"pitch=%f yaw=%f roll=%f\\n\",pitch,roll,yaw);
然后我发现没有角度信息
初始化的返回值是-9
注意:如果成功了后面就不用继续看了
根据返回值去修改
打开
进入这个函数
最后发现删掉下面代码就成功了
大家就根据自己的返回值修改就ok了