野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14944|回复: 12

I2C-EEPROM

[复制链接]
发表于 2014-6-16 16:32:57 | 显示全部楼层 |阅读模式
刚开始看这一部分,觉得比之前的内容难度增加了不少难度。有两个问题,希望得到指点:
第一个:AT24C02的存储容量是2Kbit=256B。例程里定义了一个数组:I2c_Buf_Write,里面有256个数字,每个数字定义的数据类型是:u16,这个
u16怎么定义的,摁了F12怎么找不到定义(看到论坛里也有人问过这个问题)。如果按照,u16=unsigned short int,那么这个应该是16位的,一个数就占了2B,256*2B=512B,这么说,AT24C02存不下啊??
我这个理解是错的,但不知错在哪了,还希望得到指点。
第二个:有没有关于I2C_EE_BufferW_rite()和I2C_EE_BufferRead(),和I2C_EE_PageWrite()的注释,呵呵,看着很吃力。


回复

使用道具 举报

发表于 2014-6-16 16:36:39 | 显示全部楼层

  1. /**
  2.   * @brief   从EEPROM里面读取一块数据
  3.   * @param   
  4.   *    @arg pBuffer:存放从EEPROM读取的数据的缓冲区指针
  5.   *    @arg WriteAddr:接收数据的EEPROM的地址
  6.   *     @arg NumByteToWrite:要从EEPROM读取的字节数
  7.   * @retval  无
  8.   */
  9. void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)
  10. {  
  11.   //*((u8 *)0x4001080c) |=0x80;
  12.     while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // Added by Najoua 27/08/2008   
  13.    
  14.   /* Send START condition */
  15.   I2C_GenerateSTART(I2C1, ENABLE);
  16.   //*((u8 *)0x4001080c) &=~0x80;
  17.   
  18.   /* Test on EV5 and clear it */
  19.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

  20.   /* Send EEPROM address for write */
  21.   I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);

  22.   /* Test on EV6 and clear it */
  23.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  24.   
  25.   /* Clear EV6 by setting again the PE bit */
  26.   I2C_Cmd(I2C1, ENABLE);

  27.   /* Send the EEPROM's internal address to write to */
  28.   I2C_SendData(I2C1, ReadAddr);  

  29.   /* Test on EARM and clear it */
  30.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  31.   
  32.   /* Send STRAT condition a second time */  
  33.   I2C_GenerateSTART(I2C1, ENABLE);
  34.   
  35.   /* Test on EV5 and clear it */
  36.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
  37.   
  38.   /* Send EEPROM address for read */
  39.   I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Receiver);
  40.   
  41.   /* Test on EV6 and clear it */
  42.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
  43.   
  44.   /* While there is data to be read */
  45.   while(NumByteToRead)  
  46.   {
  47.     if(NumByteToRead == 1)
  48.     {
  49.       /* Disable Acknowledgement */
  50.       I2C_AcknowledgeConfig(I2C1, DISABLE);
  51.       
  52.       /* Send STOP Condition */
  53.       I2C_GenerateSTOP(I2C1, ENABLE);
  54.     }

  55.     /* Test on EV7 and clear it */
  56.     if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))  
  57.     {      
  58.       /* Read a byte from the EEPROM */
  59.       *pBuffer = I2C_ReceiveData(I2C1);

  60.       /* Point to the next location where the byte read will be saved */
  61.       pBuffer++;
  62.       
  63.       /* Decrement the read bytes counter */
  64.       NumByteToRead--;        
  65.     }   
  66.   }

  67.   /* Enable Acknowledgement to be ready for another reception */
  68.   I2C_AcknowledgeConfig(I2C1, ENABLE);
  69. }
复制代码
这么多注释~~~
回复 支持 反对

使用道具 举报

发表于 2014-6-16 16:38:00 | 显示全部楼层
数组都是定义成u8的,哪里是u16啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-6-16 16:47:41 | 显示全部楼层
东门安芙 发表于 2014-6-16 16:38
数组都是定义成u8的,哪里是u16啊

这个数组是定义成u8的,但给它里面的元素赋值时,用的是u16 定义的 i, 这里面除了类型强制转换之外,还有别的考虑吗? 或者 为什么i 不是直接定义成u8类型。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-6-16 16:53:10 | 显示全部楼层
随风 发表于 2014-6-16 16:36
这么多注释~~~

嗯,是这注释很详细。如果像点亮流水灯时的程序注释那样,估计就更容易理解,毕竟对不是搞嵌入式的新手来说,看这个程序还是有难度的。
回复 支持 反对

