野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 182|回复: 11

STM32__I2C__EEPROM示例代码中的问题

[复制链接]
发表于 2025-1-9 14:41:55 | 显示全部楼层 |阅读模式

在这段代码中,如果写地址没有对齐页,并且写入数据小于页大小时,我认为并不能直接用整页写入。
如果写地址为 WriteAddr = 5,页大小为8,并且要写入 7 字节数据,这是满足上述条件的。那么从地址 5 开始写入 7 字节,写操作将涉及地址 5, 6, 7, 8, 9, 10, 11。这意味着,数据的第四个字节将落在页面边界之后(即页大小为 8 字节,地址 8 是一个新页面的开始)。因此,数据将跨越页面边界。EEPROM 无法跨页面进行写操作

有大佬解答一下我的问题吗?





  1. /**
  2.   * [url=home.php?mod=space&uid=41770]@brief[/url]   将缓冲区中的数据写到I2C EEPROM中
  3.   * @param   
  4.   *        @arg pBuffer:缓冲区指针
  5.   *        @arg WriteAddr:写地址
  6.   *     @arg NumByteToWrite:写的字节数
  7.   * @retval  无
  8.   */
  9. void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)
  10. {
  11.   u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;

  12.   Addr = WriteAddr % I2C_PageSize;
  13.   count = I2C_PageSize - Addr;
  14.   NumOfPage =  NumByteToWrite / I2C_PageSize;
  15.   NumOfSingle = NumByteToWrite % I2C_PageSize;

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

  35.       if(NumOfSingle!=0)
  36.       {
  37.         I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  38.         I2C_EE_WaitEepromStandbyState();
  39.       }
  40.     }
  41.   }
  42.   /* If WriteAddr is not I2C_PageSize aligned  */
  43.   else
  44.   {
  45.     /* If NumByteToWrite < I2C_PageSize */
  46.     if(NumOfPage== 0)
  47.     {
  48.       I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  49.       I2C_EE_WaitEepromStandbyState();
  50.     }
  51.     /* If NumByteToWrite > I2C_PageSize */
  52.     else
  53.     {
  54.       NumByteToWrite -= count;
  55.       NumOfPage =  NumByteToWrite / I2C_PageSize;
  56.       NumOfSingle = NumByteToWrite % I2C_PageSize;   
  57.       
  58.       if(count != 0)
  59.       {  
  60.         I2C_EE_PageWrite(pBuffer, WriteAddr, count);
  61.         I2C_EE_WaitEepromStandbyState();
  62.         WriteAddr += count;
  63.         pBuffer += count;
  64.       }
  65.       
  66.       while(NumOfPage--)
  67.       {
  68.         I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
  69.         I2C_EE_WaitEepromStandbyState();
  70.         WriteAddr +=  I2C_PageSize;
  71.         pBuffer += I2C_PageSize;  
  72.       }
  73.       if(NumOfSingle != 0)
  74.       {
  75.         I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  76.         I2C_EE_WaitEepromStandbyState();
  77.       }
  78.     }
  79.   }  
  80. }
复制代码


回复

使用道具 举报

发表于 2025-1-11 09:01:20 | 显示全部楼层
while(NumOfPage--)
      {
        I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
        I2C_EE_WaitEepromStandbyState();
        WriteAddr +=  I2C_PageSize;
        pBuffer += I2C_PageSize;
      }
写满一页的量就换下一页的地址继续写了,这样就跨页了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-1-11 09:07:13 | 显示全部楼层
菠萝片 发表于 2025-1-11 09:01
while(NumOfPage--)
      {
        I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);

大佬,我的意思是WriteAddr is not I2C_PageSize aligned并且NumByteToWrite < I2C_PageSize,因此NumOfPage = 0,所以程序貌似并不会进入这个while循环
回复 支持 反对

使用道具 举报

发表于 2025-1-11 09:57:05 | 显示全部楼层
那不就是后面的else的逻辑判断了,本身一开始就需要先计算是否对齐,是否满一页然后再进行后续的
野火论坛202501110950332287..png
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-1-11 10:15:34 | 显示全部楼层
本帖最后由 blakeniuniu 于 2025-1-11 10:18 编辑
菠萝片 发表于 2025-1-11 09:57
那不就是后面的else的逻辑判断了,本身一开始就需要先计算是否对齐,是否满一页然后再进行后续的
...

