IIC学习的简单问题3?

2019-08-17 01:50发布

   在研究原子哥的代码过程中总有好多疑问。
  我先把有疑问的原子例程部分代码粘贴一下。
u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{
  u8 temp=0;
IIC_Start();
if(EE_TYPE>AT24C16)
{
  IIC_Send_Byte(0XA0);
  IIC_Wait_Ack();
  IIC_Send_Byte(ReadAddr>>8);
  IIC_Wait_Ack();
}else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));
  IIC_Wait_Ack();     
  IIC_Send_Byte(ReadAddr%256);   //发送低地址      
   IIC_Wait_Ack();
IIC_Start();  
IIC_Send_Byte(0XA1);           //进入接收模式      
  IIC_Wait_Ack();  
   temp=IIC_Read_Byte(0);     
   IIC_Stop();//产生一个停止条件     
  return temp;

}
这段代码是IIC例程中读取EEPROM数据的函数,我根据我找到的资料对照例程一步一步分析,有些部分不太理解。我先把资料粘贴一下。
主器件通过发送一个起始信号启动发送过程,然后发送它所要寻址的从器件的地址,8位从器件地址的高4位固定为1010,接下来的3位A2A1A0为器件的地址位,用来定义哪个器件
以及器件的哪个部分被主器件访问,可单独被系统寻址从器件8位地址的最低位作为读写控制位,1表示对从器件进行读操作,0表示对从器件进行写操作。
在主器件发送起始信号和从器件地址字节后CAT24C02监视总线,并当其地址与发送的从地址相符时响应一个应答信号。CAT24C02再根据读写控制位R/W的状态进行读或写操作。

这是百度文库里找到的24C02的中文手册中的话,我总结一下就是:
1、主器件先发送一个起始信号给24C02
2、发送从器件地址
3、当24C02发现从期间地址和自己的地址相同时会产生一个应答信号
4、根据R/W控制位的状态进行读写操作。
下面是问题:
1、ReadAddr这个地址是什么地址,存储开始的地址吗?0XA0我知道是 1010 0000,那ReadAddr这个地址是用来填写A2A1A0这三个位的吗?这个地址为什么是u16?
2、为什么在代码中有两次起始信号IIC_Start();?在启动信号之后不会将EEPROM复位吗?我将第二个启动信号注释掉之后程序就不能正常运行了。很想知道第二个启动信号是什么作用。
3、我看到有很多人问问题时用的不是粘贴代码,而是可以用带颜 {MOD}的滚动代码我想知道是怎么做到的,这样以后问问题看的人更方便一点。








友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
6条回答
Acuity
1楼-- · 2019-08-17 05:48
1、ReadAddr是存储地址,24c02为2k bit即256字节,此时有效地址范围为0——255,对应24c02用u8即可,但为兼容更大容量系列的EEPROM,设置为u16型,比如24c16/24c32;0xA0是器件地址,A2A1A0是可选器件地址,就是i2c总线最多可以挂8个24c02,详细看24c02数据手册以及理解i2c总线。
2、2次起始信号由EEPROM的读时序图决定,为什么写时序图不用两次?手册规定的!个人觉得可以这样理解:读数据时,先是写状态,后是读状态,所以需要2次i2c启动信号;写数据时:一直是写状态,所以不需再次启动信号了。
3、这个得版主回答。。
beyond696
2楼-- · 2019-08-17 11:22
1,ReadAddr是内部寄存器地址,不是A2A1A0引脚决定的,A2A1A0引脚是决定的设备地址;
2,每次发送从机地址的时候都需要产生一个启动信号,比如在读寄存器数据的时候,先产生一个启动信号,然后发送从机地址,然后再发送内部寄存器地址,然后再产生启动信号,再发送从机地址,然后再读数据;
3,发帖时候添加代码文字就可以了?
我做的USB2IIC适配器:https://item.taobao.com/item.htm ... amp;id=545509364910

WriteRead.png
WWCool
3楼-- · 2019-08-17 13:00
Acuity 发表于 2017-7-10 15:50
1、ReadAddr是存储地址,24c02为2k bit即256字节,此时有效地址范围为0——255,对应24c02用u8即可,但为兼 ...

还有一个问题哈,IIC_Send_Byte(0XA0+((ReadAddr/256)<<1)); 这里为什么将数据地址和器件地址相加呢,作用是什么。
Acuity
4楼-- · 2019-08-17 16:57
WWCool 发表于 2017-7-10 17:20
还有一个问题哈,IIC_Send_Byte(0XA0+((ReadAddr/256)

1、这个是对于24c04-24c16有效,相当于翻页(256字节)功能;因为此时的存储地址都是占1字节,大于255地址时,增加一个大页地址标识,每增加一个大页(256字节)曾占用一个地址选择线(A2A1A0),24c16(2K字节)占用了3跟地址线(A2A1A0)。换句话说一根i2c总线可以挂8个24c02,4个24c04,2个24c08,1个24c16.
2、从24c32开始,地址空间为2字节,则不占用地址线。
qq1079051122
5楼-- · 2019-08-17 19:57
 精彩回答 2  元偷偷看……
beyond696
6楼-- · 2019-08-18 01:18
常用的I2C读写操作时序图
http://www.usbxyz.com/archives/309

一周热门 更多>