野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11418|回复: 6

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

[复制链接]
发表于 2016-1-23 11:32:30 | 显示全部楼层 |阅读模式
buffer写这个函数很简单,简单是因为我们只是调用而没有看代码的实现,很多初学的用户去看里面的
代码的时候就有很多疑问了,自己把自己绕晕。

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

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

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

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

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

  20.   /* Addr=0,则WriteAddr 刚好按页对齐 aligned  */
  21.   if(Addr == 0)
  22.   {
  23.     /* 如果 NumByteToWrite < I2C_PageSize */
  24.     if(NumOfPage == 0)
  25.     {
  26.       I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  27.       I2C_EE_WaitEepromStandbyState();
  28.     }
  29.     /* 如果 NumByteToWrite > I2C_PageSize */
  30.     else  
  31.     {
  32.                         /*先把整数页都写了*/
  33.       while(NumOfPage--)
  34.       {
  35.         I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
  36.         I2C_EE_WaitEepromStandbyState();
  37.         WriteAddr +=  I2C_PageSize;
  38.         pBuffer += I2C_PageSize;
  39.       }
  40.                         
  41.                         /*若有多余的不满一页的数据,把它写完*/
  42.       if(NumOfSingle!=0)
  43.       {
  44.         I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  45.         I2C_EE_WaitEepromStandbyState();
  46.       }
  47.     }
  48.   }
  49.   /* 如果 WriteAddr 不是按 I2C_PageSize 对齐  */
  50.   else
  51.   {
  52.     /* 如果 NumByteToWrite < I2C_PageSize */
  53.     if(NumOfPage== 0)
  54.     {        
  55.                         /*若NumOfSingle>count,当前面写不完,要写到下一页*/
  56.                         if (NumOfSingle > count)
  57.       {
  58.         temp = NumOfSingle - count;

  59.         I2C_EE_PageWrite(pBuffer, WriteAddr, count);
  60.                                 I2C_EE_WaitEepromStandbyState();
  61.         WriteAddr +=  count;
  62.         pBuffer += count;

  63.         I2C_EE_PageWrite(pBuffer, WriteAddr, temp);
  64.                                 I2C_EE_WaitEepromStandbyState();
  65.       }
  66.       else /*若count比NumOfSingle大*/
  67.       {
  68.         I2C_EE_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
  69.                                 I2C_EE_WaitEepromStandbyState();
  70.       }
  71.     }
  72.     /* 如果 NumByteToWrite > I2C_PageSize */
  73.     else
  74.     {
  75.                         /*地址不对齐多出的count分开处理,不加入这个运算*/
  76.       NumByteToWrite -= count;
  77.       NumOfPage =  NumByteToWrite / I2C_PageSize;
  78.       NumOfSingle = NumByteToWrite % I2C_PageSize;        
  79.       
  80.                         /*先把WriteAddr所在页的剩余字节写了*/
  81.       if(count != 0)
  82.       {  
  83.         I2C_EE_PageWrite(pBuffer, WriteAddr, count);
  84.         I2C_EE_WaitEepromStandbyState();
  85.                                 
  86.                                 /*WriteAddr加上count后,地址就对齐到页了*/
  87.         WriteAddr += count;
  88.         pBuffer += count;
  89.       }
  90.       /*把整数页都写了*/
  91.       while(NumOfPage--)
  92.       {
  93.         I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
  94.         I2C_EE_WaitEepromStandbyState();
  95.         WriteAddr +=  I2C_PageSize;
  96.         pBuffer += I2C_PageSize;  
  97.       }
  98.                         /*若有多余的不满一页的数据,把它写完*/
  99.       if(NumOfSingle != 0)
  100.       {
  101.         I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  102.         I2C_EE_WaitEepromStandbyState();
  103.       }
  104.     }
  105.   }  
  106. }
复制代码

回复

使用道具 举报

 楼主| 发表于 2016-1-23 11:32:50 | 显示全部楼层
着重理解帖子上红色字体部分,还是看不懂的跟帖提问吧   
回复 支持 反对

使用道具 举报

发表于 2016-1-26 10:39:19 | 显示全部楼层
确实是新程序,把原来的bug修改了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-1-27 17:19:23 | 显示全部楼层
猕猴桃11 发表于 2016-1-26 10:39
确实是新程序,把原来的bug修改了。

原来那个bug是你发现的           
回复 支持 反对

使用道具 举报

发表于 2016-3-27 18:05:15 | 显示全部楼层
之前那个程序有点小问题吧火哥  当时没有考虑NumOfSingle和count的大小吧 这样一看完全没问题了
回复 支持 反对

使用道具 举报

发表于 2016-3-30 11:19:14 | 显示全部楼层
哎,看了fire的库开发指南,死角还真是不少,MP3那个实验就有很多死角
回复 支持 反对

使用道具 举报

发表于 2016-3-30 11:20:39 | 显示全部楼层
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-19 08:41 , Processed in 0.031733 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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