由于最近公司要求国产化,需要将软件代码也国产化,项目后续使用APM的库进行开发,最近在使用apm库进行开发时发现库里在iic主里面只有写的例程,没有读的例程,参照其他库写了一个iic读的代码,供参考
uint8_t I2C_Read(uint8_t addr,uint32_t readsize,uint8_t data[],uint32_t len)
{
int ret=0;
if(readsize>len)
{
readsize=len;
}
uint16_t I2CTimeout = I2CT_LONG_TIMEOUT;
while(I2C_ReadStatusFlag(I2C1, I2C_FLAG_BUSBSY))
{
I2C_Init();
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(4);
}
I2C_DisableInterrupt(I2C1, I2C_INT_EVT);
/** Send START condition */
I2C_EnableGenerateStart(I2C1);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(!I2C_ReadEventStatus(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) //EV5
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(5);
}
/** Send address for write */
I2C_Tx7BitAddress(I2C1, addr, I2C_DIRECTION_TX);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(!I2C_ReadEventStatus(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) //EV6
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(6);
}
I2C_TxData(I2C1, addr);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(!I2C_ReadEventStatus(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING)) //EV8
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(6);
}
I2C_EnableGenerateStart(I2C1);
I2CTimeout = I2CT_LONG_TIMEOUT;
while (!I2C_ReadEventStatus(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) //EV5
{
if((I2CTimeout--) == 0)
{
return I2C_TIMEOUT_UserCallback(8);
}
}
I2C_Tx7BitAddress(I2C1, addr, I2C_DIRECTION_RX);
while (!I2C_ReadEventStatus(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) //EV6
{
if((I2CTimeout--) == 0)
{
return I2C_TIMEOUT_UserCallback(8);
}
}
while(ret<readsize)
{
if(ret==readsize-1)
{
I2C_DisableAcknowledge(I2C1);
I2C_EnableGenerateStop(I2C1);
}
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(I2C_ReadEventStatus(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)==ERROR&&I2CTimeout--);
if(I2CTimeout == 0)
{
// errno=6;
return -1;
}
data[ret++]=I2C_RxData(I2C1);
}
I2C_EnableAcknowledge(I2C1);
return ret;
}
附件为基于APM10x以及APM0xx库的模拟iic代码,供参考。
|