当前位置: 首页 > web >正文

CCS-MSPM0G3507-7-模块篇-MPU6050的基本使用

前言

本篇我们接收对MPU6050的基本使用,获取ID,通过IIC协议获取寄存器的值,至于高级滤波算法,比如卡尔曼滤波,或者上面的,后面再更新

基本配置

最好选择PA0和PA1,5V开漏

然后给上代码

MPU6050.c

#include "MPU6050.h"
#include "delay.h"// I2C通信相关的静态函数定义
// 设置 SCL 引脚电平,并添加延时
static void IIC_SCL_(uint8_t state)
{if (state)DL_GPIO_setPins(SOFT_IIC_SCL_PORT, SOFT_IIC_SCL_PIN);elseDL_GPIO_clearPins(SOFT_IIC_SCL_PORT, SOFT_IIC_SCL_PIN);delay_us(5);
}// 设置 SDA 引脚电平,并添加延时
static void IIC_SDA_(uint8_t state)
{DL_GPIO_initDigitalOutput(MPU6050_SDA_IOMUX);if (state)DL_GPIO_setPins(SOFT_IIC_SDA_PORT, SOFT_IIC_SDA_PIN);elseDL_GPIO_clearPins(SOFT_IIC_SDA_PORT, SOFT_IIC_SDA_PIN);delay_us(5);
}// 读取 SDA 引脚电平
static uint8_t IIC_SDA_Read(void)
{DL_GPIO_initDigitalInputFeatures(MPU6050_SDA_input,DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_NONE,DL_GPIO_HYSTERESIS_DISABLE, DL_GPIO_WAKEUP_DISABLE);return DL_GPIO_readPins(SOFT_IIC_SDA_PORT, SOFT_IIC_SDA_PIN);
}// I2C 初始化
static void IIC_Init(void)
{// 初始状态:SCL 和 SDA 都为高电平IIC_SCL_(1);IIC_SDA_(1);
}// 发送起始信号
static void IIC_Start(void)
{IIC_SDA_(1);IIC_SCL_(1);IIC_SDA_(0);IIC_SCL_(0);
}// 发送停止信号
static void IIC_Stop(void)
{IIC_SCL_(0);IIC_SDA_(0);IIC_SCL_(1);IIC_SDA_(1);
}// 发送一个字节
static void IIC_SendByte(uint8_t data)
{uint8_t i;for (i = 0; i < 8; i++){IIC_SDA_((data & 0x80) >> 7);data <<= 1;IIC_SCL_(1);IIC_SCL_(0);}
}// 接收一个字节
static uint8_t IIC_ReceiveByte(uint8_t ack)
{uint8_t i, data = 0;IIC_SDA_(1); // 释放 SDA 线for (i = 0; i < 8; i++){IIC_SCL_(1);data <<= 1;if (IIC_SDA_Read())data |= 0x01;IIC_SCL_(0);}if (ack)IIC_SDA_(0); // 发送应答elseIIC_SDA_(1); // 发送非应答IIC_SCL_(1);IIC_SCL_(0);return data;
}// 等待应答信号
static uint8_t IIC_WaitAck(void)
{uint8_t ack;IIC_SDA_(1);IIC_SCL_(1);ack = IIC_SDA_Read();IIC_SCL_(0);return ack;
}// 向 MPU6050 写入一个字节数据
static void IIC_Write_REG(uint8_t addr, uint8_t reg, uint8_t data)
{IIC_Start();IIC_SendByte((addr << 1) | 0); // 发送写地址IIC_WaitAck();IIC_SendByte(reg); // 发送寄存器地址IIC_WaitAck();IIC_SendByte(data); // 发送数据IIC_WaitAck();IIC_Stop();
}// 从 MPU6050 读取一个字节数据
static uint8_t IIC_Read_REG(uint8_t Address, uint8_t regaddress)
{uint8_t data;IIC_Start();                    // 发送起始信号IIC_SendByte(Address << 1 | 0); // 发送设备地址和写操作IIC_WaitAck();                  // 等待 ACKIIC_SendByte(regaddress);       // 发送寄存器地址IIC_WaitAck();                  // 等待 ACKIIC_Start();                    // 发送起始信号IIC_SendByte(Address << 1 | 1); // 发送设备地址和读操作IIC_WaitAck();                  // 等待 ACKdata = IIC_ReceiveByte(0);      // 读取数据IIC_Stop();                     // 发送停止信号return data;                    // 返回读取的数据
}// MPU6050 初始化函数
uint8_t MPU6050_Init(void)
{IIC_Init(); // 初始化 I2C 总线// 唤醒 MPU6050IIC_Write_REG(MPU6050_ADDR_AD0_LOW, PWR_MGMT_1, 0x00);delay_ms(100); // 等待唤醒// 设置采样率分频IIC_Write_REG(MPU6050_ADDR_AD0_LOW, SMPLRT_DIV, 0x07);// 设置低通滤波器IIC_Write_REG(MPU6050_ADDR_AD0_LOW, CONFIG, 0x06);// 设置陀螺仪量程 ±250°/sIIC_Write_REG(MPU6050_ADDR_AD0_LOW, GYRO_CONFIG, 0x00);// 设置加速度计量程 ±2gIIC_Write_REG(MPU6050_ADDR_AD0_LOW, ACCEL_CONFIG, 0x00);delay_ms(100); // 等待唤醒return 0;
}// 读取 MPU6050 的设备 ID
uint8_t MPU6050_GetDeviceID(void)
{uint8_t data;data = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, WHO_AM_I); // 读取设备 ID 寄存器return data;                                         // 返回设备 ID
}float MPU6050_GET_Tempure(void)
{int16_t temp;                                       // 用于存储温度传感器数据uint8_t H, L;                                       // 用于存储高字节和低字节的数据H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, TEMP_OUT_H); // 读取温度传感器高字节L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, TEMP_OUT_L); // 读取温度传感器低字节temp = (H << 8) | L;                                // 将高字节和低字节合并为一个 16 位数据return (float)temp / 340.0 + 36.53 - 200;           // 计算温度值并返回
}float MPU6050_GetAccelX(void)
{int16_t accel;                                        // 用于存储加速度传感器数据uint8_t H, L;                                         // 用于存储高字节和低字节的数据H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_XOUT_H); // 读取加速度传感器 X 轴高字节L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_XOUT_L); // 读取加速度传感器 X 轴低字节accel = (H << 8) | L;                                 // 将高字节和低字节合并为一个 16 位数据return ((float)accel / 16384.0 + 1) * 90 - 90;        // 直接返回角度
}float MPU6050_GetAccelY(void)
{int16_t accel;                                        // 用于存储加速度传感器数据uint8_t H, L;                                         // 用于存储高字节和低字节的数据H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_YOUT_H); // 读取加速度传感器 Y 轴高字节L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_YOUT_L); // 读取加速度传感器 Y 轴低字节accel = (H << 8) | L;                                 // 将高字节和低字节合并为一个 16 位数据return ((float)accel / 16384.0 + 1) * 90 - 90;        // 直接返回角度
}float MPU6050_GetAccelZ(void)
{int16_t accel;                                        // 用于存储加速度传感器数据uint8_t H, L;                                         // 用于存储高字节和低字节的数据H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_ZOUT_H); // 读取加速度传感器 Z 轴高字节L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, ACCEL_ZOUT_L); // 读取加速度传感器 Z 轴低字节accel = (H << 8) | L;                                 // 将高字节和低字节合并为一个 16 位数据return ((float)accel / 16384.0 + 1) * 90 - 90;        // 直接返回角度
}float MPU6050_GetAngleX(void)
{int16_t gyro;                                        // 用于存储陀螺仪数据uint8_t H, L;                                        // 用于存储高字节和低字节的数据H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_XOUT_H); // 读取陀螺仪 X 轴高字节L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_XOUT_L); // 读取陀螺仪 X 轴低字节gyro = (H << 8) | L;                                 // 将高字节和低字节合并为一个 16 位数据return (float)gyro / 131.0;                          // 计算角速度值并返回
}float MPU6050_GetAngleY(void)
{int16_t gyro;                                        // 用于存储陀螺仪数据uint8_t H, L;                                        // 用于存储高字节和低字节的数据H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_YOUT_H); // 读取陀螺仪 Y 轴高字节L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_YOUT_L); // 读取陀螺仪 Y 轴低字节gyro = (H << 8) | L;                                 // 将高字节和低字节合并为一个 16 位数据return (float)gyro / 131.0;                          // 计算角速度值并返回
}float MPU6050_GetAngleZ(void)
{int16_t gyro;                                        // 用于存储陀螺仪数据uint8_t H, L;                                        // 用于存储高字节和低字节的数据H = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_ZOUT_H); // 读取陀螺仪 Z 轴高字节L = IIC_Read_REG(MPU6050_ADDR_AD0_LOW, GYRO_ZOUT_L); // 读取陀螺仪 Z 轴低字节gyro = (H << 8) | L;                                 // 将高字节和低字节合并为一个 16 位数据return (float)gyro / 131.0;                          // 计算角速度值并返回
}

