MPU9250的开发

功能函数全解

/*
*********************************************************************************************************
*    函 数 名: i2c_Delay
*    功能说明: I2C总线位延迟,最快400KHz
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
static void i2c_Delay(void)
{
    uint8_t i;

    /*
         下面的时间是通过安富莱AX-Pro逻辑分析仪测试得到的。
        CPU主频72MHz时,在内部Flash运行, MDK工程不优化
        循环次数为10时,SCL频率 = 205KHz
        循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us
         循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us
        
    IAR工程编译效率高,不能设置为7
    */
    for (i = 0; i < 10; i++);
}

/*
*********************************************************************************************************
*    函 数 名: i2c_Start
*    功能说明: CPU发起I2C总线启动信号
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
void i2c_Start(void)
{
    /* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */
    I2C_SDA_1();
    I2C_SCL_1();
    i2c_Delay();
    I2C_SDA_0();
    i2c_Delay();
    I2C_SCL_0();
    i2c_Delay();
}

/*
*********************************************************************************************************
*    函 数 名: i2c_Start
*    功能说明: CPU发起I2C总线停止信号
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
void i2c_Stop(void)
{
    /* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */
    I2C_SDA_0();
    I2C_SCL_1();
    i2c_Delay();
    I2C_SDA_1();
}

/*
*********************************************************************************************************
*    函 数 名: i2c_SendByte
*    功能说明: CPU向I2C总线设备发送8bit数据
*    形    参:_ucByte : 等待发送的字节
*    返 回 值: 无
*********************************************************************************************************
*/
void i2c_SendByte(uint8_t _ucByte)
{
    uint8_t i;

    /* 先发送字节的高位bit7 */
    for (i = 0; i < 8; i++)
    {        
        if (_ucByte & 0x80)
        {
            I2C_SDA_1();
        }
        else
        {
            I2C_SDA_0();
        }
        i2c_Delay();
        I2C_SCL_1();
        i2c_Delay();    
        I2C_SCL_0();
        if (i == 7)
        {
             I2C_SDA_1(); // 释放总线
        }
        _ucByte <<= 1;    /* 左移一个bit */
        i2c_Delay();
    }
}

/*
*********************************************************************************************************
*    函 数 名: i2c_ReadByte
*    功能说明: CPU从I2C总线设备读取8bit数据
*    形    参:无
*    返 回 值: 读到的数据
*********************************************************************************************************
*/
uint8_t i2c_ReadByte(u8 ack)
{
    uint8_t i;
    uint8_t value;

    /* 读到第1个bit为数据的bit7 */
    value = 0;
    for (i = 0; i < 8; i++)
    {
        value <<= 1;
        I2C_SCL_1();
        i2c_Delay();
        if (I2C_SDA_READ())
        {
            value++;
        }
        I2C_SCL_0();
        i2c_Delay();
    }
    if(ack==0)
        i2c_NAck();
    else
        i2c_Ack();
    return value;
}

/*
*********************************************************************************************************
*    函 数 名: i2c_WaitAck
*    功能说明: CPU产生一个时钟,并读取器件的ACK应答信号
*    形    参:无
*    返 回 值: 返回0表示正确应答,1表示无器件响应
*********************************************************************************************************
*/
uint8_t i2c_WaitAck(void)
{
    uint8_t re;

    I2C_SDA_1();    /* CPU释放SDA总线 */
    i2c_Delay();
    I2C_SCL_1();    /* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
    i2c_Delay();
    if (I2C_SDA_READ())    /* CPU读取SDA口线状态 */
    {
        re = 1;
    }
    else
    {
        re = 0;
    }
    I2C_SCL_0();
    i2c_Delay();
    return re;
}

/*
*********************************************************************************************************
*    函 数 名: i2c_Ack
*    功能说明: CPU产生一个ACK信号
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
void i2c_Ack(void)
{
    I2C_SDA_0();    /* CPU驱动SDA = 0 */
    i2c_Delay();
    I2C_SCL_1();    /* CPU产生1个时钟 */
    i2c_Delay();
    I2C_SCL_0();
    i2c_Delay();
    I2C_SDA_1();    /* CPU释放SDA总线 */
}

