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

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

这个是以前的库吧,我现在用HAL库,是不是就很难移植了
liudejun2020 回答时间:2020-4-26 22:01:08
新手上路
李康1202 回答时间:2020-4-27 18:10:00
toofree 发表于 2020-4-26 09:11
EEPROM不能直接跨页写,要跨页的话,得重新指定一次新的页地址,同时得有一次停止位。
理解一下这段代码, ...

官方IIC好用不
七哥 回答时间:2020-4-27 19:11:14
好用啊,
对于EEPROM操作,5ms的延时最重要,一定要数据对照手册。

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版