赞
踩
硬件工具:ESP32开发板,MPU6050
编译工具:VScode
测试工具:putty0.7.3
烧录工具:flash_download_tool_v3.8.5。下载地址:https://www.espressif.com/zh-hans/support/download/other-tools
MPU6050仅支持I2C通讯,且其主要的串行接口和辅助接口都支持I2C通讯。包括串行数据线(SDA)和串行时钟线(SCL),连接到 I2C 接口的设备可做主设备或从设备。主设备将 Slave 地址传到总线上,从设备用与其匹配的地址来识别主设备。当连接到系统芯片时,MPU6050总是作为从设备。
主设备发出开始标志(S),在地址位(AD)后加上一个R / W位,0为写,1为读。
代码如下:
uint8_t MPU_Write_Byte(uint8_t reg, uint8_t data) { esp_err_t error; i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); //开始 error = i2c_master_write_byte(cmd, (MPU_ADDR << 1) | I2C_MASTER_WRITE, 1); //器件地址 if(error != ESP_OK) return 1; error = i2c_master_write_byte(cmd, reg, 1); //寄存器地址 if(error != ESP_OK) return 1; error = i2c_master_write_byte(cmd, data, 1); //写入数据 if(error != ESP_OK) return 1; i2c_master_stop(cmd); //结束 i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); return 0; }
主设备发一个开始信号(下图中为第二个“S”信号),然后发送从设备地址位和一个读数据位(AD+R)。作为从设备的 MPU-60X0 产生应答信号并开始发送寄存器数据。通信以主设备产生的拒绝应答信号(NACK)和结束标志(P)结束。拒绝应答信号(NACK)产生,定义为 SDA 数据在第 9 个时钟周期一直为高。
所有的 SDA 信号变化都要在 SCL 时钟为低电平时进行,除了开始和结束标志。
代码如下:
uint8_t MPU_Read_Byte(uint8_t reg, uint8_t *res) { esp_err_t error; i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); //开始 error = i2c_master_write_byte(cmd, (MPU_ADDR << 1) | I2C_MASTER_WRITE, 1); //器件地址,写 if(error != ESP_OK) return 1; error = i2c_master_write_byte(cmd, reg, 1); //寄存器地址 if(error != ESP_OK) return 1; i2c_master_start(cmd); //开始 error = i2c_master_write_byte(cmd, (MPU_ADDR << 1) | I2C_MASTER_READ, 1); //器件地址,读 if(error != ESP_OK) return 1; error = i2c_master_read_byte(cmd, res, I2C_MASTER_LAST_NACK); //发送数据 if(error != ESP_OK) return 1; i2c_master_stop(cmd); //结束 i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); return 0; }
MPU6050的器件地址根据AD0脚的接法,分两种情况:
如果AD0脚(9脚)接地,IIC地址为 0X68 (不包含最低位).
如果接V3.3,则IIC地址为 0X69 (不包含最低位).
如果不知道AD0脚的接法,也有个办法可以找到器件地址,利用I2C通讯。
在esp32-idf的例工程里可以找到“i2c_tools”工程,(文件在你安装 esp-idf 的子目录:examples\peripherals\i2c\i2c_tools)
修改引脚:
static gpio_num_t i2c_gpio_sda = 18;
static gpio_num_t i2c_gpio_scl = 19;
烧录,调试串口,(具体见我的上一篇博客:https://blog.csdn.net/qq_45057368/article/details/117128999)打印出来如下:
可以看见器件地址为0x69。
这里推荐这个博主的工程,传送门,工程还是很齐全的,基本能满足绝大部分需要。
工程下载后,在VScode中编译。这里首先要创建文件夹,然后创建 “main” 文件、 “.vscode” 和一些编译需要的文件等等,比较繁琐,所以我一般喜欢用一招狸猫换太子。
找一个完整工程,例如 “hello_world” 复制该文件夹,改个文件名,如 “hello_test” ,删除里面的 “hello_world_main.c” ,这个是 “太子” 。把我们下载的 “MPU_6050” 文件里的文件复制过来,这个是我们的 “狸猫” 。
当然不可能这么容易就能替换工程,还需要修改编译地址:打开 “CMakeLists.txt” 文件,修改 “**_main.c” 为 “狸猫” 工程的 main 文件。如下:
idf_component_register(SRCS "hello_world_main.c"
INCLUDE_DIRS "")
同样,文件夹的编译文档地址也需要更改为工程文件夹名:
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(hello-test)
这样一个工程文件夹的新建就完毕了。
修改 “MPU6050.h” 的器件地址:
#define MPU_ADDR 0X69
修改 “MPU6050.c” 的引脚:
#define SCL 19 /*!< I2C SCL pin number */
#define SDA 18 /*!< I2C SDA pin number */
这样这个工程就任我们使用了。
先调用个最底层的读取六轴加速度的函数:修改 main.c 文件主函数:
void app_main() { MPU_Init(); uint8_t flag = 1; float pitch, roll,yaw; int ax, ay, az; int gx,gy,gz; int ret,ret1; flag = mpu_dmp_init(); for(;;) { // printf("hello world %d\n", flag); MPU_Get_Accelerometer(&ax, &ay, &az); MPU_Get_Gyroscope(&gx, &gy, &gz); // mpu_dmp_get_data(&pitch, &roll, &yaw); //串口数据读取 printf("ax = %d\n",ax); printf("ay = %d\n",ay); printf("az = %d\n",az); printf("Gx = %d\n",gx); printf("Gy = %d\n",gy); printf("Gz = %d\n",gy); vTaskDelay(1000 / portTICK_RATE_MS); } }
这个工程功能非常丰富,包括卡尔曼滤波降噪,计算三轴角度,其他功能会在以后的博客更新。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。