MPU6050.h

#ifndef __MPU6050_H
#define __MPU6050_H#include "ti_msp_dl_config.h"// I2C引脚定义
#define SOFT_IIC_SCL_PORT GPIOA        // SCL端口
#define SOFT_IIC_SCL_PIN DL_GPIO_PIN_1 // SCL引脚
#define SOFT_IIC_SDA_PORT GPIOA        // SDA端口
#define SOFT_IIC_SDA_PIN DL_GPIO_PIN_0 // SDA引脚
#define MPU6050_SDA_input   IOMUX_PINCM1  // SDA引脚IOMUX配置// MPU6050寄存器地址定义
#define M_PI 3.14
#define SMPLRT_DIV 0x19   // 采样率分频,典型值:0x07(125Hz) */
#define CONFIG 0x1A       // 低通滤波频率,典型值:0x06(5Hz) */
#define GYRO_CONFIG 0x1B  // 陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s) */
#define ACCEL_CONFIG 0x1C // 加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz) */#define ACCEL_XOUT_H 0x3B // 存储最近的X轴、Y轴、Z轴加速度感应器的测量值 */
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40#define TEMP_OUT_H 0x41 // 存储的最近温度传感器的测量值 */
#define TEMP_OUT_L 0x42#define GYRO_XOUT_H 0x43 // 存储最近的X轴、Y轴、Z轴陀螺仪感应器的测量值 */
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48#define PWR_MGMT_1 0x6B // 电源管理,典型值:0x00(正常启用) */
#define PWR_MGMT_2 0x6C // 电源管理,典型值:0x00(正常启用) */
#define WHO_AM_I 0x75   // IIC地址寄存器(默认数值0x68,只读) */// HAL库的读写只需要使用7位地址
#define MPU6050_ADDR_AD0_LOW 0x68 // AD0低电平时7位地址为0X68 iic写时时发送0XD0
#define MPU6050_ADDR_AD0_HIGH 0x69// 函数声明
uint8_t MPU6050_Init(void);
uint8_t MPU6050_GetDeviceID(void);
float MPU6050_GET_Tempure(void);
float MPU6050_GetAccelX(void);
float MPU6050_GetAccelY(void);
float MPU6050_GetAccelZ(void);
float MPU6050_GetAngleX(void);
float MPU6050_GetAngleY(void);
float MPU6050_GetAngleZ(void);#endif /* __MPU6050_H */

