logo资料库

基于FPGA的IIC接口驱动设计.pdf

第1页 / 共21页
第2页 / 共21页
第3页 / 共21页
第4页 / 共21页
第5页 / 共21页
第6页 / 共21页
第7页 / 共21页
第8页 / 共21页
资料共21页,剩余部分请下载后查看
FPGA 培训专家 www.zxopen.com 基于 FPGA 的 IIC 接口驱动设计 1. 实验引言 本节我们要学习的内容,简单来说,就是一种串行的通信协议,IIC 的通信 协议和通信接口在很多工程中有广泛的应用,如数据采集领域的串行 AD,图像处 理领域的摄像头配置,工业控制领域的 X 射线管配置等等。除此之外,由于 IIC 协议占用的 IO 资源特别少,连接方便,所以工程中也常选用 IIC 接口做为不同 芯片间的通信协议。 2. 实验目的 IIC 协议的完成靠的是严紧的时序,一个周期都不能错,这也正是我们设置 本实验的目的。通过 IIC 的学习,锻炼自己的时序实现技巧和方法,可以说最佳 的案例之一。 3.实验内容 本实验我们用 FPGA 设计一个满足 IIC 通信协议的接口,读写至芯开发板板 载的 EEPROM,用两个外部按键作为控制端,当“写控制键”按下时,FPGA 向 EEPROM 固定地址写入一个字节的数据,并点亮一个 LED 灯,表示写入成功。当 “读控制按键”按下时,FPGA 从 EEPROM 读出数据,并将该数据显示到数码管。 4.实验原理 1)EEPROM 封装 图1 EEPROM封装 接下来,我们梳理一下各引脚定义: 1.A0,A1,A2 为 24LC64 的片选信号,由于 IIC 总线可以挂载多个 IIC 接口器 件,所以每个器件都应该有自己的“身份标识”,通过对 A0,A1,A2 输入不同的高 至芯科技论坛 www.fpgaw.com
FPGA 培训专家 www.zxopen.com 低电平,就可以设置该 EEPROM 的片选信号。 2.WP 为读写使能信号,当 WP 悬空或者接地,EEPROM 可读可写,当 WP 接电 源,EEPROM 只能读不能写。 3.SCL 为 IIC 接口的时钟线 4.SDA 为 IIC 接口的数据线 2) IIC 接口的读写时序 IIC 接口读写时序分为随机读写(单字节读写)和页面读写(多字节读写), 我们首先来学习随机读写(Byte Write/Read) Byte Write 时序如下: 图 2 单字节写时序 时序解读:如果我们要向 EEPROM 写入一个字节,那么必须经过以下步骤: 1. 发送启动信号 2. 发送控制字 3. 接收并检测 EEPROM 发来的应答信号 ACK 4. 发送高字节地址位 5. 接收并检测 EEPROM 发来的应答信号 ACK 6. 发送低字节地址位 7. 接收并检测 EEPROM 发来的应答信号 ACK 8. 发送 8bit 有效数据 9. 接收并检测 EEPROM 发来的应答信号 ACK 10.发送停止信号 至芯科技论坛 www.fpgaw.com
FPGA 培训专家 www.zxopen.com Byte Read 时序如下: 图 3 单字节读时序 时序解读:如果我们要从 EEPROM 读出一个字节,那么必须经过以下步骤: 1. 发送启动信号 2. 发送控制字 1010_A2A1A0_0 3. 接收并检测 EEPROM 发来的应答信号 ACK 4. 发送高字节地址位 5. 接收并检测 EEPROM 发来的应答信号 ACK 6. 发送低字节地址位 7. 接收并检测 EEPROM 发来的应答信号 ACK 8. 发送启动信号 9. 发送控制字 1010_A2A1A0_1 10. 接收并检测 EEPROM 发来的应答信号 ACK 11. 读取一个字节数据 12. 发送 NO ACK 信号 13. 发送停止信号 3)各步骤具体意义 1.启动信号 图 4 启动信号时序 至芯科技论坛 www.fpgaw.com
FPGA 培训专家 www.zxopen.com 在 SCL 保持高电平期间,如果 SDA 出现由高到低的跳变沿,代表启动信 号 2. 控制字 我们的控制字为 1010_0000,其中 1010 为 EEPROM 的型号标识,为一组固定 的序列,紧接着 A2,A1,A0 就是我们的片选信号,最后一位为读写控制位,低电 平代表写,高电平代表读,我们这里首先需要对 EEPROM 写入地址位,所以我们 最后一位为 0。 3. 高/低位地址 由于 24LC64 有 64Kbit 的存储空间,所以我们需要 13 位的地址位宽才能寻 址所有的存储空间,由于 IIC 协议规定只能以字节形式写入,所以必须将 13 位 的地址扩展为 16 位的地址,分为高八位和低八位,多出来的前三位填充任意数 据即可,对我们的寻址地址没有影响。 3. 停止信号 图 5 停止信号时序 4. 应答信号 ACK 应答信号是由数据接收方发出的,当 SCL 为高电平期间,如果监测到 SDA 为低电平,说明有应答信号。 5. 非应答信号 NO ACK 非应答信号也是由数据接收方发出的,当 SCL 为高电平期间,如果 SDA 为高 电平,说明有非应答信号。 说明:由于 IIC 总线协议启动和停止信号都是在 SCL 高电平期间发生跳变, 这就决定了我们其他数据的改变只能发生在 SCL 低电平期间,在 SCL 为高电平期 间,数据必须保持稳定。即在 SCL 低电平改变数据,在 SCL 高电平采集数据。 至芯科技论坛 www.fpgaw.com
FPGA 培训专家 www.zxopen.com 5. 硬件设计 图 6 EEPROM 典型配置电路 由原理图可知,A2、A1、A0 全部接低电平,那么发送控制字的时候,只需 要将这三个位填充 000 即可。 6.系统结构框图 图 7 系统结构框图 系统端口及其意义如下: 表 1 系统端口及其意义 端口说明 端口名 clk rst_n key_wr 端口功能或意义 系统 50MHz 时钟输入 系统复位 EEPROM 写控制按键 至芯科技论坛 www.fpgaw.com iic_wrseg7_lutclkrst_nResult[7:0]VGAkey_wrkey_rdseg[7:0]sel[2:0]eeprom_scleeprom_sdaled
FPGA 培训专家 www.zxopen.com key_rd seg sel eeprom_scl eeprom_sda led EEPROM 读控制按键 数码管段选 数码管位选 EEPROM 时钟线 EEPROM 双向数据线 数据写入完成指示灯 内部信号及其意义如下: 表 2 内部信号及其意义 内部信号说明 内部信号名 result 内部信号功能或意义 FPGA 从 EEPROM 中读取出来的待显示 数据 7. 代码解释 有器件手册得知,EEPROM 时钟 scl 最高频率不能超过 400KHz,而我们的系统 时钟为 50MHz,因此我们首先需要将时钟进行分频。由上文论述可知,IIC 数据的 改变必须发生在时钟线 SCL 的低电平期间,数据线 sda 在时钟线 scl 为低电平期 间改变,在 scl 高电平期间,数据接收方会读取 sda 上的高低电平。那么怎样才 能读取到稳定的数据呢?最好就是读取数据的时钟线上升沿刚好对在 scl 电平的 中间位置,此时的数据是最可靠、最稳定的。 基于上述设想,我们首先将 50MHz 系统时钟分频成为 400KHz,作为我们整个 系统的同步时钟,负责控制发送和读取数据。然后利用 400KHz 时钟的下降沿进 行二分频,产生 200KHz 的 EEPROM 时钟 scl。由于 scl 在 400KHz 时钟的下降沿 才发生反转,那么 400KHz 时钟的上升沿则刚好落在 EEPROM 时钟 scl 的中间位 置。 至芯科技论坛 www.fpgaw.com
FPGA 培训专家 www.zxopen.com 程序清单 时钟分频 1 //-----------------system clk---------------- 2 //系统时钟分频 3 always @(posedge clk_sys or negedge rst_n) 4 begin 5 if(!rst_n) 6 begin 7 clk<=0; 8 cnt<=0; 9 end 10 else 11 begin 12 if(cnt<250) 13 cnt<=cnt+1'b1; 14 else 15 begin 16 clk<=~clk; 17 cnt<=0; 18 end 19 end 20 end 21 //-----------------eeprom scl----------------- 22 //产生 eeprom scl 信号 23 always @(negedge clk or negedge rst_n) 24 begin 25 if(!rst_n) 26 begin 27 eeprom_scl<=0; 28 end 29 else 30 eeprom_scl<=~eeprom_scl; 31 end eeprom_scl 生成完毕,接下来我们就可以驱动 eeprom_sda,发送或读取数据。 那么第一步,首先应该发送的是启动信号,以下代码为状态机的一个状态,在复 位的时候,link_sda==1,sda_buf==1,因此 eeprom_sda 输出的是高电平,当状态到 1 时,在 eeprom_scl 为高电平期间,将 sda_buf 置为 0,出现下降的跳变沿,则 启动信号发送成功。 至芯科技论坛 www.fpgaw.com
FPGA 培训专家 www.zxopen.com assign eeprom_sda=(link_sda)?sda_buf:1'hz; 1:begin 程序清单 发送启动信号 if(eeprom_scl)//高电平期间,使 sda 由高变低,启动串行传输 begin sda_buf<=0; state<=2; data<=8'b10100000;//写控制字准备 end end 启动信号发送完毕以后,紧接着应该发送控制字,我们这里使用位拼接的方 式实现并串转换,在 eeprom_scl 为低电平期间,将八个比特的数据依次发出。 程序清单 并串转换 1 //--------------send countral word-------------- 2 2:begin 3 if((counter<8)&&(!eeprom_scl))//在 scl 低电平期间, 完成并串转换,发出写控制字 4 begin 5 counter<=counter+1'b1; 6 data<={data[6:0],data[7]}; 7 sda_buf<=data[7]; 8 end 9 else if((counter==8)&&(!eeprom_scl)) 10 begin 11 counter<=0; 12 state<=3; 13 link_sda<=0;//FPGA 释放总线控制权 14 end 15 end 控制字发送结束以后,需要检测接收 EEPROM 发送回来的应答信号 ACK,即 eeprom_scl 为高电平,而 eeprom_sda 为低电平。 程序清单 检测应答信号 1 //--------------receive ack singial-------------- 2 3:begin 3 if(eeprom_scl)//在 scl 高电平期间,检测是否有应答信号 4 begin 5 if(!eeprom_sda) 6 begin 7 state<=4;//有应答则状态继续跳转 至芯科技论坛 www.fpgaw.com
分享到:
收藏