本帖最后由 GDCM3OS 于 2013-6-20 10:34 编辑
看到经常讨论使用IIC操作EEPROM经常遇到问题,根据实操,总结注意以下个问题。
1、IIC有4种工作模式。Slave transmitter,Slave receiver,Master transmitter,Master receiver。
2、每种工作模式对应若干事件标志,可以猜想芯片设计内部对应若干状态机。
3、每种事件标志的相应处理动作序列,要求有比较严密的步骤和时序。
4、具体应用还需注意处理意外情况。
程序实例,标的EE芯片AT24C02C。
写数据到EEPROM:
- uint8_t I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)
- {
- uint32_t timeout;
-
- timeout=0;
- while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
- {
- if(timeout++>=I2C_TIMEOUT)
- {
- return 0;
- }
- }
-
- /* Send START condition */
- I2C_GenerateSTART(I2C1, ENABLE);
- /* Test on EV5 and clear it */
- timeout=0;
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
- {
- if(timeout++>=I2C_TIMEOUT)
- {
- return 0;
- }
- }
-
- /* Send EEPROM address for write */
- I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);
- /* Test on EV6 and clear it */
- timeout=0;
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
- {
- if(timeout++>=I2C_TIMEOUT)
- {
- return 0;
- }
- }
-
- /* Send the EEPROM's internal address to write to */
- I2C_SendData(I2C1, WriteAddr);
- /* Test on EV8 and clear it */
- timeout=0;
- while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
- {
- if(timeout++>=I2C_TIMEOUT)
- {
- return 0;
- }
- }
-
- /* While there is data to be written */
- while(NumByteToWrite--)
- {
- /* Send the current byte */
- I2C_SendData(I2C1, *pBuffer);
-
- /* Point to the next byte to be written */
- pBuffer++;
-
- /* Test on EV8 and clear it */
- timeout=0;
- while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
- {
- if(timeout++>=I2C_TIMEOUT)
- {
- return 0;
- }
- }
- }
-
- /* Send STOP condition */
- I2C_GenerateSTOP(I2C1, ENABLE);
- timeout=0;
- while(I2C1->CR1&0x0200)
- {
- if(timeout++>=I2C_TIMEOUT)
- {
- return 0;
- }
- }
- return 1;
- }
判断EEPROM处于StandBy状态:
- uint8_t I2C_EE_WaitEepromStandbyState(void)
- {
- uint32_t timeout;
-
- while(1)
- {
- timeout=0;
- while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
- {
- if(timeout++>=I2C_TIMEOUT)
- {
- return 0;
- }
- }
-
- /* Send START condition */
- I2C_GenerateSTART(I2C1, ENABLE);
- /* Test on EV5 and clear it */
- timeout=0;
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
- {
- if(timeout++>=I2C_TIMEOUT)
- {
- return 0;
- }
- }
-
- /* Send EEPROM address for write */
- I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);
- /* Test on EV6 and clear it */
- timeout=0;
- while( (!I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR)) && (!I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)) );
- {
- if(timeout++>=I2C_TIMEOUT)
- {
- return 0;
- }
- }
- if(I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR))
- {
- break;
- }
- if(I2C_GetFlagStatus(I2C1, I2C_FLAG_AF))
- {
- I2C_ClearFlag(I2C1,I2C_FLAG_AF);
- I2C_GenerateSTOP(I2C1, ENABLE);
- timeout=0;
- while(I2C1->CR1&0x0200)
- {
- if(timeout++>=I2C_TIMEOUT)
- {
- return 0;
- }
- }
- }
- }
- timeout=0;
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
- {
- if(timeout++>=I2C_TIMEOUT)
- {
- return 0;
- }
- }
- I2C_GenerateSTOP(I2C1, ENABLE);
- timeout=0;
- while(I2C1->CR1&0x0200)
- {
- if(timeout++>=I2C_TIMEOUT)
- {
- return 0;
- }
- }
- return 1;
- }
|