采用软件iic读取的数据,软件iic就暂时不讲了,开搞mpu9250
在网上了解了一些,mpu9250实际上就是mpu6050+磁力计,即有两个器件地址,可以通过设置读取模式来分别读到mpu6050和磁力计的数据。
在网上看到这一片帖子,可以借鉴一点:https://blog.csdn.net/black_yu/article/details/51815049
还有一些前辈的指点
但是,最终还是没有调好,用的是工作时间,所以准备回去调试
莫名奇妙的成功了几次,即mpu9250+ak8963 数据成功读出来了,害得我高兴地上厕所去了,结果一回来又不行了。中间断了一次电。
现在棘手的问题是mpu9250,我没办法写寄存器
以下是这个问题的具体描述
1、mpu9250能读到ID,能读数据。
比如我现在加速度默认的量程是正负2G的,我想换成正负16G的量程时,读出来的数据还是2G的量程范围的值(我通过成功的那几次中才发现的问题)。我去读加速度量程的寄存器,读出来的值就是0x00。因此这个问题也导致我mpu9250没办法设置成passby模式,因此没办法读取磁力计!!!
2、这个iic的时序我是沿用的icm20609的时序这是设置完i6G后,读的加速度config寄存器(仍是2G的配置)
感觉波形是正确的呀,icm20609读的66的,也能修改配置。
下面我也贴一下我的iic代码,初始化代码。
#include "bsp_gpio.h"
#include "app_mpu9250.h"
#include "app\iam20609\app_iam20609.h"
#include "app\iam20609\imu.h"
#include "bsp_simiic.h"
#include "elog.h"
#include "app\connectDT\sendmessage.h"
u8 mpu9250_init_State = mpu9250_init_pre_state;
u8 mpu9250_init_delay = 0x00;
u8 mpu9250_device = 2;
Mpu9250_t mpu9250regdata;
accel_t mpu9250acceldata;
gyro_t mpu9250gyrodata;
magn_t mpu9250magndata;
uint16_T temp;
accel_t mpu9250acceldatashow[5];
gyro_t mpu9250gyrodatashow[5];
accel_t mpu9250accel_adjust[200];
gyro_t mpu9250gyro_adjust[200];
/**
* \brief MPU6050 write single byte
*
* \param address,value
*
* \return 1:write success or 0:write fail
*/
u8 MPU9250_WriteReg(u8 device, u8 address, u8 Value)
{
i2c_Start();
i2c_SendByte(device | I2C_WR);
if (i2c_WaitAck() != 1)
{
goto writesingle_fail;
}
i2c_SendByte(address);
if (i2c_WaitAck() != 1)
{
goto writesingle_fail;
}
i2c_SendByte(Value);
if (i2c_WaitAck() != 1)
{
goto writesingle_fail;
}
i2c_Stop();
return 1;
writesingle_fail:
i2c_Stop();
return 0;
}
/**
* \brief iam20609 read single byte
*
* \param address,value
*
* \return 1:read success or 0:read fail
*/
u8 MPU9250_ReadReg(u8 device, u8 address, u8 * value)
{
i2c_Start();
i2c_SendByte(device | I2C_WR);
if (i2c_WaitAck() != 0)
{
goto readsingle_fail;
}
i2c_SendByte(address);
if (i2c_WaitAck() != 0)
{
goto readsingle_fail;
}
i2c_Start();
i2c_SendByte(device | I2C_RD);
if (i2c_WaitAck() != 0)
{
goto readsingle_fail;
}
*value = i2c_ReadByte();
i2c_NAck();
i2c_Stop();
return 1;
readsingle_fail:
i2c_Stop();
return 0;
}
/**
* \brief iam20609 read bytes
*
* \param address,rxbuff,num
*
* \return 1:read success or 0:read fail
*/
u8 MPU9250_ReadData(u8 device, u8 address, u8 * rxBuff, u8 num)
{
u8 i = 0;
i2c_Start();
i2c_SendByte(device | I2C_WR);
if (i2c_WaitAck() != 0)
{
goto readdata_fail;
}
i2c_SendByte(address);
if (i2c_WaitAck() != 0)
{
goto readdata_fail;
}
i2c_Start();
i2c_SendByte(device | I2C_RD);
if (i2c_WaitAck() != 0)
{
goto readdata_fail;
}
for(i=0; i<(num); i++)
{
*rxBuff = i2c_ReadByte();
if (i != (num - 1))
{
i2c_Ack();
}
else
{
i2c_NAck();
}
rxBuff++;
}
i2c_Stop();
return 1;
readdata_fail:
i2c_Stop();
return 0;
}
/**
* \brief iam20609_readid
*
* \param none
*
* \return none
*/
void MPU9250_ReadID(void)
{
mpu9250regdata.WHO_AM_I_REG = 0x00;
MPU9250_ReadReg(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_WHO_AM_I, &mpu9250regdata.WHO_AM_I_REG);
if(0x71 != mpu9250regdata.WHO_AM_I_REG)
{
mpu9250_device = 0;
// log_e("not found device");
}
else
{
mpu9250_device = 1;
log_i(" device ok");
}
}
void mpu9250_InitState(void)
{
mpu9250_init_State = mpu9250_init_pre_state;
mpu9250_device = DEVICE_INIT;
mpu9250_init_delay = 0;
IMU_init();
}
int8_t MPU9250_Init(void)
{
int8_t mpu9250_init_returnvalue = 0xff;
u8 rest = 0;
switch (mpu9250_init_State)
{
case mpu9250_init_pre_state:
MPU9250_ReadID();
mpu9250_init_State = mpu9250_init_step1_state;
break;
case mpu9250_init_step1_state:
if (mpu9250_init_delay == 0x00)
{
mpu9250_init_delay++;
mpu9250regdata.PWR_MGMT_1_REG = 0x00;
MPU9250_WriteReg(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_PWR_MGMT_1, 0x81);
}
else
{
mpu9250_init_delay++;
if (mpu9250_init_delay > 8) //瀵よ埖妞?160ms
{
mpu9250_init_delay = 0;
mpu9250_init_State = mpu9250_init_step2_state;
}
}
break;
case mpu9250_init_step2_state:
mpu9250_init_delay++;
switch (mpu9250_init_delay)
{
case 0x01:
MPU9250_WriteReg(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_PWR_MGMT_1, MPU6050_CLOCK_PLL_XGYRO);
break;
case 0x02:
MPU9250_WriteReg(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_SMPLRT_DIV, 0x04); //200 Hz
// MPU9250_WriteReg(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_PWR_MGMT_2, 0);
break;
case 0x03:
// MPU9250_WriteReg(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_CONFIG, 0x06);
break;
case 0x04:
MPU9250_WriteReg(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_ACCEL_CONFIG, (MPU6050_ACCEL_FS_16 << 3));//+-2g
// MPU9250_WriteReg(MPU6050_RA_FF_THR, IAM20609_ACCEL_BW_21HZ);/*accel LPF 20HZ*/
break;
case 0x05:
MPU9250_WriteReg(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_GYRO_CONFIG, (MPU6050_GYRO_FS_1000 << 3)); //+-2000dps
// IAM20609_WriteReg(IAM20609_CONFIG_REG,IAM20609_GYRO_BW_20HZ); //gtro and temp LPF
break;
case 0x06:
// MPU9250_WriteReg(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_FF_THR, 0x00);
break;
case 0x07:
// MPU9250_WriteReg(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_USER_CTRL, 0x00);
MPU9250_ReadReg(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_GYRO_CONFIG, (u8 *)&rest);//+-2g
break;
case 0x08:
MPU9250_WriteReg(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_INT_PIN_CFG, 0x02);//set i2c bypass enable pin to true to access magnetometer
break;
case 0x09:
MPU9250_ReadReg(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_INT_PIN_CFG, (u8 *)&rest);//+-2g
if((rest&0x02) != 0x02)
{
mpu9250_init_delay = 0x07;
}
MPU9250_WriteReg(MPU9150_RA_MAG_ADDRESS, AK8963_CNTL2,0x01);//复位器件
MPU9250_WriteReg(MPU9150_RA_MAG_ADDRESS, AK8963_CNTL1,0x11);//设置为16bit模式
mpu9250_init_State = mpu9250_init_step3_state;
break;
default:
break;
}
break;
case mpu9250_init_step3_state:
if(0x48 == InitAK8963())
{
mpu9250_init_State = mpu9250_init_finish_state;
}
break;
case mpu9250_init_finish_state:
mpu9250_init_returnvalue = 0x01;
break;
default:
break;
}
return mpu9250_init_returnvalue;
}
u8 InitAK8963(void)
{
u8 wia = 0;
MPU9250_ReadReg(MPU9150_RA_MAG_ADDRESS, 0x00, (u8 *)&wia);
log_i("ak8963 id = %d ",wia);
return wia;
}
//获取数据
//void GetAK8963Mag(void)
//{
// MPU9250_WriteReg(AK8963_CNTL2,0x01);//复位芯片
// MPU9250_WriteReg(AK8963_CNTL1,0x16);//设置为16bit模式 采样率为100HZ
// while(!AK8963_ReadByte(AK8963_ST1));//等等数据转换完成
// AK8963_ReadData();//连续读取三轴的数据,保存在结构体中
//}
//自我测试模式
//u8 ak8963_Self_test(void)
//{
// AK8963_WriteByte(AK8963_CNTL2,0x01);
// AK8963_WriteByte(AK8963_CNTL1,0x00);//power down
// AK8963_WriteByte(AK8963_ASTC,0x40);//Set self test
// AK8963_WriteByte(AK8963_CNTL1,0x18);//SET Self Mode
// while(!AK8963_ReadByte(AK8963_ST1));
// AK8963_ReadData();
// //usart4.printf("X_Mag=%d,Y_Mag=%d,Z_Mag=%d\r\n",g_tMag.X,g_tMag.Y,g_tMag.Z);
// AK8963_WriteByte(AK8963_ASTC,0x00);//Clear self test
// AK8963_WriteByte(AK8963_CNTL1,0x00);//power down
// AK8963_WriteByte(AK8963_CNTL2,0x01);
// if(((g_tMag.X>=-200)&&(g_tMag.X<=200))&&((g_tMag.Y>=-200)&&(g_tMag.Y<=200))&&((g_tMag.Z>=-3200)&&(g_tMag.Z<=-800)))
// return 0;
// else return 1;
//}
/** Get raw 9-axis motion sensor readings (accel/gyro/compass).
* FUNCTION NOT FULLY IMPLEMENTED YET.
* @param ax 16-bit signed integer container for accelerometer X-axis value
* @param ay 16-bit signed integer container for accelerometer Y-axis value
* @param az 16-bit signed integer container for accelerometer Z-axis value
* @param gx 16-bit signed integer container for gyroscope X-axis value
* @param gy 16-bit signed integer container for gyroscope Y-axis value
* @param gz 16-bit signed integer container for gyroscope Z-axis value
* @param mx 16-bit signed integer container for magnetometer X-axis value
* @param my 16-bit signed integer container for magnetometer Y-axis value
* @param mz 16-bit signed integer container for magnetometer Z-axis value
* @see getMotion6()
* @see getAcceleration()
* @see getRotation()
* @see MPU6050_RA_ACCEL_XOUT_H
*/
void MPU9250_getMotion9(accel_t* acc, gyro_t* gyro, magn_t* magn)
{
u8 reg_data[6];
//get accel and gyro
MPU9250_getMotion6(acc, gyro);
//read mag
// I2Cdev::writeByte(devAddr, MPU6050_RA_INT_PIN_CFG, 0x02);
MPU9250_ReadData(MPU9150_RA_MAG_ADDRESS, MPU9150_RA_MAG_XOUT_L, reg_data, 6);
magn->x = (((int16_t)reg_data[0]) << 8) | reg_data[1];
magn->y = (((int16_t)reg_data[2]) << 8) | reg_data[3];
magn->z = (((int16_t)reg_data[4]) << 8) | reg_data[5];
MPU9250_WriteReg(MPU9150_RA_MAG_ADDRESS, 0x0A, 0x11); //enable the magnetometer
}
/** Get raw 6-axis motion sensor readings (accel/gyro).
* Retrieves all currently available motion sensor values.
* @param ax 16-bit signed integer container for accelerometer X-axis value
* @param ay 16-bit signed integer container for accelerometer Y-axis value
* @param az 16-bit signed integer container for accelerometer Z-axis value
* @param gx 16-bit signed integer container for gyroscope X-axis value
* @param gy 16-bit signed integer container for gyroscope Y-axis value
* @param gz 16-bit signed integer container for gyroscope Z-axis value
* @see getAcceleration()
* @see getRotation()
* @see MPU6050_RA_ACCEL_XOUT_H
*/
void MPU9250_getMotion6(accel_t* acc, gyro_t* gyro)
{
#if 0
u8 reg_data[14];
MPU9250_ReadData(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_ACCEL_XOUT_H, reg_data, 14);
acc->x = (((int16_t)reg_data[0]) << 8) | reg_data[1];
acc->y = (((int16_t)reg_data[2]) << 8) | reg_data[3];
acc->z = (((int16_t)reg_data[4]) << 8) | reg_data[5];
gyro->x = (((int16_t)reg_data[8]) << 8) | reg_data[9];
gyro->y = (((int16_t)reg_data[10]) << 8) | reg_data[11];
gyro->z = (((int16_t)reg_data[12]) << 8) | reg_data[13];
#else
u8 reg_data[6];
MPU9250_ReadData(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_ACCEL_XOUT_H, reg_data, 6);
acc->x = (((int16_t)reg_data[0]) << 8) | reg_data[1];
acc->y = (((int16_t)reg_data[2]) << 8) | reg_data[3];
acc->z = (((int16_t)reg_data[4]) << 8) | reg_data[5];
MPU9250_ReadData(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_GYRO_XOUT_H, reg_data, 6);
gyro->x = (((int16_t)reg_data[0]) << 8) | reg_data[1];
gyro->y = (((int16_t)reg_data[2]) << 8) | reg_data[3];
gyro->z = (((int16_t)reg_data[4]) << 8) | reg_data[5];
#endif
}
void MPU9250_testMotion6(void)
{
u8 reg_data[6];
accel_t acc;
gyro_t gyro;
MPU9250_ReadData(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_ACCEL_XOUT_H, reg_data, 6);
mpu9250acceldata.x = (((int16_t)reg_data[0]) << 8) | reg_data[1];
mpu9250acceldata.y = (((int16_t)reg_data[2]) << 8) | reg_data[3];
mpu9250acceldata.z = (((int16_t)reg_data[4]) << 8) | reg_data[5];
MPU9250_ReadData(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_GYRO_XOUT_H, reg_data, 6);
mpu9250gyrodata.x = (((int16_t)reg_data[0]) << 8) | reg_data[1];
mpu9250gyrodata.y = (((int16_t)reg_data[2]) << 8) | reg_data[3];
mpu9250gyrodata.z = (((int16_t)reg_data[4]) << 8) | reg_data[5];
// log_i("%6d %6d %6d %6d %6d %6d ",acc.x,acc.y,acc.z,gyro.x,gyro.y,gyro.z);
}
void MPU9250_testMotion9(void)
{
u8 reg_data[6];
u8 st1 = 0;
MPU9250_testMotion6();
// MPU9250_ReadReg(MPU9150_RA_MAG_ADDRESS,AK8963_ST1, &st1);
// if(st1)
{
MPU9250_ReadData(MPU9150_RA_MAG_ADDRESS, MPU9150_RA_MAG_XOUT_L, reg_data, 6);
mpu9250magndata.x = (((int16_t)reg_data[0]) << 8) | reg_data[1];
mpu9250magndata.y = (((int16_t)reg_data[2]) << 8) | reg_data[3];
mpu9250magndata.z = (((int16_t)reg_data[4]) << 8) | reg_data[5];
}
// MPU9250_WriteReg(MPU9150_RA_MAG_ADDRESS, AK8963_CNTL2,0x01);
MPU9250_WriteReg(MPU9150_RA_MAG_ADDRESS,AK8963_CNTL1,0x11);//设置为16bit模式 采样率为100HZ
// log_i("%6d %6d %6d %6d %6d %6d ",acc.x,acc.y,acc.z,gyro.x,gyro.y,gyro.z);
// MPU9250_WriteReg(MPU9150_RA_MAG_ADDRESS, 0x0A, 0x01); //enable the magnetometer
// delay(10);
// MPU9250_WriteReg(MPU9150_RA_MAG_ADDRESS,AK8963_CNTL1,0x11);//每读一次,ak8963自动进入powerdown模式,这里需要重新设定单测量模式
}
void MPU9250_shelldata(void)
{
// log_i("%6d %6d %6d ",mpu9250acceldata.x,mpu9250acceldata.y,mpu9250acceldata.z);
// ANO_DT_Send_Senser(mpu9250acceldata.x,mpu9250acceldata.y,mpu9250acceldata.z,mpu9250gyrodata.x,mpu9250gyrodata.y,mpu9250gyrodata.z,0,0,0,0);
log_i("%6d %6d %6d %6d %6d %6d %6d %6d %6d ",mpu9250acceldata.x,mpu9250acceldata.y,mpu9250acceldata.z,mpu9250gyrodata.x,mpu9250gyrodata.y,mpu9250gyrodata.z,mpu9250magndata.x,mpu9250magndata.y,mpu9250magndata.z);
}
//*****************************************************************************
//
//! \addtogroup linux-t
//! @{
//
//*****************************************************************************
/*---------------------------------------------------------------------------*/
/* include files */
/*---------------------------------------------------------------------------*/
#include "bsp.h"
#include
#include
#include
#include "bsp_adc0.h"
#include "bsp_gpio.h"
#include "bsp_iic.h"
#include "bsp_lptmr0.h"
#include "bsp/bsp_simiic.h"
/*
*********************************************************************************************************
* 函 数 名: bsp_InitI2C
* 功能说明: 配置I2C总线的GPIO,采用模拟IO的方式实现
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* 函 数 名: i2c_Delay
* 功能说明: I2C总线位延迟,最快400KHz
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void i2c_Delay(void)
{
// u8 i;
/*
CPU主频 48MHZ
实际应用选择400KHz左右的速率即可
*/
// for (i = 0; i < 20; i++);
return;
}
/*
*********************************************************************************************************
* 函 数 名: i2c_Start
* 功能说明: CPU发起I2C总线启动信号
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void i2c_Start(void)
{
I2C_SCL_SetOutput();
I2C_SDA_SetOutput();
i2c_Delay();
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)
{
I2C_SCL_0();
I2C_SDA_0();
i2c_Delay();
I2C_SCL_1();
i2c_Delay();
I2C_SDA_1();
i2c_Delay();
I2C_SCL_SetInput();
I2C_SDA_SetInput();
}
/*
*********************************************************************************************************
* 函 数 名: bsp_InitI2C
* 功能说明: 配置I2C总线的GPIO,采用模拟IO的方式实现
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_InitI2C(void)
{
I2C_SCL_SetOutput();
I2C_SDA_SetOutput();
i2c_Stop();
}
/*
*********************************************************************************************************
* 函 数 名: i2c_WaitAck
* 功能说明: CPU产生一个时钟,并读取器件的ACK应答信号
* 形 参: 无
* 返 回 值: 返回0表示正确应答,1表示无器件响应
*********************************************************************************************************
*/
#if 1
uint8 i2c_WaitAck(void)
{
uint8 re;
I2C_SCL_0();
I2C_SDA_SetInput(); /*在SCL低态,先SDA置输出,再SCL高态,否则会产生总线停止,引脚输入/输出状态不锁存*/
i2c_Delay();
I2C_SCL_1();
if (I2C_SDA_READ()) /* CPU读取SDA口线状态 */
{
I2C_SDA_1();
re = 1;
}
else
{
I2C_SDA_0();
re = 0;
}
i2c_Delay();
I2C_SDA_SetOutput(); /*在SCL高态,先同步SDA状态再置输出,再SCL低态,否则会产生总线停止或SDA多余状态*/
I2C_SCL_0();
return re;
}
#endif
#if 0
uint8 i2c_WaitAck(void)
{
uint8 re;
uint8 tempTime = 0;
I2C_SCL_0();
I2C_SDA_SetInput(); /*在SCL低态,先SDA置输出,再SCL高态,否则会产生总线停止,引脚输入/输出状态不锁存*/
i2c_Delay();
I2C_SCL_1();
while(I2C_SDA_READ())
{
tempTime++;
if(tempTime>250)
{
I2C_SDA_1();
i2c_Delay();
I2C_SDA_SetOutput(); /*在SCL高态,先同步SDA状态再置输出,再SCL低态,否则会产生总线停止或SDA多余状态*/
I2C_SCL_0();
return 1;
}
}
I2C_SDA_0();
i2c_Delay();
I2C_SDA_SetOutput(); /*在SCL高态,先同步SDA状态再置输出,再SCL低态,否则会产生总线停止或SDA多余状态*/
I2C_SCL_0();
return 0;
}
#endif
/*
*********************************************************************************************************
* 函 数 名: i2c_Ack
* 功能说明: CPU产生一个ACK信号
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void i2c_Ack(void)
{
I2C_SDA_SetOutput();
I2C_SCL_0();
i2c_Delay();
I2C_SDA_0();
i2c_Delay();
I2C_SCL_1();
i2c_Delay();
I2C_SCL_0();
i2c_Delay();
}
/*
*********************************************************************************************************
* 函 数 名: i2c_NAck
* 功能说明: CPU产生1个NACK信号
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void i2c_NAck(void)
{
I2C_SDA_SetOutput();
I2C_SCL_0();
i2c_Delay();
I2C_SDA_1();
i2c_Delay();
I2C_SCL_1();
i2c_Delay();
I2C_SCL_0();
i2c_Delay();
}
/*
*********************************************************************************************************
* 函 数 名: i2c_SendByte
* 功能说明: CPU向I2C总线设备发送8bit数据
* 形 参: _ucByte : 等待发送的字节
* 返 回 值: 无
*********************************************************************************************************
*/
void i2c_SendByte(uint8 _ucByte)
{
uint8 i;
/* 先发送字节的高位bit7 */
for (i = 0; i < 8; i++)
{
I2C_SCL_0();
i2c_Delay();
if (_ucByte & 0x80)
{
I2C_SDA_1();
}
else
{
I2C_SDA_0();
}
i2c_Delay();
I2C_SCL_1();
i2c_Delay();
_ucByte <<= 1; /* 左移一个bit */
}
}
/*
*********************************************************************************************************
* 函 数 名: i2c_ReadByte
* 功能说明: CPU从I2C总线设备读取8bit数据
* 形 参: 无
* 返 回 值: 读到的数据
*********************************************************************************************************
*/
uint8 i2c_ReadByte(void)
{
uint8 i;
uint8 value;
I2C_SDA_SetInput();
for (i = 0; i < 8; i++)
{
i2c_Delay();
I2C_SCL_1();
value <<= 1;
if (I2C_SDA_READ())
{
I2C_SDA_1();
value |= 0x01;
}
else
{
I2C_SDA_0();
value &= 0xfe;
}
i2c_Delay();
if(i == 7)
I2C_SDA_SetOutput();/*置SDA输出,这样SDA不会产生多余状态*/
I2C_SCL_0();
}
return value;
}
/*
*********************************************************************************************************
* 函 数 名: i2c_CheckDevice
* 功能说明: 检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在
* 形 参: _Address:设备的I2C总线地址
* 返 回 值: 返回值 0 表示正确, 返回1表示未探测到
*********************************************************************************************************
*/
uint8 i2c_CheckDevice(uint8 _Address)
{
uint8 ucAck;
I2C_SDA_SetInput();
I2C_SCL_SetInput();
if (I2C_SDA_READ() && I2C_SCL_READ())
{
I2C_SDA_SetOutput();
I2C_SCL_SetOutput();
i2c_Start(); /* 发送启动信号 */
/* 发送设备地址+读写控制bit(0 = w, 1 = r) bit7 先传 */
i2c_SendByte(_Address | I2C_WR);
ucAck = i2c_WaitAck(); /* 检测设备的ACK应答 */
i2c_Stop(); /* 发送停止信号 */
return ucAck;
}
I2C_SDA_SetOutput();
I2C_SCL_SetOutput();
return 1; /* I2C总线异常 */
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************