[问题]mpu9250+bmp280数据读取

采用软件iic读取的数据,软件iic就暂时不讲了,开搞mpu9250

 

在网上了解了一些,mpu9250实际上就是mpu6050+磁力计,即有两个器件地址,可以通过设置读取模式来分别读到mpu6050和磁力计的数据。

在网上看到这一片帖子,可以借鉴一点:https://blog.csdn.net/black_yu/article/details/51815049

还有一些前辈的指点

[问题]mpu9250+bmp280数据读取_第1张图片

 

但是,最终还是没有调好,用的是工作时间,所以准备回去调试

 

莫名奇妙的成功了几次,即mpu9250+ak8963 数据成功读出来了,害得我高兴地上厕所去了,结果一回来又不行了。中间断了一次电。

现在棘手的问题是mpu9250,我没办法写寄存器

以下是这个问题的具体描述

1、mpu9250能读到ID,能读数据。

比如我现在加速度默认的量程是正负2G的,我想换成正负16G的量程时,读出来的数据还是2G的量程范围的值(我通过成功的那几次中才发现的问题)。我去读加速度量程的寄存器,读出来的值就是0x00。因此这个问题也导致我mpu9250没办法设置成passby模式,因此没办法读取磁力计!!!

[问题]mpu9250+bmp280数据读取_第2张图片

[问题]mpu9250+bmp280数据读取_第3张图片

2、这个iic的时序我是沿用的icm20609的时序这是设置完i6G后,读的加速度config寄存器(仍是2G的配置)

感觉波形是正确的呀,icm20609读的66的,也能修改配置。

[问题]mpu9250+bmp280数据读取_第4张图片

下面我也贴一下我的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.
//! @}
//
//*****************************************************************************

 

 

你可能感兴趣的:(项目之四轴)