是的,但因为地址没对齐,会不会出现NumByteToWrite < I2C_PageSize,但一页不够写的情况呢?比如页大小是8,从此页最后一个地址开始写2个数据,就会写到下一页,但貌似这种情况下 按代码逻辑中的NumOfPage仍然是0,会进入这部分代码
  1. /* If WriteAddr is not I2C_PageSize aligned  */
  2.   else
  3.   {
  4.     /* If NumByteToWrite < I2C_PageSize */
  5.     if(NumOfPage== 0)
  6.     {
  7.       I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  8.       I2C_EE_WaitEepromStandbyState();
  9.     }
复制代码

但这种情况,如果写地址未对齐页面,并且 NumOfSingle > 当前页面剩余空间,这段代码会尝试进行跨页面写入,导致写入失败或数据不完整。
所以说真正应该比较大小的不是NumByteToWrite 与 I2C_PageSize而是NumByteToWrite 与 当前页面剩余空间?
回复 支持 反对

使用道具 举报

发表于 2025-1-11 10:53:35 | 显示全部楼层
blakeniuniu 发表于 2025-1-11 10:15
是的,但因为地址没对齐,会不会出现NumByteToWrite < I2C_PageSize,但一页不够写的情况呢?比如页大小是 ...

继续往后面看,后面的程序的逻辑不就是处理你说的这个情况了,程序完整看一遍,对齐与否一开始就先判断的,然后再判断是否满一页
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-1-11 11:52:23 | 显示全部楼层
菠萝片 发表于 2025-1-11 10:53
继续往后面看,后面的程序的逻辑不就是处理你说的这个情况了,程序完整看一遍,对齐与否一开始就先判断的 ...

大佬,还是不懂
  1. NumOfPage =  NumByteToWrite / I2C_PageSize;
复制代码

这种情况的NumOfpage是0,但确实一页不够。程序貌似只会进入if(NumOfpage==0),似乎不会进入后面的else来处理,也就是程序不会进入二楼所回复的循环?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-1-12 14:46:14 | 显示全部楼层
  1.         /* 若地址与 SPI_FLASH_PageSize 不对齐  */
  2.   else
  3.   {
  4.                 /* NumByteToWrite < SPI_FLASH_PageSize */
  5.     if (NumOfPage == 0)
  6.     {
  7.                         /*当前页剩余的count个位置比NumOfSingle小,写不完*/
  8.       if (NumOfSingle > count)
  9.       {
  10.         temp = NumOfSingle - count;
  11.                                
  12.                                 /*先写满当前页*/
  13.         SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
  14.         WriteAddr +=  count;
  15.         pBuffer += count;
  16.                                
  17.                                 /*再写剩余的数据*/
  18.         SPI_FLASH_PageWrite(pBuffer, WriteAddr, temp);
  19.       }
  20.       else /*当前页剩余的count个位置能写完NumOfSingle个数据*/
  21.       {                               
  22.         SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
  23.       }
  24.     }
复制代码


这是SPI_FLASH的代码例程,似乎比I2C_eeprom多了些判断逻辑。综上,i2c_eeprom的例程好像是有些问题的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-1-12 14:46:58 | 显示全部楼层
菠萝片 发表于 2025-1-11 10:53
继续往后面看,后面的程序的逻辑不就是处理你说的这个情况了,程序完整看一遍,对齐与否一开始就先判断的 ...

大佬,八楼回复你了
回复 支持 反对

使用道具 举报

发表于 2025-1-13 09:31:27 | 显示全部楼层
blakeniuniu 发表于 2025-1-11 11:52
大佬,还是不懂。
这种情况的NumOfpage是0,但确实一页不够。程序貌似只会进入if(NumOfpage==0),似 ...

谁说不会进入的,这不就是if else判断嘛,本身一页就写完的才NumOfpage==0,一页写不满的就后续的逻辑
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-1-13 17:05:35 | 显示全部楼层
菠萝片 发表于 2025-1-13 09:31
谁说不会进入的,这不就是if else判断嘛,本身一页就写完的才NumOfpage==0,一页写不满的就后续的逻辑 ...

所以说上述情况判断有误,对比下我发的eeprom和flash的例程就能发现两个pagewrite的逻辑不同
回复 支持 反对

使用道具 举报

发表于 7 天前 | 显示全部楼层
blakeniuniu 发表于 2025-1-13 17:05
所以说上述情况判断有误,对比下我发的eeprom和flash的例程就能发现两个pagewrite的逻辑不同 ...

为什么会有误,只能说,你要实在觉得他有问题,实际来读写验证
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2025-1-22 09:36 , Processed in 0.214971 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表