MPU6050_Reg.h
这是MPU6050常用寄存器的值在此文件中定义出来
#ifndef __MPU6050_REG_H
#define __MPU6050_REG_H
#define MPU6050_SMPLRT_DIV 0x19
#define MPU6050_CONFIG 0x1A
#define MPU6050_GYRO_CONFIG 0x1B
#define MPU6050_ACCEL_CONFIG 0x1C
#define MPU6050_ACCEL_XOUT_H 0x3B
#define MPU6050_ACCEL_XOUT_L 0x3C
#define MPU6050_ACCEL_YOUT_H 0x3D
#define MPU6050_ACCEL_YOUT_L 0x3E
#define MPU6050_ACCEL_ZOUT_H 0x3F
#define MPU6050_ACCEL_ZOUT_L 0x40
#define MPU6050_TEMP_OUT_H 0x41
#define MPU6050_TEMP_OUT_L 0x42
#define MPU6050_GYRO_XOUT_H 0x43
#define MPU6050_GYRO_XOUT_L 0x44
#define MPU6050_GYRO_YOUT_H 0x45
#define MPU6050_GYRO_YOUT_L 0x46
#define MPU6050_GYRO_ZOUT_H 0x47
#define MPU6050_GYRO_ZOUT_L 0x48
#define MPU6050_PWR_MGMT_1 0x6B
#define MPU6050_PWR_MGMT_2 0x6C
#define MPU6050_WHO_AM_I 0x75
#endif
iic.h
i2c文件中封装了5个函数,分别是ESP32硬件的初始化
指定从设备寄存器地址写和指定从设备地址读
#ifndef __I2C_H__
#define __I2C_H_
#include"stdint.h"
#include"esp_err.h"
void i2c_master_init();
esp_err_t i2c_master_write_slave(uint8_t slave_addr, uint8_t *data, size_t data_len);
esp_err_t i2c_master_read_slave(uint8_t slave_addr, uint8_t *data, size_t data_len);
esp_err_t i2c_master_write_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t data);
esp_err_t i2c_master_read_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t data);
#endif
iic.c
#include "driver/i2c.h"
#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "mpu6050_Reg.h"
#define I2C_MASTER_SCL_IO 19 // GPIO number for I2C master clock
#define I2C_MASTER_SDA_IO 18 // GPIO number for I2C master data
#define I2C_MASTER_NUM I2C_NUM_0 // I2C port number
#define I2C_MASTER_FREQ_HZ 100000 // I2C master clock frequency
#define I2C_MASTER_TX_BUF_DISABLE 0 // I2C master doesn't need buffer
#define I2C_MASTER_RX_BUF_DISABLE 0 // I2C master doesn't need buffer
#define I2C_MASTER_TIMEOUT_MS 1000 // I2C master timeout in milliseconds
static const char *TAG = "I2C_DRIVER";
// /**
// * @brief Initialize I2C master
// */
void i2c_master_init()
{
int i2c_master_port = I2C_MASTER_NUM;
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.scl_io_num = I2C_MASTER_SCL_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ,
};
//IIC控制器编号i2c_master_port
i2c_param_config(i2c_master_port, &conf);
i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}
// /**
// * @brief Write data to I2C slave
// *
// * @param slave_addr I2C slave address
// * @param data Pointer to data bufferdata
// * @param data_len Length of data in bytes
// * @return esp_err_t ESP_OK on success, otherwise an error code
// */
// //slave_addr 从设备地址
esp_err_t i2c_master_write_slave(uint8_t slave_addr, uint8_t *data, size_t data_len)
{
int ret;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
// i2c起始信号
i2c_master_start(cmd);
// i2c发送地址
i2c_master_write_byte(cmd, (slave_addr << 1) | I2C_MASTER_WRITE, true);
// i2c发送数据
i2c_master_write(cmd, data, data_len, true);
// i2c停止信号
i2c_master_stop(cmd);
// 发送命令,这个函数是真正实现上面代码内容的函数
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, I2C_MASTER_TIMEOUT_MS/portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
return ret;
}
// /**
// * @brief Read data from I2C slave
// *
// * @param slave_addr I2C slave address
// * @param data Pointer to data buffer
// * @param data_len Length of data in bytes
// * @return esp_err_t ESP_OK on success, otherwise an error code
// */
esp_err_t i2c_master_read_slave(uint8_t slave_addr, uint8_t *data, size_t data_len)
{
int ret;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (slave_addr << 1) | I2C_MASTER_READ, true);
if (data_len > 1) {
i2c_master_read(cmd, data, data_len - 1, I2C_MASTER_ACK);
}
i2c_master_read_byte(cmd, data + data_len - 1, I2C_MASTER_NACK);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS );
i2c_cmd_link_delete(cmd);
return ret;
}
//指定从机寄存器地址写
/*
参数:
slave_addr:从设备地址
reg_addr:从设备寄存器地址
data:要写入的数据
返回值为ESP_OK时表示写入成功
*/
esp_err_t i2c_master_write_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t data)
{
int ret;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
// 写从机地址
ret=i2c_master_write_byte(cmd, (slave_addr << 1) | I2C_MASTER_WRITE, true);
if(ret!= ESP_OK)
{
ESP_LOGE(TAG, "I2C write slaver address failed: %d", ret);
}
// 写从机寄存器地址
ret=i2c_master_write_byte(cmd, reg_addr, true);
if(ret!= ESP_OK)
{
ESP_LOGE(TAG, "I2C write slaver reg failed: %d", ret);
}
// 写数据
ret=i2c_master_write_byte(cmd, data, true);
if(ret!= ESP_OK)
{
ESP_LOGE(TAG, "I2C write slaver regdata failed: %d", ret);
}
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS );
i2c_cmd_link_delete(cmd);
return ret;
}
//指定从机寄存器地址读
/*
参数:
slave_addr:从设备地址
reg_addr:从设备寄存器地址
*data:读取出来的数据存入此地址
返回值为ESP_OK时表示写入成功
*/
esp_err_t i2c_master_read_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data)
{
int ret;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
// 发送从机地址
ret=i2c_master_write_byte(cmd, (slave_addr << 1) | I2C_MASTER_WRITE, true);
if(ret!= ESP_OK){
ESP_LOGE(TAG, "I2C write slaver address failed: %d", ret);
}
// 写从机寄存器地址
ret=i2c_master_write_byte(cmd, reg_addr, true);
if(ret!= ESP_OK){
ESP_LOGE(TAG, "I2C write slaver reg failed: %d", ret);
}
i2c_master_start(cmd);
// 写从机寄存器地址后读
ret =i2c_master_write_byte(cmd, (slave_addr << 1) | I2C_MASTER_READ, true);
if(ret!= ESP_OK){
ESP_LOGE(TAG, "I2C write slaver address failed: %d", ret);
}
ret=i2c_master_read_byte(cmd, data, I2C_MASTER_LAST_NACK);
if(ret!= ESP_OK){
ESP_LOGE(TAG, "I2C read slaver regdata failed: %d", ret);
}
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
return ret;
}
// 代码解释:
// i2c_master_init: 初始化I2C总线,设置SCL和SDA引脚,以及I2C时钟频率。
// i2c_master_write_slave: 向I2C从设备写入数据。
// i2c_master_read_slave: 从I2C从设备读取数据。
MPU6050.h
#ifndef __MPU6050_H__
#define __MPU6050_H__
void mpu6050_init();
esp_err_t MPU6050_getID(uint8_t *data);
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ,
int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ);
#endif
MPU6050.c
#include "mpu6050_Reg.h"
#include "myi2c.c"
#include "mpu6050.h"
#define MPU6050_ADDRESS 0x68
void mpu6050_init()
{
//ESP32I2C硬件初始化
i2c_master_init();
//激活MPU6050
uint8_t data=0x01;
//电源管理寄存器1,取消睡眠模式,选择时钟源为X轴陀螺仪
i2c_master_write_reg(MPU6050_ADDRESS,MPU6050_PWR_MGMT_1,data);
//电源管理寄存器2,保持默认值0,所有轴均不待机
data=0x00;
i2c_master_write_reg(MPU6050_ADDRESS,MPU6050_PWR_MGMT_2,data);
//采样率分频寄存器,配置采样率
data=0x09;
i2c_master_write_reg(MPU6050_ADDRESS,MPU6050_SMPLRT_DIV,data);
//配置寄存器,配置DLPF
data=0x06;
i2c_master_write_reg(MPU6050_ADDRESS,MPU6050_CONFIG,data);
data=0x18;
//陀螺仪配置寄存器,选择满量程为±2000°/s
i2c_master_write_reg(MPU6050_ADDRESS,MPU6050_GYRO_CONFIG,data);
//加速度计配置寄存器,选择满量程为±16g
i2c_master_write_reg(MPU6050_ADDRESS, MPU6050_ACCEL_CONFIG, data);
}
//返回WHO_AM_I寄存器的值0x68
esp_err_t MPU6050_getID(uint8_t *data)
{
int ret;
ret=i2c_master_read_reg(MPU6050_ADDRESS,MPU6050_WHO_AM_I,data);
return ret;
}
//读取3轴加速度与角速度
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ,
int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{
uint8_t DataH, DataL; //定义数据高8位和低8位的变量
i2c_master_read_reg(MPU6050_ADDRESS,MPU6050_ACCEL_XOUT_H,&DataH); //读取加速度计X轴的高8位数据
i2c_master_read_reg(MPU6050_ADDRESS,MPU6050_ACCEL_XOUT_L,&DataL); //读取加速度计X轴的低8位数据
*AccX = (DataH << 8) | DataL; //数据拼接,通过输出参数返回
i2c_master_read_reg(MPU6050_ADDRESS,MPU6050_ACCEL_YOUT_H,&DataH); //读取加速度计Y轴的高8位数据
i2c_master_read_reg(MPU6050_ADDRESS,MPU6050_ACCEL_YOUT_L,&DataL);
*AccY = (DataH << 8) | DataL; //数据拼接,通过输出参数返回
i2c_master_read_reg(MPU6050_ADDRESS,MPU6050_ACCEL_ZOUT_H,&DataH);
i2c_master_read_reg(MPU6050_ADDRESS,MPU6050_ACCEL_ZOUT_L,&DataL);
//读取加速度计Z轴的高8位数据
//读取加速度计Z轴的低8位数据
*AccZ = (DataH << 8) | DataL; //数据拼接,通过输出参数返回
i2c_master_read_reg(MPU6050_ADDRESS,MPU6050_GYRO_XOUT_H,&DataH);
i2c_master_read_reg(MPU6050_ADDRESS,MPU6050_GYRO_XOUT_L,&DataL);
*GyroX = (DataH << 8) | DataL;
i2c_master_read_reg(MPU6050_ADDRESS,MPU6050_GYRO_YOUT_H,&DataH);
i2c_master_read_reg(MPU6050_ADDRESS,MPU6050_GYRO_YOUT_L,&DataL);
*GyroY = (DataH << 8) | DataL;
i2c_master_read_reg(MPU6050_ADDRESS,MPU6050_GYRO_ZOUT_H,&DataH);
i2c_master_read_reg(MPU6050_ADDRESS,MPU6050_GYRO_ZOUT_L,&DataL);
*GyroZ = (DataH << 8) | DataL;
// DataH = MPU6050_ReadReg(MPU6050_GYRO_XOUT_H); //读取陀螺仪X轴的高8位数据
// DataL = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L); //读取陀螺仪X轴的低8位数据
// *GyroX = (DataH << 8) | DataL; //数据拼接,通过输出参数返回
// DataH = MPU6050_ReadReg(MPU6050_GYRO_YOUT_H); //读取陀螺仪Y轴的高8位数据
// DataL = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L); //读取陀螺仪Y轴的低8位数据
// *GyroY = (DataH << 8) | DataL; //数据拼接,通过输出参数返回
// DataH = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H); //读取陀螺仪Z轴的高8位数据
// DataL = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L); //读取陀螺仪Z轴的低8位数据
// *GyroZ = (DataH << 8) | DataL; //数据拼接,通过输出参数返回
}