lxm734974094 发表于 2014-7-7 18:33:39

I2C 陀螺仪mpu6050 求大神指教

最近在做mpu6050,控制小车的转角。用的是DSP C2000,网上找的都是51的程序,移植后采的z轴角速度一直显示239...看网上说要初始化前要复位,但是不会...求大神指教啊。

我采用的是定时器中断,每1ms读取一次值。

#include "DSP28x_Project.h"
#include "GlobalVariable.h"
#include "math.h"

#define SCL GpioDataRegs.GPADAT.bit.GPIO6
#define SDA GpioDataRegs.GPADAT.bit.GPIO7
int CY;

//GpioDataRegs.GPASET.bit.GPIO6
//GpioDataRegs.GPACLEAR.bit.GPIO6



//**************************************
//I2C起始信号
//**************************************
void I2C_Start()
{
        GpioDataRegs.GPASET.bit.GPIO7 = 1;                  //拉高数据线
    GpioDataRegs.GPASET.bit.GPIO6 = 1;                  //拉高时钟线
    DELAY_US(5);               //延时
    GpioDataRegs.GPACLEAR.bit.GPIO7 = 1;                  //产生下降沿
    DELAY_US(5);               //延时
    GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;                  //拉低时钟线
    DELAY_US(5);
}
//**************************************
//I2C停止信号
//**************************************
void I2C_Stop()
{
        GpioDataRegs.GPACLEAR.bit.GPIO7 = 1;                  //拉低数据线
        GpioDataRegs.GPASET.bit.GPIO6 = 1;                  //拉高时钟线
        DELAY_US(5);               //延时
    GpioDataRegs.GPASET.bit.GPIO7 = 1;                  //产生上升沿
    DELAY_US(5);               //延时
}
//**************************************
//I2C发送应答信号
//入口参数:ack (0:ACK 1:NAK)
//**************************************
void I2C_SendACK()
{
        GpioDataRegs.GPASET.bit.GPIO7 = 1;                  //写应答信号
    GpioDataRegs.GPASET.bit.GPIO6 = 1;                  //拉高时钟线
    DELAY_US(5);               //延时
    GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;                  //拉低时钟线
    DELAY_US(5);               //延时
}
//**************************************
//I2C接收应答信号
//**************************************
void I2C_RecvACK()
{
        GpioDataRegs.GPASET.bit.GPIO7 = 1;                  //释放总线
        DELAY_US(5);               //延时
        GpioDataRegs.GPASET.bit.GPIO6 = 1;                  //拉高时钟线
        DELAY_US(5);               //延时
    CY = SDA;                   //读应答信号
        DELAY_US(5);               //延时
    GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;                  //拉低时钟线
    DELAY_US(5);               //延时

}
//**************************************
//向I2C总线发送一个字节数据
//**************************************
void I2C_SendByte(Uchar dat)
{
    Uchar i,k;
    for (i=0; i<8; i++)         //8位计数器
    {
            k=dat & 128;
            if(k==128)
                    GpioDataRegs.GPASET.bit.GPIO7 = 1;
            else
                    GpioDataRegs.GPACLEAR.bit.GPIO7 = 1;//送数据口
      DELAY_US(5);             //延时
            GpioDataRegs.GPASET.bit.GPIO6 = 1;                //拉高时钟线
      DELAY_US(5);             //延时
      GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;                //拉低时钟线
      DELAY_US(5);             //延时
      dat <<= 1;            //移出数据的最高位
    }
    I2C_RecvACK();
}
//**************************************
//从I2C总线接收一个字节数据
//**************************************
Uchar I2C_RecvByte()
{
    Uchar i;
    Uchar dat = 0;
    GpioDataRegs.GPASET.bit.GPIO7 = 1;                  //使能内部上拉,准备读取数据,
    for (i=0; i<8; i++)         //8位计数器
    {
            GpioDataRegs.GPASET.bit.GPIO6 = 1;                //拉高时钟线
            DELAY_US(5);             //延时
            dat <<= 1;
            if(SDA)                                        //如果数据线为高平电平。
                    dat=dat|0x1;//则给缓冲字节的最低位写1。
      GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;                //拉低时钟线
      DELAY_US(5);             //延时
    }
    return dat;
}
//**************************************
//向I2C设备写入一个字节数据
//**************************************
void Single_WriteI2C(Uchar REG_Address,Uchar REG_data)
{
    I2C_Start();                  //起始信号
    I2C_SendByte(SlaveAddress);   //发送设备地址+写信号
    I2C_SendByte(REG_Address);    //内部寄存器地址,
    I2C_SendByte(REG_data);       //内部寄存器数据,
    I2C_Stop();
}

//**************************************
//从I2C设备读取一个字节数据
//**************************************
Uchar Single_ReadI2C(Uchar REG_Address)
{
        Uchar REG_data;
        I2C_Start();                   //起始信号
        I2C_SendByte(SlaveAddress);    //发送设备地址+写信号
        I2C_SendByte(REG_Address);   //发送存储单元地址,从0开始
        I2C_Start();                   //起始信号
        I2C_SendByte(SlaveAddress+1);//发送设备地址+读信号
        REG_data=I2C_RecvByte();       //读出寄存器数据
        I2C_SendACK();                //接收应答信号
        I2C_Stop();                  //停止信号
        return REG_data;
}
//**************************************
//初始化MPU6050
//**************************************
void InitMPU6050()
{
        Single_WriteI2C(PWR_MGMT_1, 0x00);        //解除休眠状态
        Single_WriteI2C(SMPLRT_DIV, 0x07);
        Single_WriteI2C(CONFIG, 0x06);
        Single_WriteI2C(GYRO_CONFIG, 0x18);
        Single_WriteI2C(ACCEL_CONFIG, 0x01);
}
//**************************************
//合成数据
//**************************************
int GetData(Uchar REG_Address)
{
        Uchar H,L;
        H=Single_ReadI2C(REG_Address);
        L=Single_ReadI2C(REG_Address+1);
        return (H<<8)+L;   //合成数据
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
interrupt voidTINT0_ISR(void)      // CPU-Timer 0
{
        float Angle = 0;
        CpuTimer0Regs.TCR.bit.TSS = 1; //0开始,1停止计数
        CpuTimer0Regs.TCR.bit.TRB = 1; //reload
        opaa=GetData(GYRO_ZOUT_H);

        Angle =Angle+( opaa * 1000 * 3.3 * 1.0 / (2 * 1024));//AD每读数实际角速度值 传感器资料为2mv为1度/秒
//        Angle = Angle / 1000;//每1ms取一次数据,每次取的角速度单为1000ms/度,1000/1=1000,积分后的角度需除以50,如要提高分辨率,需把此值放大,即采集时间间隔缩小
}

飞扬琴声 发表于 2014-8-10 21:21:20

同求啊,坛友

默默七 发表于 2014-8-19 17:00:46

软的I2C很好调的。你注意下引脚定义这些是否正确

596142041 发表于 2014-8-19 17:21:26

为啥不用硬件IIC呢?你是用的2812?
页: [1]
查看完整版本: I2C 陀螺仪mpu6050 求大神指教