本帖最后由 梦翼师兄 于 2015-12-21 15:35 编辑
本节我们要学习的内容,简单来说,就是一种串行的通信协议,IIC的通信协议和通信接口在很多工程中有广泛的应用,如数据采集领域的串行AD,图像处理领域的摄像头配置,工业控制领域的X射线管配置等等。除此之外,由于IIC协议占用的IO资源特别少,连接方便,所以工程中也常选用IIC接口做为不同芯片间的通信协议。 IIC协议的完成靠的是严紧的时序,一个周期都不能错,这也正是我们设置本实验的目的。通过IIC的学习,锻炼自己的时序实现技巧和方法,可以说最佳的案例之一。 本实验的学习,我们采用的外部接口芯片为EEPROM,其封装图如下: 接下来,我们梳理一下各引脚定义: 1. A0,A1,A2为24LC64的片选信号,由于IIC总线可以挂载多个IIC接口器件,所以每个器件都应该有自己的“身份标识”,通过对A0,A1,A2输入不同的高低电平,就可以设置该EEPROM的片选信号。 2. WP为读写使能信号,当WP悬空或者接地,EEPROM可读可写,当WP接电源,EEPROM只能读不能写。 3. SCL为IIC接口的时钟线 4. SDA为IIC接口的数据线
得到了上面的配置信息,那么接下来,看一下我们开发板的配置原理图 由此可以看出我们的位选信号为“000”,EEPROM可读写。 原理图分析完毕,接下来我们看一下IIC接口的具体时序是什么。IIC读写时序分为随机读写和页面读写,也就是常说的Byte Write/Read 和Page Write/Read。 我们首先来学习Byte Write/Read时序
Byte Write时序如下: 由时序图可以看出,如果我们要向EEPROM写入一个字节,那么必须经过以下步骤: 1. 发送启动信号 2. 发送控制字 3. 接收并检测EEPROM发来的应答信号ACK 4. 发送高字节地址位 5. 接收并检测EEPROM发来的应答信号ACK 6. 发送低字节地址位 7. 接收并检测EEPROM发来的应答信号ACK 8. 发送8bit有效数据 9. 接收并检测EEPROM发来的应答信号ACK 10.发送停止信号
Byte Read时序如下: 由时序图可以看出,如果我们要从EEPROM读出一个字节,那么必须经过以下步骤: 1. 发送启动信号 2. 发送控制字1010_0000 3. 接收并检测EEPROM发来的应答信号ACK 4. 发送高字节地址位 5. 接收并检测EEPROM发来的应答信号ACK 6. 发送低字节地址位 7. 接收并检测EEPROM发来的应答信号ACK 8. 发送启动信号 9. 发送控制字1010_0001 10.接收并检测EEPROM发来的应答信号ACK 11.读取一个字节数据 12.发送NOACK信号 13.发送停止信号
那么现在的问题就变成了每个步骤的意义到底是什么呢?各位且听我慢慢道来。
1. 启动信号 在SCL保持高电平期间,如果SDA出现由高到低的跳变沿,代表启动信号 1. 控制字 我们的控制字为1010_0000,其中1010为EEPROM的型号标识,为一组固定的序列,紧接着A2,A1,A0就是我们的片选信号,最后一位为读写控制位,低电平代表写,高电平代表读,我们这里首先需要对EEPROM写入地址位,所以我们最后一位为0。 2. 高/低位地址 由于24LC64有64Kbit的存储空间,所以我们需要13位的地址位宽才能寻址所有的存储空间,由于IIC协议规定只能以字节形式写入,所以必须将13位的地址扩展为16位的地址,分为高八位和低八位,多出来的前三位填充任意数据即可,对我们的寻址地址没有影响。
3. 停止信号 在SCL保持高电平期间,如果SDA出现由低到高的跳变沿,代表停止信号 1. 应答信号ACK 应答信号是由数据接收方发出的,当SCL为高电平期间,如果监测到SDA为低电平,说明有应答信号。 2. 非应答信号ACK 非应答信号也是由数据接收方发出的,当SCL为高电平期间,如果SDA为高电平,说明有非应答信号。
由于IIC总线协议启动和停止信号都是在SCL高电平期间发生跳变,这就决定了我们其他数据的改变只能发生在SCL低电平期间,在SCL为高电平期间,数据必须保持稳定。即在SCL低电平改变数据,在SCL高电平采集数据。
接下来,我们分析项目需求如下: 用两个按键控制EEPROM读写,当写按键按下时,向EEPROM某一固定地址写入一个字节数据,当读按键按下时,将该地址数据读出,并显示到数码管。
我们设计顶层架构如下: 说明:LED灯是一个标志信号,LED亮说明数据写入完毕
由于读时序和写时序一直到低字节地址的写入都是相同的,因此我们设置IIC控制器流程图如下: 具体代码如下:
接下来,我们编写数码管驱动模块如下:
编写顶层模块如下:
接下来,我们可以编写简单的测试代码,验证逻辑是否正确,测试代码如下:
审查这个简单的测试,我们发现这个测试真的很简单,简单到连反馈的ACK信号都没有了,可是我们的IIC控制器,必须要检测到ACK信号,状态才会向下跳转,怎么办呢?我这里教给大家一个最简单的办法,那就是在测试的时候屏蔽掉ACK检测,状态直接向下跳转,当然有兴趣的同学,可以编写较复杂的测试,加上反馈信号,这样是最完美的。我们的代码就可以改成如下形式: 所有检测ACK的状态修改完毕以后,我们仿真如下 由仿真图可以看出当读写按键按下时,电路都会产生对应的动作,写时序如下: 读时序如下: 这里有一些需要注意的点: 如图所示,数据的改变、数据总线的放开都是在SCL低电平的中间位置实现的。 通过上面的学习,我们实现了页面读写,由于数码管前面的章节中已经学习过,所以此处不再赘述。 接下来,我们学习一下PageWrite/Read时序 Page Write时序如下: Page Read时序如下: 由此可以看出,页面读写和随机读写只是多加了几个状态而已,在我们前面设计的基础上加几个状态就可以完成。我们把这部分交给大家去发挥。
|