使用道具 举报

发表于 2014-6-16 17:07:49 | 显示全部楼层
陆地行走者 发表于 2014-6-16 16:47
这个数组是定义成u8的,但给它里面的元素赋值时,用的是u16 定义的 i, 这里面除了类型强制转换之外,还有 ...

你的c语言好像觉得不太好,    I2c_Buf_Write = i;  I2c_Buf_Write是8位的,i是16位的,给它赋值它还是一个8位的数据啊
回复 支持 反对

使用道具 举报

发表于 2014-6-16 17:08:30 | 显示全部楼层
陆地行走者 发表于 2014-6-16 16:53
嗯,是这注释很详细。如果像点亮流水灯时的程序注释那样,估计就更容易理解,毕竟对不是搞嵌入式的新手来 ...

对啊,已经每个句子都有注释了还说不详细,不太厚度啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-6-16 17:19:43 | 显示全部楼层
东门安芙 发表于 2014-6-16 17:07
你的c语言好像觉得不太好,    I2c_Buf_Write = i;  I2c_Buf_Write是8位的,i是16位的,给它赋值它还是一 ...

I2c_Buf_Write = i,这个等式左边是8位,右边是16位。“给它赋值它还是一个8位的数据啊”,意思就是,把右边的16位,转换成一个8位的吧,这是所谓的类型转换吧。如果右边那个数的范围超过左边的8位的容量,怎么搞? 如果直接把i定义成u8是不是更直接些呢?或者这里定义成u16有什么其它的考虑?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-6-16 17:20:04 | 显示全部楼层
随风 发表于 2014-6-16 17:08
对啊,已经每个句子都有注释了还说不详细,不太厚度啊

谢谢回答。
回复 支持 反对

使用道具 举报

发表于 2014-6-16 17:32:41 | 显示全部楼层
陆地行走者 发表于 2014-6-16 17:19
I2c_Buf_Write = i,这个等式左边是8位,右边是16位。“给它赋值它还是一个8位的数据啊”,意思就是,把右 ...

那是因为for循环里用到i来计数,i的值最大时会大于256,所以定义成16位,赋值给buffer会有溢出问题,但这里只是一个测试数据,可以这样写。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-6-16 17:47:36 | 显示全部楼层
东门安芙 发表于 2014-6-16 17:32
那是因为for循环里用到i来计数,i的值最大时会大于256,所以定义成16位,赋值给buffer会有溢出问题,但这 ...

嗯,嗯。thank you.
回复 支持 反对

使用道具 举报

