博士
最后登录1970-1-1
在线时间 小时
注册时间2015-11-21
|
本帖最后由 qduwg 于 2015-12-20 11:49 编辑
研究到读写EEPROM了。发现一个很奇妙的问题。就是EEPROM都是以页为单位来写和读的。所以,读写的时候要分好几个情况来区别对待才行。火哥的样例代码,只是完整的读写256个数组到EEPROM。改一下读写的开始地址和数量,就会发现运行的结果是不对的。我仔细研究了半天。把各种可能的情况都考虑周全了。写了下面的这个函数。参考火哥的样例。加上了注释哦。感谢火哥!
重要的写函数如下:
- void I2C_EE_BufferWrite(u8* pBuffer,u8 WriteAddr,u16 NumByteToWrite) <font color="#ff0000">//重要的一个函数。</font>
- { u8 NumOfSingle=0,Addr=0,count=0,NumOfSingle2=0;
- int NumOfPage=0,NumOfPage2=0;
- Addr=WriteAddr%I2C_PageSize;
- count=I2C_PageSize-Addr;
- NumOfPage=NumByteToWrite/I2C_PageSize;
- NumOfSingle=NumByteToWrite%I2C_PageSize;
- if(Addr==0) //针对页地址为一页开始的情况
- { if(NumOfPage==0) //8 的倍数的整数页地址,页小于1的情况。不到一页时的显示。都是正确的。超过一页也对
- {I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);
- I2C_EE_WaitEepromStandbyState();
- }
- else
- {while(NumOfPage--) //针对超过一页时显示。但是页起始地址是8的倍数。也就是页的边缘。都是可以任意个数写入。
- {I2C_EE_PageWrite(pBuffer,WriteAddr,I2C_PageSize);
- I2C_EE_WaitEepromStandbyState();
- WriteAddr+=I2C_PageSize; //写入地址可以是增一页的距离。比较方便
- pBuffer+=I2C_PageSize;
- if(NumOfPage==0) break; //这里的条件必须单独加上,while后面的的自减是一直在减,不判断是否为0.
- }
- if(NumOfPage==0) <font color="#ff0000">//这里条件应该是等于0才对。</font>
- {I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);
- I2C_EE_WaitEepromStandbyState();
- }
- }
- }
- else //针对起始地址不在页边界的情况,比较复杂。需要判断多种可能的情况。
- {if(NumOfPage==0) //针对不到一页8个字节的情况
- {
- //需要判断加上输出字节数后,是否超出一页的范围。然后决定写入范围。
- if(WriteAddr%8+NumByteToWrite<=8) //如果不到一页,直接输出即可,比如2开始,输出3个。1,2,3,或者6个都可以
- //因为2+6=8,2+3<=8都是可以输出的。
-
- I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);
- I2C_EE_WaitEepromStandbyState();
- }
- else //页数不为0.关键所在。起始地址不是0.总数超过一页字节数。带有零头了。比如从2号地址,输入12个字节
- {NumByteToWrite-=count; //去掉开始的count个字节,剩余要写的字节
- NumOfPage=NumByteToWrite/I2C_PageSize; //判断几页剩余
- NumOfSingle=NumByteToWrite%I2C_PageSize;//剩下的零头
- if(count!=0) //如果count不是0,说明需要先填补这个几个位置。
- {I2C_EE_PageWrite(pBuffer,WriteAddr,count); //比如从2开始,先填满8-2个。1,2,3,4,5,6.
- I2C_EE_WaitEepromStandbyState();
- WriteAddr+=count; //I2C_PageSize*NumOfPage; 写入地址的增加不是一整页了。是零头了。指向下一页开始
- pBuffer+=count;
- }
- if(NumOfPage>0) <b> //需要判断一下是否有整页数据需要写入。</b>
- {
- while(NumOfPage--) //开始下面剩余的页的写入。
- {I2C_EE_PageWrite(pBuffer,WriteAddr,I2C_PageSize);
- I2C_EE_WaitEepromStandbyState();
- WriteAddr+=I2C_PageSize; //步长增加以页面为单位。增加8.
- pBuffer+=I2C_PageSize;
- if(NumOfPage==0) break; //防止变量从0减一后变成FF,判断出错。加上判断。
- }
- }
- if(NumOfPage==0) //如果没有整页数据可写,或者写完整页后,把零头继续写进去。
- {I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle); //最后输出零头个数字节
- I2C_EE_WaitEepromStandbyState();
- }
- }
- }
- }
复制代码
|
|