24LC024读写问题
针对这种EEPROM器件,根据芯片手册配置,不超过16字节读写正常,超过就不对,会覆盖之前的内容,就是说永远只写前16个地址,后面的地址没有写上,看了半天也不知道是怎么回事?有没有哪位用过,给个提示。主控制器用的STM32F103。读写控制代码如下:#define ADDR_24LC02_Write 0xA0#define ADDR_24LC02_Read 0xA1
#define BufferSize 34
HAL_I2C_Mem_Write(&hi2c2, ADDR_24LC02_Write, 0, I2C_MEMADD_SIZE_8BIT, WriteBuffer, BufferSize, 0x10);
HAL_I2C_Mem_Read(&hi2c2, ADDR_24LC02_Read, 0, I2C_MEMADD_SIZE_8BIT, ReadBuffer, BufferSize, 0x10);
WriteBuffer写入数据依次为1-34;ReadBuffer读取仅有33,34,19,20,21,22,23,24,25,26,27,28,29,30,31,32。只能读到16个地址数,我认为是写的时候只写了16个地址,数据一直在前16个地址上覆盖。
EEPROM不能直接跨页写,要跨页的话,得重新指定一次新的页地址,同时得有一次停止位。
理解一下这段代码,其中NumOfPage、NumOfSingle两个变量,以及I2C_FLASH_PAGESIZE。
/**
* @briefWrites buffer of data to the I2C EEPROM.
* @parampBuffer : pointer to the buffercontaining the data to be
* written to the EEPROM.
* @paramWriteAddr : EEPROM's internal address to write to.
* @paramNumByteToWrite : number of bytes to write to the EEPROM.
* @retval None
*/
void I2C_EE_BufferWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
{
uint8_t NumOfPage = 0, NumOfSingle = 0, count = 0;
uint16_t Addr = 0;
Addr = WriteAddr % I2C_FLASH_PAGESIZE;
count = I2C_FLASH_PAGESIZE - Addr;
NumOfPage =NumByteToWrite / I2C_FLASH_PAGESIZE;
NumOfSingle = NumByteToWrite % I2C_FLASH_PAGESIZE;
/* If WriteAddr is I2C_FLASH_PAGESIZE aligned*/
if(Addr == 0)
{
/* If NumByteToWrite < I2C_FLASH_PAGESIZE */
if(NumOfPage == 0)
{
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
/* If NumByteToWrite > I2C_FLASH_PAGESIZE */
else
{
while(NumOfPage--)
{
I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_FLASH_PAGESIZE);
I2C_EE_WaitEepromStandbyState();
WriteAddr +=I2C_FLASH_PAGESIZE;
pBuffer += I2C_FLASH_PAGESIZE;
}
if(NumOfSingle!=0)
{
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
}
}
/* If WriteAddr is not I2C_FLASH_PAGESIZE aligned*/
else
{
/* If NumByteToWrite < I2C_FLASH_PAGESIZE */
if(NumOfPage== 0)
{
/* If the number of data to be written is more than the remaining space
in the current page: */
if (NumByteToWrite > count)
{
/* Write the data conained in same page */
I2C_EE_PageWrite(pBuffer, WriteAddr, count);
I2C_EE_WaitEepromStandbyState();
/* Write the remaining data in the following page */
I2C_EE_PageWrite((uint8_t*)(pBuffer + count), (WriteAddr + count), (NumByteToWrite - count));
I2C_EE_WaitEepromStandbyState();
}
else
{
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
}
/* If NumByteToWrite > I2C_FLASH_PAGESIZE */
else
{
NumByteToWrite -= count;
NumOfPage =NumByteToWrite / I2C_FLASH_PAGESIZE;
NumOfSingle = NumByteToWrite % I2C_FLASH_PAGESIZE;
if(count != 0)
{
I2C_EE_PageWrite(pBuffer, WriteAddr, count);
I2C_EE_WaitEepromStandbyState();
WriteAddr += count;
pBuffer += count;
}
while(NumOfPage--)
{
I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_FLASH_PAGESIZE);
I2C_EE_WaitEepromStandbyState();
WriteAddr +=I2C_FLASH_PAGESIZE;
pBuffer += I2C_FLASH_PAGESIZE;
}
if(NumOfSingle != 0)
{
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
}
}
}
/**
* @briefWrites more than one byte to the EEPROM with a single WRITE cycle.
* @note The number of byte can't exceed the EEPROM page size.
* @parampBuffer : pointer to the buffer containing the data to be
* written to the EEPROM.
* @paramWriteAddr : EEPROM's internal address to write to.
* @paramNumByteToWrite : number of bytes to write to the EEPROM.
* @retval None
*/
void I2C_EE_PageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite)
{
/* While the bus is busy */
while(I2C_GetFlagStatus(I2C_EE, I2C_FLAG_BUSY));
/* Send START condition */
I2C_GenerateSTART(I2C_EE, ENABLE);
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_MODE_SELECT));
/* Send EEPROM address for write */
I2C_Send7bitAddress(I2C_EE, EEPROM_ADDRESS, I2C_Direction_Transmitter);
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
#ifdef EE_M24C08
/* Send the EEPROM's internal address to write to : only one byte Address */
I2C_SendData(I2C_EE, WriteAddr);
#elif defined(EE_M24C64_32)
/* Send the EEPROM's internal address to write to : MSB of the address first */
I2C_SendData(I2C_EE, (uint8_t)((WriteAddr & 0xFF00) >> 8));
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* Send the EEPROM's internal address to write to : LSB of the address */
I2C_SendData(I2C_EE, (uint8_t)(WriteAddr & 0x00FF));
#endif /* EE_M24C08 */
/* Test on EV8 and clear it */
while(! I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* While there is data to be written */
while(NumByteToWrite--)
{
/* Send the current byte */
I2C_SendData(I2C_EE, *pBuffer);
/* Point to the next byte to be written */
pBuffer++;
/* Test on EV8 and clear it */
while (!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
/* Send STOP condition */
I2C_GenerateSTOP(I2C_EE, ENABLE);
}
/**
* @briefWait for EEPROM Standby state
* @paramNone
* @retval None
*/
void I2C_EE_WaitEepromStandbyState(void)
{
__IO uint16_t SR1_Tmp = 0;
do
{
/* Send START condition */
I2C_GenerateSTART(I2C_EE, ENABLE);
/* Read I2C_EE SR1 register to clear pending flags */
SR1_Tmp = I2C_ReadRegister(I2C_EE, I2C_Register_SR1);
/* Send EEPROM address for write */
I2C_Send7bitAddress(I2C_EE, EEPROM_ADDRESS, I2C_Direction_Transmitter);
}while(!(I2C_ReadRegister(I2C_EE, I2C_Register_SR1) & 0x0002));
/* Clear AF flag */
I2C_ClearFlag(I2C_EE, I2C_FLAG_AF);
/* STOP condition */
I2C_GenerateSTOP(I2C_EE, ENABLE);
}
仔细看一下那两个读写函数最后那个0x10应该是数据长度改一下就好了 mylovemcu 发表于 2020-4-26 09:15
仔细看一下那两个读写函数最后那个0x10应该是数据长度改一下就好了
HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
最后那个是超时吧... ... toofree 发表于 2020-4-26 09:11
EEPROM不能直接跨页写,要跨页的话,得重新指定一次新的页地址,同时得有一次停止位。
理解一下这段代码, ...
围观大佬 if(HAL_I2C_Mem_Write(&hi2c2, ADDR_24LC02_Write, 0, I2C_MEMADD_SIZE_8BIT, WriteBuffer, 16, 0x10) == HAL_OK)
{
HAL_Delay(10);
if(HAL_I2C_Mem_Write(&hi2c2, ADDR_24LC02_Write, 16, I2C_MEMADD_SIZE_8BIT, WriteBuffer+16, 16, 0x10) == HAL_OK)
{
HAL_Delay(10);
if(HAL_I2C_Mem_Write(&hi2c2, ADDR_24LC02_Write, 32, I2C_MEMADD_SIZE_8BIT, WriteBuffer+32, 16, 0x10) == HAL_OK)
{
HAL_Delay(10);
}
}
}
我想了一个最简单的办法,适合不需要太多存储的情况,既然不能跨页连写,那么我就采用随机写,连续读的方式,就不用修改那么多。 楼主,注意看手册中E2的每页大小,页数。写入的时候需要换页,读取可以不用。 EEPROM参数里有个页写时间,一般是5ms,意思是每次写换页要等5ms才能切换下一页,所以写要注意时序。读没要求。 EEPROM参数里有个页写时间,一般是5ms,意思是每次写换页要等5ms才能切换下一页,所以写要注意时序。读没要求。 Dandjinh 发表于 2020-4-26 10:36
EEPROM参数里有个页写时间,一般是5ms,意思是每次写换页要等5ms才能切换下一页,所以写要注意时序。读没要 ...
意思是写完一次后加长HAL_Delay时间?
页:
[1]
2