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,如要提高分辨率,需把此值放大,即采集时间间隔缩小
} 同求啊,坛友 软的I2C很好调的。你注意下引脚定义这些是否正确 为啥不用硬件IIC呢?你是用的2812?
页:
[1]