基于DSP28335的MPU6050传感器IIC通信与原始数据读取实现
一、硬件连接与配置
-
硬件连接
MPU6050引脚 DSP28335引脚 功能说明 SDAGPIO33 IIC数据线 SCLGPIO32 IIC时钟线 VCC3.3V 电源 GNDGND 地 -
关键参数
-
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
六、扩展功能
-
DMP姿态解算
- 启用MPU6050的DMP协处理器,直接输出欧拉角
MPU6050_WriteReg(MPU6050_USER_CTRL, 0x01); // 启用DMP -
多传感器融合
- 结合磁力计数据实现九轴融合(需扩展IIC总线)

浙公网安备 33010602011771号