/**
* @brief 写一个字节到I2C设备中
* @param
* @arg pBuffer:缓冲区指针
* @arg WriteAddr:写地址
* @retval 正常返回1,异常返回0
*/
uint8_t I2C_ByteWrite(u8 pBuffer, u8 WriteAddr)
{
/* Send STRAT condition */
I2C_GenerateSTART(macI2Cx, ENABLE); I2CTimeout = I2CT_FLAG_TIMEOUT; /* Test on EV5 and clear it */
//启动信号发出之后要等待状态寄存器SR1的位0(SB=1),状态寄存器SR2的位1(BUSY=1)和位0(MSL=1),此时表明主模式下,起始条件已发送,总线处于忙状态;确保IIC通讯正确
while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_MODE_SELECT))
{
if((I2CTimeout--) == ) return I2C_TIMEOUT_UserCallback();
} /* Send slave address for write */
I2C_Send7bitAddress(macI2Cx, MPU6050_SLAVE_ADDRESS, I2C_Direction_Transmitter);//7bit slave address + read/write (0write,1 read) I2CTimeout = I2CT_FLAG_TIMEOUT; /* Test on EV6 and clear it */
//从机地址发出之后,等待 BUSY, MSL, ADDR, TXE and TRA flags标志位
while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if((I2CTimeout--) == ) return I2C_TIMEOUT_UserCallback();
} /* Send the slave's internal address to write to */
I2C_SendData(macI2Cx, WriteAddr); I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV8 and clear it */
/* TRA, BUSY, MSL, TXE and BTF flags */
while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if((I2CTimeout--) == ) return I2C_TIMEOUT_UserCallback();
} /* Send the byte to be written */
I2C_SendData(macI2Cx, pBuffer); I2CTimeout = I2CT_FLAG_TIMEOUT; /* Test on EV8 and clear it */
/* TRA, BUSY, MSL, TXE and BTF flags */
while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if((I2CTimeout--) == ) return I2C_TIMEOUT_UserCallback();
} /* Send STOP condition */
I2C_GenerateSTOP(macI2Cx, ENABLE); return ; //正常返回1
}
IIC事件检测:498页。STM32的硬件IIC通信非常严格,每一步都要检测相应的标志位是否正确,确保通信不会出错。
/**
* @brief 从I2C设备里面读取一块数据
* @param
* @arg pBuffer:存放从slave读取的数据的缓冲区指针
* @arg WriteAddr:接收数据的从设备的地址
* @arg NumByteToWrite:要从从设备读取的字节数
* @retval 正常返回1,异常返回0
*/
uint8_t I2C_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)
{
I2CTimeout = I2CT_LONG_TIMEOUT; while(I2C_GetFlagStatus(macI2Cx, I2C_FLAG_BUSY)) // Added by Najoua 27/08/2008
{
if((I2CTimeout--) == ) return I2C_TIMEOUT_UserCallback();
} I2C_GenerateSTART(macI2Cx, ENABLE); I2CTimeout = I2CT_FLAG_TIMEOUT; /* Test on EV5 and clear it */
while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_MODE_SELECT))
{
if((I2CTimeout--) == ) return I2C_TIMEOUT_UserCallback();
} /* Send slave address for write */
I2C_Send7bitAddress(macI2Cx, MPU6050_SLAVE_ADDRESS, I2C_Direction_Transmitter); I2CTimeout = I2CT_FLAG_TIMEOUT; /* Test on EV6 and clear it */
while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if((I2CTimeout--) == ) return I2C_TIMEOUT_UserCallback();
} /* Clear EV6 by setting again the PE bit */
I2C_Cmd(macI2Cx, ENABLE); /* Send the slave's internal address to write to */
I2C_SendData(macI2Cx, ReadAddr); I2CTimeout = I2CT_FLAG_TIMEOUT; /* Test on EV8 and clear it */
while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if((I2CTimeout--) == ) return I2C_TIMEOUT_UserCallback();
} /* Send STRAT condition a second time */
I2C_GenerateSTART(macI2Cx, ENABLE); I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_MODE_SELECT))
{
if((I2CTimeout--) == ) return I2C_TIMEOUT_UserCallback();
} /* Send slave address for read */
I2C_Send7bitAddress(macI2Cx, MPU6050_SLAVE_ADDRESS, I2C_Direction_Receiver); I2CTimeout = I2CT_FLAG_TIMEOUT; /* Test on EV6 and clear it */
while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
if((I2CTimeout--) == ) return I2C_TIMEOUT_UserCallback();
} /* While there is data to be read */
while(NumByteToRead)
{
if(NumByteToRead == )
{
/* Disable Acknowledgement */
I2C_AcknowledgeConfig(macI2Cx, DISABLE); /* Send STOP Condition */
I2C_GenerateSTOP(macI2Cx, ENABLE);
} /* Test on EV7 and clear it */
if(I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED))
{
/* Read a byte from the slave */
*pBuffer = I2C_ReceiveData(macI2Cx); /* Point to the next location where the byte read will be saved */
pBuffer++; /* Decrement the read bytes counter */
NumByteToRead--;
}
} /* Enable Acknowledgement to be ready for another reception */
I2C_AcknowledgeConfig(macI2Cx, ENABLE); return ; //正常,返回1
}