久芯网

24LC024读写问题

avatar yllqabz 提问时间: 2023-10-03 07:20:43 / 未解决
针对这种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个地址上覆盖。

如需获得 24LC024 等器件的更多信息,请点击链接或 点击此处 联系在线客服!

13个回答
  • avatar 七哥
    回答时间: 2023-10-03 07:52:46

    EEPROM不能直接跨页写,要跨页的话,得重新指定一次新的页地址,同时得有一次停止位。 理解一下这段代码,其中NumOfPage、NumOfSingle两个变量,以及I2C_FLASH_PAGESIZE。 /** * @brief Writes buffer of data to the I2C EEPROM. * @param pBuffer : pointer to the buffer containing the data to be * written to the EEPROM. * @param WriteAddr : EEPROM's internal address to write to. * @param NumByteToWrite : 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(); } } } } /** * @brief Writes more than one byte to the EEPROM with a single WRITE cycle. * @note The number of byte can't exceed the EEPROM page size. * @param pBuffer : pointer to the buffer containing the data to be * written to the EEPROM. * @param WriteAddr : EEPROM's internal address to write to. * @param NumByteToWrite : 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); } /** * @brief Wait for EEPROM Standby state * @param None * @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); }复制代码

  • avatar mylovemcu
    回答时间: 2023-10-03 08:23:32

    仔细看一下那两个读写函数 最后那个0x10应该是数据长度 改一下就好了

  • avatar yllqabz
    回答时间: 2023-10-03 08:49:32
    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) 最后那个是超时吧... ...

  • avatar 李康1202
    回答时间: 2023-10-03 09:22:41
    toofree 发表于 2020-4-26 09:11
    EEPROM不能直接跨页写,要跨页的话,得重新指定一次新的页地址,同时得有一次停止位。 理解一下这段代码, ...

    围观大佬

  • avatar yllqabz
    回答时间: 2023-10-03 09:41:32

    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); } } } 我想了一个最简单的办法,适合不需要太多存储的情况,既然不能跨页连写,那么我就采用随机写,连续读的方式,就不用修改那么多。

  • avatar 废鱼
    回答时间: 2023-10-03 10:04:36

    楼主,注意看手册中E2的每页大小,页数。写入的时候需要换页,读取可以不用。

  • avatar Dandjinh
    回答时间: 2023-10-03 10:31:20

    EEPROM参数里有个页写时间,一般是5ms,意思是每次写换页要等5ms才能切换下一页,所以写要注意时序。读没要求。

  • avatar Dandjinh
    回答时间: 2023-10-03 11:01:22

    EEPROM参数里有个页写时间,一般是5ms,意思是每次写换页要等5ms才能切换下一页,所以写要注意时序。读没要求。

  • avatar yllqabz
    回答时间: 2023-10-03 11:31:46
    Dandjinh 发表于 2020-4-26 10:36
    EEPROM参数里有个页写时间,一般是5ms,意思是每次写换页要等5ms才能切换下一页,所以写要注意时序。读没要 ...

    意思是写完一次后加长HAL_Delay时间?

  • avatar yllqabz
    回答时间: 2023-10-03 12:03:38
    toofree 发表于 2020-4-26 09:11
    EEPROM不能直接跨页写,要跨页的话,得重新指定一次新的页地址,同时得有一次停止位。 理解一下这段代码, ...

    这个是以前的库吧,我现在用HAL库,是不是就很难移植了

  • avatar liudejun2020
    回答时间: 2023-10-03 12:21:56

    新手上路

  • avatar 李康1202
    回答时间: 2023-10-03 12:53:48
    toofree 发表于 2020-4-26 09:11
    EEPROM不能直接跨页写,要跨页的话,得重新指定一次新的页地址,同时得有一次停止位。 理解一下这段代码, ...

    官方IIC好用不

  • avatar 七哥
    回答时间: 2023-10-03 13:22:44
    likang1202 发表于 2020-4-27 18:10
    官方IIC好用不

    好用啊, 对于EEPROM操作,5ms的延时最重要,一定要数据对照手册。

会员中心 微信客服
客服
回到顶部