/*
*********************************************************************************************************
*    函 数 名: i2c_NAck
*    功能说明: CPU产生1个NACK信号
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
void i2c_NAck(void)
{
    I2C_SDA_1();    /* CPU驱动SDA = 1 */
    i2c_Delay();
    I2C_SCL_1();    /* CPU产生1个时钟 */
    i2c_Delay();
    I2C_SCL_0();
    i2c_Delay();    
}

/*
*********************************************************************************************************
*    函 数 名: i2c_GPIO_Config
*    功能说明: 配置I2C总线的GPIO,采用模拟IO的方式实现
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
void i2c_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_I2C_PORT, ENABLE);    /* 打开GPIO时钟 */

    GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;      /* 开漏输出 */
    GPIO_Init(GPIO_PORT_I2C, &GPIO_InitStructure);

    /* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 */
    i2c_Stop();
}

/*
*********************************************************************************************************
*    函 数 名: i2c_CheckDevice
*    功能说明: 检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在
*    形    参:_Address:设备的I2C总线地址
*    返 回 值: 返回值 0 表示正确, 返回1表示未探测到
*********************************************************************************************************
*/
uint8_t i2c_CheckDevice(uint8_t _Address)
{
    uint8_t ucAck;

    i2c_GPIO_Config();        /* 配置GPIO */
    
    i2c_Start();        /* 发送启动信号 */

    /* 发送设备地址+读写控制bit(0 = w, 1 = r) bit7 先传 */
    i2c_SendByte(_Address|I2C_WR);
    ucAck = i2c_WaitAck();    /* 检测设备的ACK应答 */

    i2c_Stop();            /* 发送停止信号 */

    return ucAck;
}

void MPU9250_WriteReg(u8 reg_add,u8 reg_dat)
{
    i2c_Start();
    i2c_SendByte(MPU6050_SLAVE_ADDRESS);
    i2c_WaitAck();
    i2c_SendByte(reg_add);
    i2c_WaitAck();
    i2c_SendByte(reg_dat);
    i2c_WaitAck();
    i2c_Stop();
}


/**
  * @brief   从MPU6050寄存器读取数据
  * @param   
  * @retval  
  */
void MPU9250_ReadData(u8 reg_add,unsigned char*Read,u8 num)
{
    unsigned char i;
    
    i2c_Start();
    i2c_SendByte(MPU6050_SLAVE_ADDRESS);
    i2c_WaitAck();
    i2c_SendByte(reg_add);
    i2c_WaitAck();
    
    i2c_Start();
    i2c_SendByte(MPU6050_SLAVE_ADDRESS+1);
    i2c_WaitAck();
    
    for(i=0;i<(num-1);i++){
        *Read=i2c_ReadByte(1);
        Read++;
    }
    *Read=i2c_ReadByte(0);
    i2c_Stop();
}


/**
  * @brief   初始化MPU6050芯片
  * @param   
  * @retval  
  */
void MPU9250_Init(void)
{
  int i=0,j=0;
  //在初始化之前要延时一段时间,若没有延时,则断电后再上电数据可能会出错
  for(i=0;i<1000;i++)
  {
    for(j=0;j<1000;j++)
    {
      ;
    }
  }
    MPU9250_WriteReg(MPU6050_RA_PWR_MGMT_1, 0x00);        //解除休眠状态
    MPU9250_WriteReg(MPU6050_RA_SMPLRT_DIV , 0x07);        //陀螺仪采样率,1KHz
    MPU9250_WriteReg(MPU6050_RA_CONFIG , 0x06);            //低通滤波器的设置,截止频率是1K,带宽是5K
    MPU9250_WriteReg(MPU6050_RA_ACCEL_CONFIG , 0x00);      //配置加速度传感器工作在2G模式,不自检
    MPU9250_WriteReg(MPU6050_RA_GYRO_CONFIG, 0x18);     //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
}

/**
  * @brief   读取MPU6050的ID
  * @param   MPU6050_RA_ACCEL_XOUT_H
  * @retval  MPU6050_RA_WHO_AM_I
  */
