基于DSP28335的MPU6050传感器IIC通信与原始数据读取实现

一、硬件连接与配置

  1. 硬件连接

    MPU6050引脚 DSP28335引脚 功能说明
    SDA GPIO33 IIC数据线
    SCL GPIO32 IIC时钟线
    VCC 3.3V 电源
    GND GND
  2. 关键参数

    • IIC地址0x68(AD0接GND时)

    • 采样率:1kHz(通过SMPLRT_DIV寄存器配置)

    • 量程:加速度±2g,陀螺仪±2000°/s(默认配置)


二、IIC驱动代码实现

1. IIC初始化
#define MPU6050_ADDR 0x68  // 7位地址(AD0=GND)
#define I2C_BASE_ADDR 0x00 // I2C模块基地址(根据实际配置)

// GPIO配置(硬件IIC模式)
void I2C_GPIO_Init() {
    EALLOW;
    GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 2;  // SCL设为IIC功能
    GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 2;  // SDA设为IIC功能
    GpioCtrlRegs.GPBDIR.bit.GPIO32 = 0;   // SCL输入/输出模式
    GpioCtrlRegs.GPBDIR.bit.GPIO33 = 0;   // SDA输入/输出模式
    EDIS;
}

// IIC模块初始化
void I2C_Init() {
    I2C_GPIO_Init();
    
    // 配置I2C参数(400kHz时钟)
    SysCtrlRegs.PCLKCR3.bit.I2CAEN = 1;   // 使能I2C模块
    I2caRegs.I2CSAR = MPU6050_ADDR << 1;  // 7位地址左移1位(含R/W位)
    I2caRegs.I2CPSC.all = 15;             // 预分频器(150MHz/16=9.375MHz)
    I2caRegs.I2CCLKL = 10;                // 低电平时间(10个时钟周期)
    I2caRegs.I2CCLKH = 10;                // 高电平时间(10个时钟周期)
    I2caRegs.I2CIER.bit.ACK = 1;          // 使能ACK中断
    I2caRegs.I2CFFTX.all = 0x8000;        // 启用FIFO模式
    I2caRegs.I2CFFRX.all = 0x8000;        // 启用接收FIFO
}
2. IIC读写函数
// 发送一个字节
Uint16 I2C_WriteByte(Uint8 data) {
    I2caRegs.I2CDXR = data;          // 写入数据寄存器
    while(I2caRegs.I2CSTR.bit.TXEMPTY == 0);  // 等待发送完成
    return I2caRegs.I2CSTR.bit.I2COAR; // 返回状态
}

// 接收一个字节
Uint8 I2C_ReadByte(Uint8 ack) {
    while(I2caRegs.I2CSTR.bit.RXFULL == 0);  // 等待接收完成
    Uint8 data = I2caRegs.I2CDRR;            // 读取数据寄存器
    if(ack) I2caRegs.I2CCNT.bit.RXACK = 1;   // 发送ACK
    else I2caRegs.I2CCNT.bit.RXACK = 0;      // 发送NACK
    return data;
}

// 读取MPU6050寄存器
void MPU6050_ReadRegs(Uint8 regAddr, Uint8 *buf, Uint16 len) {
    I2C_WriteByte(regAddr);          // 发送寄存器地址
    for(Uint16 i=0; i<len; i++) {
        buf[i] = I2C_ReadByte(1);    // 连续读取并发送ACK
    }
}

三、MPU6050数据读取流程

1. 寄存器配置
// 解除休眠模式
void MPU6050_WakeUp() {
    MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x00);  // 清除SLEEP位
}

// 配置传感器量程
void MPU6050_Config() {
    MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18);  // ±2000°/s
    MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18); // ±16g
    MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x00);   // 1kHz采样率
}
2. 原始数据读取
// 读取加速度计数据(16位补码)
void MPU6050_GetAccel(int16_t *ax, int16_t *ay, int16_t *az) {
    Uint8 buf[6];
    MPU6050_ReadRegs(MPU6050_ACCEL_XOUT_H, buf, 6);
    *ax = (buf[0]<<8) | buf[1];
    *ay = (buf[2]<<8) | buf[3];
    *az = (buf[4]<<8) | buf[5];
}

// 读取陀螺仪数据(16位补码)
void MPU6050_GetGyro(int16_t *gx, int16_t *gy, int16_t *gz) {
    Uint8 buf[6];
    MPU6050_ReadRegs(MPU6050_GYRO_XOUT_H, buf, 6);
    *gx = (buf[0]<<8) | buf[1];
    *gy = (buf[2]<<8) | buf[3];
    *gz = (buf[4]<<8) | buf[5];
}

四、数据处理与校准

1. 数据解析
// 将原始数据转换为物理值(加速度:m/s²,陀螺仪:°/s)
void ConvertRawData(int16_t raw, float *value, float scale) {
    *value = raw * scale;
}

// 示例:加速度计算(±2g → ±16384 LSB/g)
float accel_scale = 9.81 / 16384.0f;
ConvertRawData(ax, &accel_x, accel_scale);
2. 数字滤波
// 移动平均滤波(窗口大小5)
#define FILTER_SIZE 5
static int16_t accel_buffer[3][FILTER_SIZE] = {0};
static Uint8 index = 0;

void FilterAccel(int16_t *raw, int16_t *filtered) {
    for(int i=0; i<3; i++) {
        accel_buffer[i][index] = raw[i];
        filtered[i] = 0;
        for(int j=0; j<FILTER_SIZE; j++) {
            filtered[i] += accel_buffer[i][j];
        }
        filtered[i] /= FILTER_SIZE;
    }
    index = (index + 1) % FILTER_SIZE;
}

五、完整代码示例

#include "DSP2833x_Device.h"
#include "MPU6050.h"

void main() {
    InitSysCtrl();      // 初始化系统时钟
    I2C_Init();         // 初始化IIC
    MPU6050_WakeUp();   // 唤醒MPU6050
    MPU6050_Config();   // 配置传感器

    int16_t ax, ay, az, gx, gy, gz;
    float accel_x, accel_y, accel_z;

    while(1) {
        MPU6050_GetAccel(&ax, &ay, &az);
        MPU6050_GetGyro(&gx, &gy, &gz);
        
        // 数据滤波
        FilterAccel(ax, &accel_x);
        
        // 输出结果
        printf("Accel: %.2f m/s², Gyro: %.2f °/s\n", accel_x, gx/131.0f);
        
        DELAY_US(1000000);  // 1秒间隔
    }
}

参考代码 基于dsp28335,利用iic协议读取mpu6050传感器的原始值 www.youwenfan.com/contentcnr/56328.html

六、扩展功能

  1. DMP姿态解算

    • 启用MPU6050的DMP协处理器,直接输出欧拉角
    MPU6050_WriteReg(MPU6050_USER_CTRL, 0x01);  // 启用DMP
    
  2. 多传感器融合

    • 结合磁力计数据实现九轴融合(需扩展IIC总线)
posted @ 2026-03-06 11:28  风一直那个吹  阅读(1)  评论(0)    收藏  举报