野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 13055|回复: 3

开源一个读写EEPROM的代码:可以从任意位置开始,写入256以内的任意字节数!

[复制链接]
发表于 2015-12-20 11:41:51 | 显示全部楼层 |阅读模式
本帖最后由 qduwg 于 2015-12-20 11:49 编辑

研究到读写EEPROM了。发现一个很奇妙的问题。就是EEPROM都是以页为单位来写和读的。所以,读写的时候要分好几个情况来区别对待才行。火哥的样例代码,只是完整的读写256个数组到EEPROM。改一下读写的开始地址和数量,就会发现运行的结果是不对的。我仔细研究了半天。把各种可能的情况都考虑周全了。写了下面的这个函数。参考火哥的样例。加上了注释哦。感谢火哥!

重要的写函数如下:

  1. void I2C_EE_BufferWrite(u8* pBuffer,u8 WriteAddr,u16 NumByteToWrite) <font color="#ff0000">//重要的一个函数。</font>
  2. {        u8 NumOfSingle=0,Addr=0,count=0,NumOfSingle2=0;
  3.         int NumOfPage=0,NumOfPage2=0;
  4.         Addr=WriteAddr%I2C_PageSize;
  5.         count=I2C_PageSize-Addr;
  6.         NumOfPage=NumByteToWrite/I2C_PageSize;
  7.         NumOfSingle=NumByteToWrite%I2C_PageSize;
  8.         if(Addr==0)              //针对页地址为一页开始的情况
  9.         { if(NumOfPage==0)       //8 的倍数的整数页地址,页小于1的情况。不到一页时的显示。都是正确的。超过一页也对
  10.                 {I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);
  11.                         I2C_EE_WaitEepromStandbyState();
  12.                 }
  13.                 else
  14.                 {while(NumOfPage--)    //针对超过一页时显示。但是页起始地址是8的倍数。也就是页的边缘。都是可以任意个数写入。
  15.                         {I2C_EE_PageWrite(pBuffer,WriteAddr,I2C_PageSize);
  16.                                 I2C_EE_WaitEepromStandbyState();
  17.                                 WriteAddr+=I2C_PageSize;  //写入地址可以是增一页的距离。比较方便
  18.                                 pBuffer+=I2C_PageSize;
  19.                                 if(NumOfPage==0) break;            //这里的条件必须单独加上,while后面的的自减是一直在减,不判断是否为0.
  20.                         }
  21.                         if(NumOfPage==0)   <font color="#ff0000">//这里条件应该是等于0才对。</font>
  22.                    {I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);
  23.                           I2C_EE_WaitEepromStandbyState();
  24.                    }
  25.                 }
  26.         }
  27.         else                      //针对起始地址不在页边界的情况,比较复杂。需要判断多种可能的情况。
  28.         {if(NumOfPage==0)          //针对不到一页8个字节的情况
  29.                 {
  30.                         //需要判断加上输出字节数后,是否超出一页的范围。然后决定写入范围。
  31.                         if(WriteAddr%8+NumByteToWrite<=8) //如果不到一页,直接输出即可,比如2开始,输出3个。1,2,3,或者6个都可以
  32.                                                                 //因为2+6=8,2+3<=8都是可以输出的。
  33.                         
  34.                         I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);
  35.                         I2C_EE_WaitEepromStandbyState();
  36.                 }
  37.                 else                    //页数不为0.关键所在。起始地址不是0.总数超过一页字节数。带有零头了。比如从2号地址,输入12个字节
  38.                 {NumByteToWrite-=count;  //去掉开始的count个字节,剩余要写的字节
  39.            NumOfPage=NumByteToWrite/I2C_PageSize;  //判断几页剩余
  40.            NumOfSingle=NumByteToWrite%I2C_PageSize;//剩下的零头
  41.                                 if(count!=0)          //如果count不是0,说明需要先填补这个几个位置。
  42.                                 {I2C_EE_PageWrite(pBuffer,WriteAddr,count);  //比如从2开始,先填满8-2个。1,2,3,4,5,6.
  43.                            I2C_EE_WaitEepromStandbyState();
  44.                                  WriteAddr+=count;  //I2C_PageSize*NumOfPage; 写入地址的增加不是一整页了。是零头了。指向下一页开始
  45.                                  pBuffer+=count;
  46.                                 }
  47.                                 if(NumOfPage>0)   <b> //需要判断一下是否有整页数据需要写入。</b>
  48.                                 {
  49.                                 while(NumOfPage--)  //开始下面剩余的页的写入。
  50.                           {I2C_EE_PageWrite(pBuffer,WriteAddr,I2C_PageSize);
  51.                                 I2C_EE_WaitEepromStandbyState();
  52.                                 WriteAddr+=I2C_PageSize;  //步长增加以页面为单位。增加8.
  53.                                 pBuffer+=I2C_PageSize;
  54.                                 if(NumOfPage==0) break;   //防止变量从0减一后变成FF,判断出错。加上判断。
  55.                     }
  56.                           }
  57.                                 if(NumOfPage==0)   //如果没有整页数据可写,或者写完整页后,把零头继续写进去。
  58.                    {I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle); //最后输出零头个数字节
  59.                           I2C_EE_WaitEepromStandbyState();
  60.                    }
  61.           }
  62.   }
  63. }
复制代码


读写EPROM.jpg

回复

使用道具 举报

 楼主| 发表于 2015-12-20 11:50:34 | 显示全部楼层
EEPROM的任意读写,可以好好研究了。我反正是研究了半天。依次跟踪函数进去的。的确写的很优美的STM32库啊。值得借鉴。
回复 支持 反对

使用道具 举报

发表于 2015-12-21 09:35:10 | 显示全部楼层
在eeprom的例程里不是本身有这个函数吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-12-21 11:58:27 | 显示全部楼层
flyleaf 发表于 2015-12-21 09:35
在eeprom的例程里不是本身有这个函数吗?

是有这个函数的。但是因为逻辑判断上有问题。导致任意写入字节数,任意起始位置时,出错。呵呵。
这个while(NumOfPage--)语句,里面的自减表达式减到0时,还会进入下次循环,继续减一的。造成不会退出循环。也就是永远不到0.。不知道为什么这个地方是这样的。所以,必须另外加一个if语句进行判断,是否到0了。如果到了,跳出循环。
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-28 23:41 , Processed in 0.034491 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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