fire 发表于 2016-1-23 11:32:30

【F1-I2C】I2C_EE_BufferWrite()函数的解惑,谁看谁明白

buffer写这个函数很简单,简单是因为我们只是调用而没有看代码的实现,很多初学的用户去看里面的
代码的时候就有很多疑问了,自己把自己绕晕。

其实要想看懂这个函数的代码,只要抓住两个要点即可:一是EEPROM页写的时候一次只能写8个字节,超过8个字节的时候会从该页重新开始写,那这是要不得的,我们要特殊处理,具体怎么处理呢?看第二点

二是为了解决EEPROM一页只能写8字节的情况,我们在代码上分两种情况:①写地址跟EEPROM页写地址对齐的时候,这部分代码很好理解,直接整页整页的写,然后把剩下的少于页字节数的写完即可,②写地址

跟EEPROM页写地址没有对齐的时候,这个时候先算出写地址到页写的对齐地址还差多少个字节,然后先把这部分差的字节写完,写完之后的写地址就又是对齐到页写地址了,剩下的代码重复①部即可,理解起来就那么简单。

/**
* @brief   将缓冲区中的数据写到I2C EEPROM中,采用页写入的方式,加快写入速度
*      @param         pBuffer:缓冲区指针
*      @param         WriteAddr:写地址
* @param         NumByteToWrite:写的字节数
* @retval无
*/
void I2C_EE_BufferWrite(uint8_t* pBuffer, uint8_t WriteAddr, u16 NumByteToWrite)
{
uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0,temp=0;

      /*mod运算求余,若writeAddr是I2C_PageSize整数倍,运算结果Addr值为0*/
Addr = WriteAddr % I2C_PageSize;
      
      /*差count个数据值,刚好可以对齐到页地址*/
count = I2C_PageSize - Addr;
      /*计算出要写多少整数页*/
NumOfPage =NumByteToWrite / I2C_PageSize;
      /*mod运算求余,计算出剩余不满一页的字节数*/
NumOfSingle = NumByteToWrite % I2C_PageSize;

/* Addr=0,则WriteAddr 刚好按页对齐 aligned*/
if(Addr == 0)
{
    /* 如果 NumByteToWrite < I2C_PageSize */
    if(NumOfPage == 0)
    {
      I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
      I2C_EE_WaitEepromStandbyState();
    }
    /* 如果 NumByteToWrite > I2C_PageSize */
    else
    {
                        /*先把整数页都写了*/
      while(NumOfPage--)
      {
      I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
      I2C_EE_WaitEepromStandbyState();
      WriteAddr +=I2C_PageSize;
      pBuffer += I2C_PageSize;
      }
                        
                        /*若有多余的不满一页的数据,把它写完*/
      if(NumOfSingle!=0)
      {
      I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
      I2C_EE_WaitEepromStandbyState();
      }
    }
}
/* 如果 WriteAddr 不是按 I2C_PageSize 对齐*/
else
{
    /* 如果 NumByteToWrite < I2C_PageSize */
    if(NumOfPage== 0)
    {      
                        /*若NumOfSingle>count,当前面写不完,要写到下一页*/
                        if (NumOfSingle > count)
      {
      temp = NumOfSingle - count;

      I2C_EE_PageWrite(pBuffer, WriteAddr, count);
                              I2C_EE_WaitEepromStandbyState();
      WriteAddr +=count;
      pBuffer += count;

      I2C_EE_PageWrite(pBuffer, WriteAddr, temp);
                              I2C_EE_WaitEepromStandbyState();
      }
      else /*若count比NumOfSingle大*/
      {
      I2C_EE_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
                              I2C_EE_WaitEepromStandbyState();
      }
    }
    /* 如果 NumByteToWrite > I2C_PageSize */
    else
    {
                        /*地址不对齐多出的count分开处理,不加入这个运算*/
      NumByteToWrite -= count;
      NumOfPage =NumByteToWrite / I2C_PageSize;
      NumOfSingle = NumByteToWrite % I2C_PageSize;      
      
                        /*先把WriteAddr所在页的剩余字节写了*/
      if(count != 0)
      {
      I2C_EE_PageWrite(pBuffer, WriteAddr, count);
      I2C_EE_WaitEepromStandbyState();
                              
                              /*WriteAddr加上count后,地址就对齐到页了*/
      WriteAddr += count;
      pBuffer += count;
      }
      /*把整数页都写了*/
      while(NumOfPage--)
      {
      I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
      I2C_EE_WaitEepromStandbyState();
      WriteAddr +=I2C_PageSize;
      pBuffer += I2C_PageSize;
      }
                        /*若有多余的不满一页的数据,把它写完*/
      if(NumOfSingle != 0)
      {
      I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
      I2C_EE_WaitEepromStandbyState();
      }
    }
}
}

fire 发表于 2016-1-23 11:32:50

着重理解帖子上红色字体部分,还是看不懂的跟帖提问吧   

猕猴桃11 发表于 2016-1-26 10:39:19

确实是新程序,把原来的bug修改了。

fire 发表于 2016-1-27 17:19:23

猕猴桃11 发表于 2016-1-26 10:39
确实是新程序,把原来的bug修改了。

原来那个bug是你发现的         

luoyuchenxiao 发表于 2016-3-27 18:05:15

之前那个程序有点小问题吧火哥当时没有考虑NumOfSingle和count的大小吧 这样一看完全没问题了:lol:lol:lol:lol

yxazxw 发表于 2016-3-30 11:19:14

哎,看了fire的库开发指南,死角还真是不少,MP3那个实验就有很多死角

yxazxw 发表于 2016-3-30 11:20:39

fire 发表于 2016-1-27 17:19
原来那个bug是你发现的

http://www.firebbs.cn/thread-11474-1-1.html
页: [1]
查看完整版本: 【F1-I2C】I2C_EE_BufferWrite()函数的解惑,谁看谁明白