您的位置:首页 > 其它

I2C协议通讯过程

qq_33214029 2020-07-21 04:15 281 查看 https://blog.csdn.net/qq_33214

1. 位写

1.发送起始信号(S),
2.产生EV5事件
3.发送从机设备地址
6.从机应答,产生EV6事件
7. 发送要写入的从机存储器内部地址
8. 从机应答,产生EV8事件
9. 发送要写入的数据
10. 从机应答,产生EV8事件
11. 发送停止信号(P)


uint32_t I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr)
{
/* Send STRAT condition */
I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);

I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(0);
}

I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Send EEPROM address for write */
I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Transmitter);

/* Test on EV6 and clear it */
while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(1);
}
/* Send the EEPROM's internal address to write to */
I2C_SendData(EEPROM_I2Cx, WriteAddr);

I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(2);
}
/* Send the byte to be written */
I2C_SendData(EEPROM_I2Cx, *pBuffer);

I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(3);
}

/* Send STOP condition */
I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE);

return 1;
}

2.页写

1.发送起始信号(S)
2.产生EV5事件
3. 发送从机设备地址
4.从机应答,产生EV6事件
5.发送要写入的从机存储器地址
6…从机应答,产生EV8事件
7.循环发送n个数据 ,发送一个数据,产生一个应答(ACK),EV8事件
8,.发送停止信号(P)

uint32_t I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)
{
//  I2CTimeout = I2CT_LONG_TIMEOUT;

//  while(I2C_GetFlagStatus(EEPROM_I2Cx, I2C_FLAG_BUSY))
//  {
//    if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(4);
//  }

/* Send START condition */
I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);

I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(5);
}

/* Send EEPROM address for write */
I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Transmitter);

I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(6);
}

/* Send the EEPROM's internal address to write to */
I2C_SendData(EEPROM_I2Cx, WriteAddr);

I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV8 and clear it */
while(! I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(7);
}

/* While there is data to be written */
while(NumByteToWrite--)
{
/* Send the current byte */
I2C_SendData(EEPROM_I2Cx, *pBuffer);

/* Point to the next byte to be written */
pBuffer++;

I2CTimeout = I2CT_FLAG_TIMEOUT;

/* Test on EV8 and clear it */
while (!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(8);
}
}

/* Send STOP condition */
I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE);

return 1;
}

3. 读数据

1.发送起始信号(S)
2. 产生EV5事件
3. 发送从机设备地址
4. 从机应答,产生EV6事件
5. 发送要写入的从机存储器地址
6. 从机应答,产生EV8事件
7. 再次发送起始事件(S)
8. 产生EV5事件
9. 发送从机设备地址
10. 从机应答,产生EV6事件
11. 读取数据
12. 每接收一个数据,从机应答一次,产生一次EV7事件
13. 接收完毕,发送停止信号(P)

uint32_t I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)
{

//  I2CTimeout = I2CT_LONG_TIMEOUT;
//
//  //*((u8 *)0x4001080c) |=0x80;
//  while(I2C_GetFlagStatus(EEPROM_I2Cx, I2C_FLAG_BUSY))
//  {
//    if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(9);
//  }
//
/* Send START condition */
I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);
//*((u8 *)0x4001080c) &=~0x80;

I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(10);
}

/* Send EEPROM address for write */
I2C_Send7bitAddress(EEPROM_I2Cx, 0XA0, I2C_Direction_Transmitter);

I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(11);
}

/* Clear EV6 by setting again the PE bit */
//  I2C_Cmd(EEPROM_I2Cx, ENABLE);

/* Send the EEPROM's internal address to write to */
I2C_SendData(EEPROM_I2Cx, ReadAddr);

I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(12);
}

/* Send STRAT condition a second time */
I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);

I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(13);
}

/* Send EEPROM address for read */
I2C_Send7bitAddress(EEPROM_I2Cx, 0XA0, I2C_Direction_Receiver);

I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(14);
}

/* While there is data to be read */
while(NumByteToRead)
{
if(NumByteToRead == 1)
{
/* Disable Acknowledgement */
I2C_AcknowledgeConfig(EEPROM_I2Cx, DISABLE);

/* Send STOP Condition */
I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE);
}

/* Test on EV7 and clear it */
I2CTimeout = I2CT_LONG_TIMEOUT;

while(I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)==0)
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(3);
}
{
/* Read a byte from the EEPROM */
*pBuffer = I2C_ReceiveData(EEPROM_I2Cx);

/* 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(EEPROM_I2Cx, ENABLE);

return 1;
}

以上纯属个人观点,若有不正之处,请不吝赐教!

标签: