中级会员
 
- 积分
- 235
- 金钱
- 235
- 注册时间
- 2014-12-18
- 在线时间
- 13 小时
|
用STM32F207 I2C读写AT24C256,读取后要延时一段时间才可以得到正确的值,不知各位遇到过没有
读写函数用的从ST网上下载包中的EPPROM 例程
sEE_ReadBuffer((uint8_t *)&time, r_addr, (uint16_t*)&read_num);
在此处加延时,才可以输出time值为0xFF,否则time的值为0
printf("%d",time);
uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
{
/* Set the pointer to the Number of data to be read. This pointer will be used
by the DMA Transfer Completer interrupt Handler in order to reset the
variable to 0. User should check on this variable in order to know if the
DMA transfer has been complete or not. */
sEEDataReadPointer = NumByteToRead;
/*!< While the bus is busy */
sEETimeout = sEE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BUSY))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Send START condition */
I2C_GenerateSTART(sEE_I2C, ENABLE);
/*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Send EEPROM address for write */
I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Transmitter);
/*!< Test on EV6 and clear it */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
if(sEEAddress==AT24C256_ADDRESS)
{
/*!< Send the EEPROM's internal address to write to : MSB of the address first */
I2C_SendData(sEE_I2C, (uint8_t)((ReadAddr & 0xFF00) >> 8));
/*!< Test on EV8 and clear it */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTING))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Send the EEPROM's internal address to write to : LSB of the address */
I2C_SendData(sEE_I2C, (uint8_t)(ReadAddr & 0x00FF));
}
else if(sEEAddress==MCP23017_ADDRESS)
{
/*!< Send the EEPROM's internal address to write to : only one byte Address */
I2C_SendData(sEE_I2C, ReadAddr);
}
//#ifdef sEE_M24C08
// /*!< Send the EEPROM's internal address to read from: Only one byte address */
// I2C_SendData(sEE_I2C, ReadAddr);
//#elif defined (sEE_M24C02)
// /*!< Send the EEPROM's internal address to read from: Only one byte address */
// I2C_SendData(sEE_I2C, ReadAddr);
//#elif defined (sEE_M24C64_32)
// /*!< Send the EEPROM's internal address to read from: MSB of the address first */
// I2C_SendData(sEE_I2C, (uint8_t)((ReadAddr & 0xFF00) >> 8));
// /*!< Test on EV8 and clear it */
// sEETimeout = sEE_FLAG_TIMEOUT;
// while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTING))
// {
// if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
// }
// /*!< Send the EEPROM's internal address to read from: LSB of the address */
// I2C_SendData(sEE_I2C, (uint8_t)(ReadAddr & 0x00FF));
//
//#endif /*!< sEE_M24C08 */
/*!< Test on EV8 and clear it */
sEETimeout = sEE_FLAG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BTF) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Send STRAT condition a second time */
I2C_GenerateSTART(sEE_I2C, ENABLE);
/*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Send EEPROM address for read */
I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Receiver);
/* If number of data to be read is 1, then DMA couldn't be used */
/* One Byte Master Reception procedure (POLLING) ---------------------------*/
if ((uint16_t)(*NumByteToRead) < 2)
{
/* Wait on ADDR flag to be set (ADDR is still not cleared at this level */
sEETimeout = sEE_FLAG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_ADDR) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Disable Acknowledgment */
I2C_AcknowledgeConfig(sEE_I2C, DISABLE);
/* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */
(void)sEE_I2C->SR2;
/*!< Send STOP Condition */
I2C_GenerateSTOP(sEE_I2C, ENABLE);
/* Wait for the byte to be received */
sEETimeout = sEE_FLAG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_RXNE) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Read the byte received from the EEPROM */
*pBuffer = I2C_ReceiveData(sEE_I2C);
/*!< Decrement the read bytes counter */
(uint16_t)(*NumByteToRead)--;
/* Wait to make sure that STOP control bit has been cleared */
sEETimeout = sEE_FLAG_TIMEOUT;
while(sEE_I2C->CR1 & I2C_CR1_STOP)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Re-Enable Acknowledgment to be ready for another reception */
I2C_AcknowledgeConfig(sEE_I2C, ENABLE);
}
else/* More than one Byte Master Reception procedure (DMA) -----------------*/
{
/*!< Test on EV6 and clear it */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Configure the DMA Rx Channel with the buffer address and the buffer size */
sEE_LowLevel_DMAConfig((uint32_t)pBuffer, (uint16_t)(*NumByteToRead), sEE_DIRECTION_RX);
/* Inform the DMA that the next End Of Transfer Signal will be the last one */
I2C_DMALastTransferCmd(sEE_I2C, ENABLE);
/* Enable the DMA Rx Stream */
DMA_Cmd(sEE_I2C_DMA_STREAM_RX, ENABLE);
}
/* If all operations OK, return sEE_OK (0) */
return sEE_OK;
}
|
|