主函数测试

    uart_init();uart_send_string("=== MPU6050 Test Program ===\r\n");char buf[100];MPU6050_Init();uint8_t id = MPU6050_GetDeviceID();sprintf(buf, "MPU6050 ID: %x\r\n", id);uart_send_string(buf);while (1){//sprintf(buf, "Acc: %.2f, %.2f, %.2f,\r\n", MPU6050_GetAccelX(), MPU6050_GetAccelY(), MPU6050_GetAccelZ());// uart_send_string(buf);sprintf(buf, "Gyro: %.2f, %.2f, %.2f,\r\n",MPU6050_GetAngleX(), MPU6050_GetAngleY(), MPU6050_GetAngleZ());uart_send_string(buf);delay_ms(100);}

http://www.xdnf.cn/news/15434.html

相关文章:

  • 002大模型基础知识
  • 认识String、StringBuffer、StringBuilder
  • vue3 el-select默认选中
  • 【设计模式】策略模式(政策(Policy)模式)
  • 从 Manifest V2 升级到 Manifest V3 的注意事项
  • Cursor三大核心AI功能
  • 详解缓存淘汰策略:LFU
  • JS红宝书pdf完整版
  • mac上BRPC的CMakeLists.txt优化:解决Protobuf路径问题
  • SCTP协议网络编程
  • 【算法】贪心算法:柠檬水找零C++
  • Redis 命令总结
  • SpringBoot3-Flowable7初体验
  • Java 内部类详解:从基础到实战,掌握嵌套类、匿名类与局部类的使用技巧
  • Vivado ILA抓DDR信号(各种IO信号:差分、ISERDES、IOBUFDS等)
  • MYSQL笔记2
  • 4. MyISAM vs InnoDB:深入解析MySQL两大存储引擎
  • 39.Sentinel微服务流量控制组件
  • 论文笔记:AnImitation Learning Approach for Cache Replacement
  • Prometheus Operator:Kubernetes 监控自动化实践
  • 深入解析Hadoop架构设计:原理、组件与应用
  • Java 高级特性实战:反射与动态代理在 spring 中的核心应用
  • ADB 调试日志全攻略:如何开启与关闭 `ADB_TRACE` 日志
  • 面试150 二叉树展开为链表
  • Redis面试精讲 Day 2:Redis数据类型全解析
  • 【操作系统-Day 5】通往内核的唯一桥梁:系统调用 (System Call)
  • 【DVWA系列】——File Upload——low详细教程(webshell工具冰蝎)
  • MySQL SQL语句精要:DDL、DML与DCL的深度探究
  • ROS2---NodeOptions
  • 01.深入理解 Python 中的 if __name__ == “__main__“