uint8_t MPU9250ReadID(void)
{
    unsigned char Re = 0;
    MPU9250_ReadData(MPU6050_RA_WHO_AM_I,&Re,1);    //读器件地址
    if(Re != 0x71)
    {
        printf("MPU6050 dectected error!\r\n检测不到MPU6050模块,请检查模块与开发板的接线");
        return 0;
    }
    else
    {
        printf("MPU6050 ID = %d\r\n",Re);
        return 1;
    }
        
}
/**
  * @brief   读取MPU6050的加速度数据
  * @param   
  * @retval  
  */
void MPU9250ReadAcc(short *accData)
{
    u8 buf[6];
    MPU9250_ReadData(MPU6050_ACC_OUT, buf, 6);
    accData[0] = (buf[0] << 8) | buf[1];
    accData[1] = (buf[2] << 8) | buf[3];
    accData[2] = (buf[4] << 8) | buf[5];
}

/**
  * @brief   读取MPU6050的角加速度数据
  * @param   
  * @retval  
  */
void MPU9250ReadGyro(short *gyroData)
{
    u8 buf[6];
    MPU9250_ReadData(MPU6050_GYRO_OUT,buf,6);
    gyroData[0] = (buf[0] << 8) | buf[1];
    gyroData[1] = (buf[2] << 8) | buf[3];
    gyroData[2] = (buf[4] << 8) | buf[5];
}


/**
  * @brief   读取MPU6050的原始温度数据
  * @param   
  * @retval  
  */
void MPU9250ReadTemp(short *tempData)
{
    u8 buf[2];
    MPU9250_ReadData(MPU6050_RA_TEMP_OUT_H,buf,2);     //读取温度值
    *tempData = (buf[0] << 8) | buf[1];
}


/**
  * @brief   读取MPU6050的温度数据,转化成摄氏度
  * @param   
  * @retval  
  */
void MPU9250_ReturnTemp(float *Temperature)
{
    short temp3;
    u8 buf[2];
    
    MPU9250_ReadData(MPU6050_RA_TEMP_OUT_H,buf,2);     //读取温度值
  temp3= (buf[0] << 8) | buf[1];    
    *Temperature=((double) temp3/340.0)+36.53;

}

以下是实现代码

		MPU9250ReadAcc(Accel);			
				printf("\r\n加速度: %8d%8d%8d    ",Accel[0],Accel[1],Accel[2]);
				MPU9250ReadGyro(Gyro);
				printf("陀螺仪: %8d%8d%8d    ",Gyro[0],Gyro[1],Gyro[2]);
				
				MPU9250_ReturnTemp(&Temp); 
				printf("温度: %8.2f",Temp);

数据还需要进行进一步的计算,其中有有部分数值进行了更改,stm32f1vet6的板子做的实验

加速度:     -396   -7964   13020    陀螺仪:     -363     -54     408    温度:    45.24

加速度:     -324   -8144   12668    陀螺仪:     -172     -21     301    温度:    45.24

加速度:      -56   -7804   12712    陀螺仪:       34       4     201    温度:    45.23

加速度:      -60   -7660   13324    陀螺仪:      245     -14     105    温度:    45.23

加速度:     -400   -8268   13404    陀螺仪:      464     -72     -23    温度:    45.24

加速度:     -216   -7764   13584    陀螺仪:      592     -82    -156    温度:    45.24

加速度:      -24   -7076   14312    陀螺仪:      713     -59    -231    温度:    45.24

加速度:       56   -7620   14624    陀螺仪:      804     -54    -269    温度:    45.24

加速度:      168   -7292   14312    陀螺仪:      864     -72    -356    温度:    45.24

加速度:      604   -5976   14472    陀螺仪:      833     -64    -414    温度:    45.23

加速度:      740   -5928   14832    陀螺仪:      867     -28    -369    温度:    45.24

加速度:      920   -6192   14856    陀螺仪:      896      -2    -272    温度:    45.24

加速度:      996   -5592   15712    陀螺仪:      877       2    -184    温度:    45.24

 

对完整代码文件请关注后续博客

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值