用模拟I2C读取MP6050,读取WHO_AM_I寄存器的值为0,很烦人!!!!
模拟I2C
/*******************************************************************************
* Function Name : I2C_GPIO_Config
* Description : Configration Simulation IIC GPIO
* Input : None
* Output : None
* Return : None
****************************************************************************** */
void I2C_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_GPIO_I2C, ENABLE); //使能GPIOB时钟
GPIO_InitStructure.GPIO_Pin = SCL_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIO_I2C, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SDA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIO_I2C, &GPIO_InitStructure);
delay(0XFFF);
}
/*******************************************************************************
* Function Name : I2C_delay
* Description : Simulation IIC Timing series delay
* Input : None
* Output : None
* Return : None
****************************************************************************** */
void I2C_delay(void)
{
__NOP();
}
void delay5ms(void)
{
int i=5000;
while(i)
{
i--;
}
}
/*******************************************************************************
* Function Name : I2C_Start
* Description : Master Start Simulation IIC Communication
* Input : None
* Output : None
* Return : Wheather Start
****************************************************************************** */
uint16_t I2C_Start(void)
{
SDA_H;
SCL_H;
I2C_delay();
if(!SDA_read)return FALSE; //SDA线为低电平则总线忙,退出
SDA_L;
I2C_delay();
if(SDA_read) return FALSE; //SDA线为高电平则总线出错,退出
SDA_L;
I2C_delay();
return TRUE;
}
/*******************************************************************************
* Function Name : I2C_Stop
* Description : Master Stop Simulation IIC Communication
* Input : None
* Output : None
* Return : None
****************************************************************************** */
void I2C_Stop(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SDA_H;
I2C_delay();
}
/*******************************************************************************
* Function Name : I2C_Ack
* Description : Master Send Acknowledge Single
* Input : None
* Output : None
* Return : None
****************************************************************************** */
void I2C_Ack(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
/*******************************************************************************
* Function Name : I2C_NoAck
* Description : Master Send No Acknowledge Single
* Input : None
* Output : None
* Return : None
****************************************************************************** */
void I2C_NoAck(void)
{
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
/*******************************************************************************
* Function Name : I2C_WaitAck
* Description : Master Reserive Slave Acknowledge Single
* Input : None
* Output : None
* Return : Wheather Reserive Slave Acknowledge Single
****************************************************************************** */
uint16_t I2C_WaitAck(void) //返回为:=1有ACK,=0无ACK
{
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
if(SDA_read)
{
SCL_L;
I2C_delay();
return FALSE;
}
SCL_L;
I2C_delay();
return TRUE;
}
/*******************************************************************************
* Function Name : I2C_SendByte
* Description : Master Send a Byte to Slave
* Input : Will Send Date
* Output : None
* Return : None
****************************************************************************** */
void I2C_SendByte(unsigned char SendByte) //数据从高位到低位//
{
u8 i=8;
while(i--)
{
SCL_L;
I2C_delay();
if(SendByte&0x80)
SDA_H;
else
SDA_L;
SendByte<<=1;
I2C_delay();
SCL_H;
I2C_delay();
}
SCL_L;
}
/*******************************************************************************
* Function Name : I2C_RadeByte
* Description : Master Reserive a Byte From Slave
* Input : None
* Output : None
* Return : Date From Slave
****************************************************************************** */
unsigned char I2C_RadeByte(void) //数据从高位到低位//
{
u8 i=8;
u8 ReceiveByte=0;
SDA_H;
while(i--)
{
ReceiveByte<<=1;
SCL_L;
I2C_delay();
SCL_H;
I2C_delay();
if(SDA_read)
{
ReceiveByte|=0x01;
}
}
SCL_L;
return ReceiveByte;
}
//ZRX
//单字节写入*******************************************
uint16_t Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data) //void
{
if(!I2C_Start())return FALSE;
I2C_SendByte(SlaveAddress); //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}
I2C_SendByte(REG_Address ); //设置低起始地址
I2C_WaitAck();
I2C_SendByte(REG_data);
I2C_WaitAck();
I2C_Stop();
delay5ms();
return TRUE;
}
//单字节读取*****************************************
unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address)
{
unsigned char REG_data;
if(!I2C_Start())return FALSE;
I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck()){I2C_Stop();return FALSE;}
I2C_SendByte((u8) REG_Address); //设置低起始地址
I2C_WaitAck();
I2C_Start();
I2C_SendByte(SlaveAddress+1);
I2C_WaitAck();
REG_data= I2C_RadeByte();
I2C_NoAck();
I2C_Stop();
//return TRUE;
return REG_data;
}
void I2C_Read(u8 addr_, u8 reg_, u8 len, u8 *buf)
{
u8 i;
// 起始信号
I2C_Start();
// 发送设备地址
I2C_SendByte(addr_);
I2C_WaitAck();
//发送存储单元地址
I2C_SendByte(reg_);
I2C_WaitAck();
// 起始信号
I2C_Start();
//发送设备地址+读信号
I2C_SendByte(addr_+1);
I2C_WaitAck();
for (i=0; i<len; i++) //连续读取6个地址数据,存储中BUF
{
*(buf+i) = I2C_RadeByte(); //BUF[0]存储数据
if (i == len-1) I2C_NoAck(); //最后一个数据需要回NOACK
else I2C_Ack(); //回应ACK
}
I2C_Stop(); //停止信号
I2C_delay();
}
---------------------------------------------------
u8 Init_MPU6050(void)
{
u8 ack;
ack = Single_Read(MPU6050_Address, WHO_AM_I);
if (!ack)
{
printf("初始化MPU6050失败!");
printf("WHO_AM_I = %d",ack);
/*Single_Write(MPU6050_Address,PWR_MGMT_1,0x40);
delay_ms(30);
Single_Write(MPU6050_Address,PWR_MGMT_1,0x00);
return FALSE;*/
}
Single_Write(MPU6050_Address, PWR_MGMT_1, 0x00); //解除休眠状态
Single_Write(MPU6050_Address, SMPLRT_DIV, 0x07);
Single_Write(MPU6050_Address, CONFIGL, MPU6050_DLPF_BW_5); //低通滤波
Single_Write(MPU6050_Address, GYRO_CONFIG, GYRO_FS_1000); //陀螺仪量程 +-1000
Single_Write(MPU6050_Address, ACCEL_CONFIG, ACCEL_FS_4); //加速度量程 +-4G
//printf("h初始化MPU6050成功!
");
return TRUE;
}
void Read_MPU6050()
{
mpu6050_buffer[0] = Single_Read(MPU6050_Address,ACCEL_XOUT_H);
mpu6050_buffer[1] = Single_Read(MPU6050_Address,ACCEL_XOUT_L);
printf("ACCEL_XOUT_H:%d ACCEL_XOUT_L:%d
",mpu6050_buffer[0],mpu6050_buffer[1]);
mpu6050_buffer[2] = Single_Read(MPU6050_Address,ACCEL_YOUT_H);
mpu6050_buffer[3] = Single_Read(MPU6050_Address,ACCEL_YOUT_L);
printf("ACCEL_YOUT_H:%d ACCEL_YOUT_L:%d
",mpu6050_buffer[2],mpu6050_buffer[3]);
mpu6050_buffer[4] = Single_Read(MPU6050_Address,ACCEL_ZOUT_H);
mpu6050_buffer[5] = Single_Read(MPU6050_Address,ACCEL_ZOUT_L);
printf("ACCEL_ZOUT_H:%d ACCEL_ZOUT_L:%d
",mpu6050_buffer[4],mpu6050_buffer[5]);
mpu6050_buffer[6] = Single_Read(MPU6050_Address,TEMP_OUT_H);
mpu6050_buffer[7] = Single_Read(MPU6050_Address,TEMP_OUT_L);
printf("TEMP_OUT_H:%d TEMP_OUT_L:%d
",mpu6050_buffer[6],mpu6050_buffer[7]);
mpu6050_buffer[8] = Single_Read(MPU6050_Address,GYRO_XOUT_H);
mpu6050_buffer[9] = Single_Read(MPU6050_Address,GYRO_XOUT_L);
printf("GYRO_XOUT_H:%d GYRO_XOUT_L:%d
",mpu6050_buffer[8],mpu6050_buffer[9]);
mpu6050_buffer[10] = Single_Read(MPU6050_Address,GYRO_YOUT_H);
mpu6050_buffer[11] = Single_Read(MPU6050_Address,GYRO_YOUT_L);
printf("GYRO_YOUT_H:%d GYRO_YOUT_L:%d
",mpu6050_buffer[10],mpu6050_buffer[11]);
mpu6050_buffer[12] = Single_Read(MPU6050_Address,GYRO_ZOUT_H);
mpu6050_buffer[13] = Single_Read(MPU6050_Address,GYRO_ZOUT_L);
printf("GYRO_ZOUT_H:%d GYRO_ZOUT_L:%d
",mpu6050_buffer[12],mpu6050_buffer[13]);
}
好气呀!printf("WHO_AM_I = %d",ack); ack也就是WHO_AM_I寄存器的值一直是0!
我用的是GY——86模块,I2C上还挂了个MS5611,还有个电子罗盘挂在MPU6050的辅助I2C上的!
各位帮我看一下吧!折磨我好几天了,谢谢了
一周热门 更多>