发表于 2015-8-18 22:15:40 | 显示全部楼层
对于这一部分的知识   我也有些疑问   请问各位大神。就是野火教程中 硬件I2C_EEPROM程序中
  1. void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)
  2. {
  3.   u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;

  4.   Addr = WriteAddr % I2C_PageSize;
  5.   count = I2C_PageSize - Addr;
  6.   NumOfPage =  NumByteToWrite / I2C_PageSize;
  7.   NumOfSingle = NumByteToWrite % I2C_PageSize;

  8.   /* If WriteAddr is I2C_PageSize aligned  */
  9.   if(Addr == 0)
  10.   {
  11.     /* If NumByteToWrite < I2C_PageSize */
  12.     if(NumOfPage == 0)
  13.     {
  14.       I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  15.       I2C_EE_WaitEepromStandbyState();
  16.     }
  17.     /* If NumByteToWrite > I2C_PageSize */
  18.     else  
  19.     {
  20.       while(NumOfPage--)
  21.       {
  22.         I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
  23.             I2C_EE_WaitEepromStandbyState();
  24.         WriteAddr +=  I2C_PageSize;
  25.         pBuffer += I2C_PageSize;
  26.       }

  27.       if(NumOfSingle!=0)
  28.       {
  29.         I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  30.         I2C_EE_WaitEepromStandbyState();
  31.       }
  32.     }
  33.   }
  34.   /* If WriteAddr is not I2C_PageSize aligned  */
  35.   else
  36.   {
  37.     /* If NumByteToWrite < I2C_PageSize */
  38.     if(NumOfPage== 0)
  39.     {
  40.       I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  41.       I2C_EE_WaitEepromStandbyState();
  42.     }
  43.     /* If NumByteToWrite > I2C_PageSize */
  44.     else
  45.     {
  46.       NumByteToWrite -= count;
  47.       NumOfPage =  NumByteToWrite / I2C_PageSize;
  48.       NumOfSingle = NumByteToWrite % I2C_PageSize;       
  49.       
  50.       if(count != 0)
  51.       {  
  52.         I2C_EE_PageWrite(pBuffer, WriteAddr, count);
  53.         I2C_EE_WaitEepromStandbyState();
  54.         WriteAddr += count;
  55.         pBuffer += count;
  56.       }
  57.       
  58.       while(NumOfPage--)
  59.       {
  60.         I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
  61.         I2C_EE_WaitEepromStandbyState();
  62.         WriteAddr +=  I2C_PageSize;
  63.         pBuffer += I2C_PageSize;  
  64.       }
  65.       if(NumOfSingle != 0)
  66.       {
  67.         I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  68.         I2C_EE_WaitEepromStandbyState();
  69.       }
  70.     }
  71.   }  
  72. }

  73. /**
  74.   * @brief   D′ò&#187;&#184;&#246;×&#214;&#189;úμ&#189;I2C EEPROM&#214;D
  75.   * @param   
  76.   *                @arg pBuffer:&#187;o3&#229;&#199;&#248;&#214;&#184;&#213;&#235;
  77.   *                @arg WriteAddr:D′μ&#216;&#214;·
  78.   * @retval  &#206;T
  79.   */
  80. void I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr)
  81. {
  82.   /* Send STRAT condition */
  83.   I2C_GenerateSTART(I2C1, ENABLE);

  84.   /* Test on EV5 and clear it */
  85.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));  

  86.   /* Send EEPROM address for write */
  87.   I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);
  88.   
  89.   /* Test on EV6 and clear it */
  90.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  91.       
  92.   /* Send the EEPROM's internal address to write to */
  93.   I2C_SendData(I2C1, WriteAddr);
  94.   
  95.   /* Test on EARM and clear it */
  96.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  97.   /* Send the byte to be written */
  98.   I2C_SendData(I2C1, *pBuffer);
  99.    
  100.   /* Test on EARM and clear it */
  101.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  102.   
  103.   /* Send STOP condition */
  104.   I2C_GenerateSTOP(I2C1, ENABLE);
  105. }

  106. /**
  107.   * @brief   &#212;úEEPROMμ&#196;ò&#187;&#184;&#246;D′&#209;-&#187;·&#214;D&#191;éò&#212;D′&#182;à&#184;&#246;×&#214;&#189;ú£&#172;μ&#171;ò&#187;′&#206;D′è&#235;μ&#196;×&#214;&#189;úêy
  108.   *          2&#187;&#196;ü3&#172;1yEEPROMò3μ&#196;′óD&#161;£&#172;AT24C02&#195;&#191;ò3óD8&#184;&#246;×&#214;&#189;ú
  109.   * @param   
  110.   *                @arg pBuffer:&#187;o3&#229;&#199;&#248;&#214;&#184;&#213;&#235;
  111.   *                @arg WriteAddr:D′μ&#216;&#214;·
  112.   *     @arg NumByteToWrite:D′μ&#196;×&#214;&#189;úêy
  113.   * @retval  &#206;T
  114.   */
  115. void I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)
  116. {
  117.     while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // Added by Najoua 27/08/2008
  118.    
  119.   /* Send START condition */
  120.   I2C_GenerateSTART(I2C1, ENABLE);
  121.   
  122.   /* Test on EV5 and clear it */
  123.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
  124.   
  125.   /* Send EEPROM address for write */
  126.   I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);
  127.   
  128.   /* Test on EV6 and clear it */
  129.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  

  130.   /* Send the EEPROM's internal address to write to */   
  131.   I2C_SendData(I2C1, WriteAddr);  

  132.   /* Test on EARM and clear it */
  133.   while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  134.   /* While there is data to be written */
  135.   while(NumByteToWrite--)  
  136.   {
  137.     /* Send the current byte */
  138.     I2C_SendData(I2C1, *pBuffer);

  139.     /* Point to the next byte to be written */
  140.     pBuffer++;
  141.   
  142.     /* Test on EARM and clear it */
  143.     while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  144.   }

  145.   /* Send STOP condition */
  146.   I2C_GenerateSTOP(I2C1, ENABLE);
  147. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2015-8-18 22:18:58 | 显示全部楼层

RE: I2C-EEPROM

aozeahj 发表于 2015-8-18 22:15
对于这一部分的知识   我也有些疑问   请问各位大神。就是野火教程中 硬件I2C_EEPROM程序中

就是41行的    要是当count = I2C_PageSize - Addr;中的count小于NumOfSingle  不是就出现逻辑错误了吗

回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-22 20:20 , Processed in 0.047818 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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