你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

24LC024读写问题

[复制链接]
yllqabz 提问时间:2020-4-26 08:56 /
针对这种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个地址上覆盖。
收藏 评论13 发布时间:2020-4-26 08:56

举报

13个回答
toofree 回答时间:2020-4-26 09:11:19
EEPROM不能直接跨页写,要跨页的话,得重新指定一次新的页地址,同时得有一次停止位。
理解一下这段代码,其中NumOfPage、NumOfSingle两个变量,以及I2C_FLASH_PAGESIZE。
  1. /**
  2.   * @brief  Writes buffer of data to the I2C EEPROM.
  3.   * @param  pBuffer : pointer to the buffer  containing the data to be
  4.   *   written to the EEPROM.
  5.   * @param  WriteAddr : EEPROM's internal address to write to.
  6.   * @param  NumByteToWrite : number of bytes to write to the EEPROM.
  7.   * @retval None
  8.   */
  9. void I2C_EE_BufferWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
  10. {
  11.   uint8_t NumOfPage = 0, NumOfSingle = 0, count = 0;
  12.   uint16_t Addr = 0;

  13.   Addr = WriteAddr % I2C_FLASH_PAGESIZE;
  14.   count = I2C_FLASH_PAGESIZE - Addr;
  15.   NumOfPage =  NumByteToWrite / I2C_FLASH_PAGESIZE;
  16.   NumOfSingle = NumByteToWrite % I2C_FLASH_PAGESIZE;

  17.   /* If WriteAddr is I2C_FLASH_PAGESIZE aligned  */
  18.   if(Addr == 0)
  19.   {
  20.     /* If NumByteToWrite < I2C_FLASH_PAGESIZE */
  21.     if(NumOfPage == 0)
  22.     {
  23.       I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  24.       I2C_EE_WaitEepromStandbyState();
  25.     }
  26.     /* If NumByteToWrite > I2C_FLASH_PAGESIZE */
  27.     else  
  28.     {
  29.       while(NumOfPage--)
  30.       {
  31.         I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_FLASH_PAGESIZE);
  32.         I2C_EE_WaitEepromStandbyState();
  33.         WriteAddr +=  I2C_FLASH_PAGESIZE;
  34.         pBuffer += I2C_FLASH_PAGESIZE;
  35.       }

  36.       if(NumOfSingle!=0)
  37.       {
  38.         I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  39.         I2C_EE_WaitEepromStandbyState();
  40.       }
  41.     }
  42.   }
  43.   /* If WriteAddr is not I2C_FLASH_PAGESIZE aligned  */
  44.   else
  45.   {
  46.     /* If NumByteToWrite < I2C_FLASH_PAGESIZE */
  47.     if(NumOfPage== 0)
  48.     {
  49.       /* If the number of data to be written is more than the remaining space
  50.       in the current page: */
  51.       if (NumByteToWrite > count)
  52.       {
  53.         /* Write the data conained in same page */
  54.         I2C_EE_PageWrite(pBuffer, WriteAddr, count);
  55.         I2C_EE_WaitEepromStandbyState();      
  56.         
  57.         /* Write the remaining data in the following page */
  58.         I2C_EE_PageWrite((uint8_t*)(pBuffer + count), (WriteAddr + count), (NumByteToWrite - count));
  59.         I2C_EE_WaitEepromStandbyState();        
  60.       }      
  61.       else      
  62.       {
  63.         I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  64.         I2C_EE_WaitEepromStandbyState();        
  65.       }     
  66.     }
  67.     /* If NumByteToWrite > I2C_FLASH_PAGESIZE */
  68.     else
  69.     {
  70.       NumByteToWrite -= count;
  71.       NumOfPage =  NumByteToWrite / I2C_FLASH_PAGESIZE;
  72.       NumOfSingle = NumByteToWrite % I2C_FLASH_PAGESIZE;
  73.       
  74.       if(count != 0)
  75.       {  
  76.         I2C_EE_PageWrite(pBuffer, WriteAddr, count);
  77.         I2C_EE_WaitEepromStandbyState();
  78.         WriteAddr += count;
  79.         pBuffer += count;
  80.       }
  81.       
  82.       while(NumOfPage--)
  83.       {
  84.         I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_FLASH_PAGESIZE);
  85.         I2C_EE_WaitEepromStandbyState();
  86.         WriteAddr +=  I2C_FLASH_PAGESIZE;
  87.         pBuffer += I2C_FLASH_PAGESIZE;  
  88.       }
  89.       if(NumOfSingle != 0)
  90.       {
  91.         I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  92.         I2C_EE_WaitEepromStandbyState();
  93.       }
  94.     }
  95.   }  
  96. }

  97. /**
  98.   * @brief  Writes more than one byte to the EEPROM with a single WRITE cycle.
  99.   * @note   The number of byte can't exceed the EEPROM page size.
  100.   * @param  pBuffer : pointer to the buffer containing the data to be
  101.   *   written to the EEPROM.
  102.   * @param  WriteAddr : EEPROM's internal address to write to.
  103.   * @param  NumByteToWrite : number of bytes to write to the EEPROM.
  104.   * @retval None
  105.   */
  106. void I2C_EE_PageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite)
  107. {
  108.   /* While the bus is busy */
  109.   while(I2C_GetFlagStatus(I2C_EE, I2C_FLAG_BUSY));
  110.   
  111.   /* Send START condition */
  112.   I2C_GenerateSTART(I2C_EE, ENABLE);
  113.   
  114.   /* Test on EV5 and clear it */
  115.   while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_MODE_SELECT));
  116.   
  117.   /* Send EEPROM address for write */
  118.   I2C_Send7bitAddress(I2C_EE, EEPROM_ADDRESS, I2C_Direction_Transmitter);

  119.   /* Test on EV6 and clear it */
  120.   while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  

  121. #ifdef EE_M24C08
  122.   
  123.   /* Send the EEPROM's internal address to write to : only one byte Address */
  124.   I2C_SendData(I2C_EE, WriteAddr);
  125.   
  126. #elif defined(EE_M24C64_32)
  127.   
  128.   /* Send the EEPROM's internal address to write to : MSB of the address first */
  129.   I2C_SendData(I2C_EE, (uint8_t)((WriteAddr & 0xFF00) >> 8));

  130.   /* Test on EV8 and clear it */
  131.   while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  132.   
  133.   /* Send the EEPROM's internal address to write to : LSB of the address */
  134.   I2C_SendData(I2C_EE, (uint8_t)(WriteAddr & 0x00FF));
  135.   
  136. #endif /* EE_M24C08 */  

  137.   /* Test on EV8 and clear it */
  138.   while(! I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  139.   /* While there is data to be written */
  140.   while(NumByteToWrite--)  
  141.   {
  142.     /* Send the current byte */
  143.     I2C_SendData(I2C_EE, *pBuffer);

  144.     /* Point to the next byte to be written */
  145.     pBuffer++;
  146.   
  147.     /* Test on EV8 and clear it */
  148.     while (!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  149.   }

  150.   /* Send STOP condition */
  151.   I2C_GenerateSTOP(I2C_EE, ENABLE);
  152. }

  153. /**
  154.   * @brief  Wait for EEPROM Standby state
  155.   * @param  None
  156.   * @retval None
  157.   */
  158. void I2C_EE_WaitEepromStandbyState(void)      
  159. {
  160.   __IO uint16_t SR1_Tmp = 0;

  161.   do
  162.   {
  163.     /* Send START condition */
  164.     I2C_GenerateSTART(I2C_EE, ENABLE);

  165.     /* Read I2C_EE SR1 register to clear pending flags */
  166.     SR1_Tmp = I2C_ReadRegister(I2C_EE, I2C_Register_SR1);

  167.     /* Send EEPROM address for write */
  168.     I2C_Send7bitAddress(I2C_EE, EEPROM_ADDRESS, I2C_Direction_Transmitter);

  169.   }while(!(I2C_ReadRegister(I2C_EE, I2C_Register_SR1) & 0x0002));
  170.   
  171.   /* Clear AF flag */
  172.   I2C_ClearFlag(I2C_EE, I2C_FLAG_AF);
  173.   
  174.   /* STOP condition */   
  175.   I2C_GenerateSTOP(I2C_EE, ENABLE);  
  176. }
复制代码



评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

mylovemcu 回答时间:2020-4-26 09:15:11
仔细看一下那两个读写函数  最后那个0x10应该是数据长度  改一下就好了

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

yllqabz 回答时间:2020-4-26 09:29:52
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)
最后那个是超时吧... ...
likang1202 回答时间:2020-4-26 09:39:56
toofree 发表于 2020-4-26 09:11
EEPROM不能直接跨页写,要跨页的话,得重新指定一次新的页地址,同时得有一次停止位。
理解一下这段代码, ...

围观大佬
yllqabz 回答时间:2020-4-26 10:04:44
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);
                                }
                        }
                }
我想了一个最简单的办法,适合不需要太多存储的情况,既然不能跨页连写,那么我就采用随机写,连续读的方式,就不用修改那么多。
回答时间:2020-4-26 10:10:44
楼主,注意看手册中E2的每页大小,页数。写入的时候需要换页,读取可以不用。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

Dandjinh 回答时间:2020-4-26 10:35:56
EEPROM参数里有个页写时间,一般是5ms,意思是每次写换页要等5ms才能切换下一页,所以写要注意时序。读没要求。
Dandjinh 回答时间:2020-4-26 10:36:52
EEPROM参数里有个页写时间,一般是5ms,意思是每次写换页要等5ms才能切换下一页,所以写要注意时序。读没要求。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

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

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

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版