基于FPGA的模拟IIC接口设计与实现

合集下载

基于FPGA的I2C实验Verilog源代码

基于FPGA的I2C实验Verilog源代码

`timescale 1ns / 1psmodule i2c_drive(clk,rst_n,sw1,sw2,scl,sda,dis_data);input clk;// 50MHzinput rst_n;//复位信号,低有效input sw1,sw2;//按键1、2,(1按下执行写入操作,2按下执行读操作)output scl;// 24C02的时钟端口inout sda;// 24C02的数据端口output [7:0] dis_data;//输出指定单元的数据//--------------------------------------------//按键检测reg sw1_r,sw2_r;//键值锁存寄存器,每20ms检测一次键值reg[19:0] cnt_20ms;//20ms计数寄存器always @ (posedge clk or negedge rst_n)if(!rst_n)cnt_20ms <= 20'd0;elsecnt_20ms <= cnt_20ms+1'b1;//不断计数always @ (posedge clk or negedge rst_n)if(!rst_n)beginsw1_r <= 1'b1;//键值寄存器复位,没有键盘按下时键值都为1sw2_r <= 1'b1;endelse if(cnt_20ms == 20'hfffff)beginsw1_r <= sw1;//按键1值锁存sw2_r <= sw2;//按键2值锁存end//---------------------------------------------//分频部分reg[2:0] cnt;// cnt=0:scl上升沿,cnt=1:scl高电平中间,cnt=2:scl下降沿,cnt=3:scl低电平中间reg[8:0] cnt_delay;//500循环计数,产生iic所需要的时钟reg scl_r;//时钟脉冲寄存器always @ (posedge clk or negedge rst_n)if(!rst_n)cnt_delay <= 9'd0;else if(cnt_delay == 9'd499)cnt_delay <= 9'd0;//计数到10us为scl的周期,即100KHz elsecnt_delay <= cnt_delay+1'b1;//时钟计数always @ (posedge clk or negedge rst_n) beginif(!rst_n)cnt <= 3'd5;elsebegincase (cnt_delay)9'd124:cnt <= 3'd1;//cnt=1:scl高电平中间,用于数据采样9'd249:cnt <= 3'd2;//cnt=2:scl下降沿9'd374:cnt <= 3'd3;//cnt=3:scl低电平中间,用于数据变化9'd499:cnt <= 3'd0;//cnt=0:scl上升沿default: cnt <= 3'd5;endcaseendend`define SCL_POS(cnt==3'd0)//cnt=0:scl上升沿`define SCL_HIG(cnt==3'd1)//cnt=1:scl高电平中间,用于数据采样`define SCL_NEG(cnt==3'd2)//cnt=2:scl下降沿`define SCL_LOW(cnt==3'd3)//cnt=3:scl低电平中间,用于数据变化always @ (posedge clk or negedge rst_n)if(!rst_n)scl_r <= 1'b0;else if(cnt==3'd0)scl_r <= 1'b1;//scl信号上升沿else if(cnt==3'd2)scl_r <= 1'b0;//scl信号下降沿assign scl = scl_r;//产生iic所需要的时钟//---------------------------------------------//需要写入24C02的地址和数据`define DEVICE_READ8'b1010_0001//被寻址器件地址(读操作)`define DEVICE_WRITE8'b1010_0000//被寻址器件地址(写操作)`define WRITE_DATA 8'b0000_0111//写入EEPROM的数据`define BYTE_ADDR 8'b0000_0100//写入/读出EEPROM的地址寄存器reg[7:0] db_r;//在IIC上传送的数据寄存器reg[7:0] read_data;//读出EEPROM的数据寄存器//---------------------------------------------//读、写时序parameter IDLE = 4'd0;parameter START1 = 4'd1;parameter ADD1 = 4'd2;parameter ACK1 = 4'd3;parameter ADD2 = 4'd4;parameter ACK2 = 4'd5;parameter START2 = 4'd6;parameter ADD3 = 4'd7;parameter ACK3= 4'd8;parameter DATA = 4'd9;parameter ACK4= 4'd10;parameter STOP1 = 4'd11;parameter STOP2 = 4'd12;reg[3:0] cstate;//状态寄存器reg sda_r;//输出数据寄存器reg sda_link;//输出数据sda信号inout方向控制位reg[3:0] num;//always @ (posedge clk or negedge rst_n) beginif(!rst_n)begincstate <= IDLE;sda_r <= 1'b1;sda_link <= 1'b0;num <= 4'd0;read_data <= 8'b0000_0000;endelsecase (cstate)IDLE:beginsda_link <= 1'b1;//数据线sda为inputsda_r <= 1'b1;if(!sw1_r || !sw2_r)begin//SW1,SW2键有一个被按下db_r <= `DEVICE_WRITE;//送器件地址(写操作)cstate <= START1;endelsecstate <= IDLE;//没有任何键被按下endSTART1:beginif(`SCL_HIG)begin//scl为高电平期间sda_link <= 1'b1;//数据线sda为outputsda_r <= 1'b0;//拉低数据线sda,产生起始位信号cstate <= ADD1;num <= 4'd0;//num计数清零endelsecstate <= START1; //等待scl高电平中间位置到来endADD1:beginif(`SCL_LOW)beginif(num == 4'd8)beginnum <= 4'd0;//num计数清零sda_r <= 1'b1;sda_link <= 1'b0;//sda置为高阻态(input)cstate <= ACK1;endelsebegincstate <= ADD1;num <= num+1'b1;case (num)4'd0: sda_r <= db_r[7];4'd1: sda_r <= db_r[6];4'd2: sda_r <= db_r[5];4'd3: sda_r <= db_r[4];4'd4: sda_r <= db_r[3];4'd6: sda_r <= db_r[1];4'd7: sda_r <= db_r[0];default: ;endcase//sda_r <= db_r[4'd7-num];//送器件地址,从高位开始endend//else if(`SCL_POS) db_r <= {db_r[6:0],1'b0};//器件地址左移1bitelsecstate <= ADD1;endACK1:beginif(/*!sda*/`SCL_NEG)begin//注:24C01/02/04/08/16器件可以不考虑应答位cstate <= ADD2;//从机响应信号db_r <= `BYTE_ADDR;// 1地址endelsecstate <= ACK1;//等待从机响应endADD2:beginif(`SCL_LOW)beginif(num==4'd8)beginnum <= 4'd0;//num计数清零sda_r <= 1'b1;sda_link <= 1'b0;//sda置为高阻态(input)cstate <= ACK2;endelsebeginsda_link <= 1'b1;//sda作为outputnum <= num+1'b1;case (num)4'd0: sda_r <= db_r[7];4'd1: sda_r <= db_r[6];4'd2: sda_r <= db_r[5];4'd3: sda_r <= db_r[4];4'd4: sda_r <= db_r[3];4'd6: sda_r <= db_r[1];4'd7: sda_r <= db_r[0];default: ;endcase//sda_r <= db_r[4'd7-num];//送EEPROM地址(高bit开始)cstate <= ADD2;endend//else if(`SCL_POS) db_r <= {db_r[6:0],1'b0};//器件地址左移1bitelsecstate <= ADD2;endACK2:beginif(/*!sda*/`SCL_NEG) begin//从机响应信号if(!sw1_r) begincstate <= DATA; //写操作db_r <= `WRITE_DATA;//写入的数据endelse if(!sw2_r) begindb_r <= `DEVICE_READ;//送器件地址(读操作),特定地址读需要执行该步骤以下操作cstate <= START2;//读操作endendelse cstate <= ACK2;//等待从机响应endSTART2: begin//读操作起始位if(`SCL_LOW) beginsda_link <= 1'b1;//sda作为outputsda_r <= 1'b1;//拉高数据线sdacstate <= START2;endelse if(`SCL_HIG) begin//scl为高电平中间sda_r <= 1'b0;//拉低数据线sda,产生起始位信号cstate <= ADD3;endelse cstate <= START2;endADD3:begin//送读操作地址if(`SCL_LOW) beginif(num==4'd8) beginnum <= 4'd0;//num计数清零sda_r <= 1'b1;sda_link <= 1'b0;//sda置为高阻态(input)cstate <= ACK3;endelse beginnum <= num+1'b1;case (num)4'd0: sda_r <= db_r[7];4'd1: sda_r <= db_r[6];4'd2: sda_r <= db_r[5];4'd3: sda_r <= db_r[4];4'd4: sda_r <= db_r[3];4'd5: sda_r <= db_r[2];4'd6: sda_r <= db_r[1];4'd7: sda_r <= db_r[0];default: ;endcase//sda_r <= db_r[4'd7-num];//送EEPROM地址(高bit开始)cstate <= ADD3;endend//else if(`SCL_POS) db_r <= {db_r[6:0],1'b0};//器件地址左移1bitelse cstate <= ADD3;endACK3:beginif(/*!sda*/`SCL_NEG) begincstate <= DATA;//从机响应信号sda_link <= 1'b0;endelse cstate <= ACK3; //等待从机响应endDATA:beginif(!sw2_r) begin//读操作if(num<=4'd7) begincstate <= DATA;if(`SCL_HIG) beginnum <= num+1'b1;case (num)4'd0: read_data[7] <= sda;4'd1: read_data[6] <= sda;4'd2: read_data[5] <= sda;4'd3: read_data[4] <= sda;4'd4: read_data[3] <= sda;4'd5: read_data[2] <= sda;4'd6: read_data[1] <= sda;4'd7: read_data[0] <= sda;default: ;endcase//read_data[4'd7-num] <= sda;//读数据(高bit开始)end//else if(`SCL_NEG) read_data <= {read_data[6:0],read_data[7]};//数据循环右移endelse if((`SCL_LOW) && (num==4'd8)) beginnum <= 4'd0;//num计数清零cstate <= ACK4;endelse cstate <= DATA;endelse if(!sw1_r) begin//写操作sda_link <= 1'b1;if(num<=4'd7) begincstate <= DATA;if(`SCL_LOW) beginsda_link <= 1'b1;//数据线sda作为outputnum <= num+1'b1;case (num)4'd0: sda_r <= db_r[7];4'd1: sda_r <= db_r[6];4'd2: sda_r <= db_r[5];4'd3: sda_r <= db_r[4];4'd4: sda_r <= db_r[3];4'd5: sda_r <= db_r[2];4'd6: sda_r <= db_r[1];4'd7: sda_r <= db_r[0];default: ;endcase//sda_r <= db_r[4'd7-num];//写入数据(高bit开始)end//else if(`SCL_POS) db_r <= {db_r[6:0],1'b0};//写入数据左移1bitendelse if((`SCL_LOW) && (num==4'd8)) beginnum <= 4'd0;sda_r <= 1'b1;sda_link <= 1'b0;//sda置为高阻态cstate <= ACK4;endelse cstate <= DATA;endendACK4: beginif(/*!sda*/`SCL_NEG) begin//sda_r <= 1'b1;cstate <= STOP1;endelse cstate <= ACK4;endSTOP1:beginif(`SCL_LOW) beginsda_link <= 1'b1;sda_r <= 1'b0;cstate <= STOP1;endelse if(`SCL_HIG) beginsda_r <= 1'b1;//scl为高时,sda产生上升沿(结束信号)cstate <= STOP2;endelse cstate <= STOP1;endSTOP2:beginif(`SCL_LOW) sda_r <= 1'b1;else if(cnt_20ms==20'hffff0) cstate <= IDLE;else cstate <= STOP2;enddefault: cstate <= IDLE;endcaseendassign sda = sda_link ? sda_r:1'bz;assign dis_data = read_data;//---------------------------------------------endmodule。

(带有源代码)基于FPGA的模拟I2C接口设计与实现

(带有源代码)基于FPGA的模拟I2C接口设计与实现

研究生课程设计论文题目:基于FPGA的模拟IIC接口设计与实现课程名称:FPGA及片上系统SOPC应用任课教师:宋树祥(教授)殷严刚(讲师)学院:电子工程学院班级: 12 级电子与通信工程学号: *******xxxx姓名: xxx2012 年 12 月 30 日目录1 IIC 总线特点及工作原理概述 (3)1.1 IIC总线特点 (3)1.2 IIC总线工作原理 (4)1.2.1总线的构成及信号类型 (4)1.2.2 总线基本操作 (5)1.3 控制字节 (5)1.4 写操作 (6)1.5 读操作 (6)1.6 7位的地址格式介绍 (7)2 IIC模块的硬、软件设计 (8)2.1 IIC模块硬件设计 (8)2.1.2 分频模块设计(Division_1_500HZ) (9)2.1.3 IIC总线接口模块设计(IIC_Interface_Bus) (9)2.1.4 显示模块设计(Led_Seg_Display) (10)2.1.5 硬件模块总体设计思想及总体电路原理图 (11)2.2 IIC模块的verilog HDL代码设计 (12)3 IIC接口模块的功能实物测试(基于EP2C20Q240C8) (14)4 IIC接口模块设计的改进 (16)参考文献 (17)附录部分源代码 (18)基于FPGA的模拟IIC接口设计与实现摘要:本文简述了IIC总线的特点;介绍了基于FPGA 的模拟IIC总线接口模块的设计思想;设计并编写了基于Verilog HDL语言来实现部分IIC总线接口功能的程序代码,同时给出了基于目标板的硬件实物测试图。

关键词:IIC 总线接口FPGA Verilog HDL EP2C20Q240C8在进行FPGA的开发时,利用EDA 工具设计芯片实现系统的功能已经成为支撑电子设计的通用平台,并逐步向支持系统级的设计方向发展。

模块化的设计思想在软件设计过程中越来越被重视。

IIC总线是Philips 公司推出的双向两线串行通讯标准,具有接口线少、通讯效率高等特点。

I~2C总线接口的fpga实现研究

I~2C总线接口的fpga实现研究

%%F !""#$%! 计算机工程与应用
器 (并 & 串变换) , 再通过 ’() 出现在 *!+ 总线上; 或接收从 ’,-./ 器件发送来的数 据 在 *!+ 总 线 时 序 控 制 逻 辑 的 控 制 下 经 过 *!+ 接收移位寄存器 (串 & 并 变 换 ) , 经 过 锁 存 由 0-12/3 在 4( 信 号 的控制下读取。
直处于忙的状态, 此时的起始条件 ’ 和重复起始 ’2-32 3/@/-2/A 条件在功能上是一样的。
>$!
数据传输
*!+ 总线协议规定,在 ’() 上发送数据每个字节必须为 B
位, 首先传输的是字节的最高位 (0’C ) , 每次传输的字节数不 受限制, 如图 = 所示为 *!+ 总线完 整 数 据 传 输 时 序 。 主 机 发 送 起始条件后, 首先发送一个 D 位的从机地址 (用 于 选 中 当 前 要 (4 & E ) 以 使用的从器件) , 紧接着发送 % 位的数据传输方向位 指示是从从器件读取数据还是把数据写入从器件。 数据传输由 主机产生的停止条件结束。
图=
*!+ 总线数据传输时序
*!+ 总线数据传输的详细过程可以参阅 *!+ 总线协议手册。
= 567) 的 F/3<,GH 8(? 实现 =$% 状态机嵌套模型
由于 *!+ 总线接口牵涉到复 杂 的 状 态 机 描 述 , 需要采用有 限状态机的嵌套, 形成树状的控制逻辑。这一点和所提倡的层 图 # 是一种简单 次化、 结构化的自顶向下的设计方法相吻合 I>J。 的状态机嵌套模型。
图#
状态机嵌套模型

基于FPGA的IIC总线接口实现方法_王前

基于FPGA的IIC总线接口实现方法_王前

第30卷 第3期Vol.30No.3微 电 子 技 术M ICROELECT RO NI C T ECHN OLOG Y总第145期2002年6月综 述基于FPGA的IIC总线接口实现方法王 前,吴淑泉,刘喜英(华南理工大学电子与信息学院,广州 510640)摘 要: 本文简述了IIC总线协议,重点介绍了基于现场可编程门阵列(FPGA)的IIC总线接口的系统结构及实现方法。

关键词: IIC总线;FPGA;VHDL中图分类号:TN431.2 文献标识码:A 文章编号:1008-0147(2002)03-21-04Implementation of IIC Bus Based on FPGA TechnologyWANG Qian,WU Shu-quan,LIU Xi-y ing(Colle ge of Ele ctronic&Information Engineering,SCUT,Guangzhou,510640,China)A bstract: In this paper,IIC Bus Protocol is briefly introduced and a method to implement the IIC Businterface using FPGA is emphatically proposed.Keywords: IIC Bus;FPGA;VHDL1 引言 由于IIC总线的连线少,结构简单,可不用专门的母板和插座直接用导线互连各个设备,因而可大大简化系统的硬件设计。

许多半导体厂商都引进了此项总线技术,并推出了不少带IIC总线接口的芯片。

已有不少文献讨论了IIC总线接口的单片机编程技术,本文从另一个角度论述基于FPGA的IIC总线接口的实现方法。

2 IIC接口及通讯协议IIC总线是以双向的数据线SDA和时钟线SCL 二根连线实现了完善的全双工同步数据传送。

总线备用时SDA和SCL都必须保持高电平状态,只有关闭IIC总线时才使SC L箝位在低电平。

FPGA有限状态机模拟I2C总线设计

FPGA有限状态机模拟I2C总线设计

-"
--
""
"-
-"
--
""
"-
-"
--
""
"-
-"
--
*!+ 总线传输全部 ./ 个 ‘a&<3 数据的状态转移图
! ! ! ! #$%&’($)*+,)-(. #/0123 4"! ,*! #56123 4#56%3789:;# 4#$%&’($)":).<
""
=>=>=
数据输入 一般情况下 #?=/ 总线传输的数据由 外部 @18 或 其 它 专 门 的 数 据 存 储 区 来 存储 $ 但在数据相对固定且数据量不是 很大的情况下 $ 可以将初始化的数据写 在程序中 $ 这样可减少频繁的数据交换 $ 简化操作 % #66A""" 的初始化数据就属 于这种情况 $ 可以通过检测应答信号来 改变输入的值 % 程序如下 & BCDBEF G ’HIF)<-) /0J?; ( ,)-(. KL
]<3<&X_"_
号 动信
3 "/>>81=3$ 的 / 倍 ! 即 其 时 钟 频 率 为 />>8?@ " -A>>8?@ %!B,!3">)A!,!3 $! 所以 %50 与 %+6 之间的 跳变沿 ! 都相应地满足 *!+ 通信协议中 %50 与 %+6 之间的建立与保持时间 %!>)A!3 $* !)! *!+ 模块程序编写 整个程序用 C<D2;’E ?56 语言编制 !选择 *!+ 总 线 的 传 输 速 率 为 !>>81=3! 则 输 入 时 钟 频 率 应 为 F>>81=3 * 在这里把双向数据线 %50 用分成两 条线 模 拟 "%50GHI 为 %50 数 据 输 出 !%500+J 为 %50

基于FPGA的I2C总线的应用设计

基于FPGA的I2C总线的应用设计

基于FPGA的I2C总线的应用设计I2C总线作为一种简单而又常见的通信协议,在各种电子设备中得到广泛应用。

然而,复杂的系统设计中对I2C控制器的要求越来越高,比如在音频数字信号处理器(DSP)和嵌入式系统中,需要对I2C进行更高效的数据交换。

此时,基于FPGA的I2C总线应用设计成为了一种比较理想的解决方案。

I2C是一个串行通信协议,它由Philips(现在为NXP公司)开发,采用双向总线,数据可以在被控制设备(从设备)和主设备(主机)之间传递。

I2C协议包括两种方式:master/slave和multi-master。

Master/slave模式下,主设备控制总线来与多个从设备通信;在multi-master模式下,多个主控设备通过相同的I2C总线同时工作。

而在基于FPGA的I2C总线应用设计中,可以通过硬核或软核组件来实现I2C控制器。

其中,硬核I2C控制器是指已经被实现并绑定到FPGA中的控制器,而软核I2C控制器是指开发人员使用硬件描述语言(HDL)来设计的控制器。

相比硬核I2C控制器,软核I2C控制器的灵活性更高,可以根据需要进行更多的自定义功能设计。

对于FPGA与I2C总线之间的交互,一种常见的方法是通过I2C接口电路连接。

在FPGA中,需要通过I2C接口电路来初始化I2C控制器并从从设备中读取或向从设备中写入数据。

因此,在基于FPGA的I2C总线应用设计中,设计人员要注意使用适当的接口电路来提供足够的电源和信号完整性。

在I2C总线应用中,对于从设备有多个时,可以使用不同的从设备地址。

而在FPGA中,可以通过I2C控制器的复用功能来实现多台I2C从设备的读写,从而实现更多的功能和灵活性。

此外,通过使用可编程的约束和技术(如VHDL、verilog、fuses和配置位等),可以控制硬核和软核I2C控制器的行为和性能。

在FPGA中使用I2C总线具有高带宽和低时延的优势,因为FPGA可以使用并行处理技术来提高执行效率。

基于fpga的i2c总线通信的实现学习

基于fpga的i2c总线通信的实现学习

IIC总线的FPGA实现一、摘要DE2_TV中,有关于寄存器的配置的部分,采用的方法是通过IIC的功能,这里对IIC总线的FPGA实现做个说明。

二、实验平台软件平台:ModelSim-Altera 6.4a (Quartus II 9.0)硬件平台:DIY_DE2三、实验原理1、IIC总线器件工作原理在IIC总线上传送信息时的时钟同步信号是由挂接在SCL时钟线上的所有器件的逻辑“与”完成的。

SCL线上由高电平到低电平的跳变将影响到这些器件,一旦某个器件的时钟信号变为低电平,将使SCL线上所有器件开始并保护低电平期。

此时,低电平周期短的器件的时钟由低至高的跳变并不影响SCL线的状态,这些器件将进入高电平等待的状态。

当所有器件的时钟信号都变为高电平时,低电平期结束,SCL线被释放返回高电平,即所有的器件都同时开始它们的高电平期。

其后,第一个结束高电平期的器件又将SCL线拉成低电平。

这样就在SCL线上产生一个同步时钟。

可见,时钟低电平时间由时钟低电平期最长的器件决定,而时钟高电平时间由时钟高电平期最短的器件决定。

IIC总线上数据的传输速率在标准模式下可达100kbit/s 在快速模式下可达400kbit/s 在高速模式下可达3.4Mbit/s ,连接到总线的接口数量只由总线电容是400pF 的限制决定。

2、IIC总线的传输协议与数据传送时序(1)起始和停止条件在数据传送过程中,必须确认数据传送的开始和结束。

在IIC总线技术规范中,开始和结束信号(也称启动和停止信号)的定义如图1所示。

图1起始和停止信号图开始信号:当时钟总线SCL为高电平时,数据线SDA由高电平向低电平跳变,开始传送数据。

结束信号:当SCL线为高电平时,SDA线从低电平向高电平跳变,结束传送数据。

开始和结束信号都是由主器件产生。

在开始信号以后,总线即被认为处于忙状态,其它器件不能再产生开始信号。

主器件在结束信号以后退出主器件角色,经过一段时间过,总线被认为是空闲的。

基于FPGA的I2C SLAVE模式总线的设计方案

基于FPGA的I2C SLAVE模式总线的设计方案

基于FPGA的I2C SLAVE模式总线的设计方案
0 引言
由于在嵌入式系统开发中越来越多的应用到FPGA,而一些嵌入式CPU,比如STM32 为了降低成本,减小封装尺寸,没有外接专门的CPU 读写总线,而只提供了一些如SPI 和I2C 的接口。

而且在应用中经常有数据要配置到FPGA 中,如FPGA 中的应用配置寄存器,和配置表项等,都需要CPU 配置。

这些数据的数据量不大,速度也不要求很高,很适合用I2C 总线来配置。

I2C 总线是Philips 公司设计的一种控制和配置内部IC 双向两线的串行总线。

主要特点是接口信号线较少,但是其数据的传送速率不是很高,其高速模式下为3.4Mb/s.应用于配置FPGA 比较适合。

在通常的应用中嵌入式CPU 作为MASTER 模式的主器件,FPGA 作为SLAVE 模式的从器件。

通过使用I2C 总线,减少了CPU 和FPGA 的连线,而且嵌入式CPU 一般有内含I2C总线控制器,使得CPU 和FPGA 间的通讯硬件电路简化。

1 I2C SLAVE 模式整体结构的分析设计。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

研究生课程论文
课程名称基于FPGA的模拟IIC接口设计与实现授课学期2012 学年至2013 学年第一学期学院电子工程学院
专业电子与通信工程
学号**********
姓名
任课教师
交稿日期2013.01.10
成绩
阅读教师签名
日期
广西师范大学研究生学院制
基于FPGA的模拟I2C接口设计与实现
摘要:本文论述了I2C总线的基本协议,以及基于FPGA 的模拟I2C 总线接口模块的设计,在QuartusII软件中用Verilog HDL语言编写了部分I2C总线接口功能的程序代码,生成原理图模块。

并连接好各个模块,进行了时序仿真。

最后,下载到FPGA的板运行测试。

关键词:I2C 接口FPGA Verilog
1课题研究意义、现状及应用分析
目前市场上主流的嵌入式设备主要是微处理器、DSP等,但FPGA 以其独有的高抗干扰性、高安全性正在逐步取得开发公司的青睐,在FPGA上开发I2C势在必行。

并且利用EDA 工具设计芯片实现系统的功能,已经成为支撑电子设计的通用平台,并逐步向支持系统级的设计方向发展。

模块化的设计思想在软件设计过程中越来越被重视。

I2C总线是Philips 公司推出的双向两线串行通讯标准,具有接口线少、通讯效率高等特点。

因此,基于FPGA的I2C总线设计有着广泛的应用前景。

2课题总体方案设计及功能模块介绍
本设计主要分三大模块,分别是I2C 总线接口模块、按键输入控制模块、数码管显示模块。

I2C总线模块集成了I2C协议用于和总线相接EEPROM的通信;按键输入控制模块用于控制I2C模块的页读、页写、字节读、字节写功能;数码管显示模块用于显示通过I2C总线读取EEPROM中的数据。

3I2C接口设计原理
I2C总线最主要的优点是其简单性和有效性。

由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。

总线的长度可高达25英尺,并且能够以10 Kbps的最大传输速率支持40个组件。

I2C总线的另一个优点是,它支持多主控(multimastering),其中任何能够进行发送和接收的设备都可以成为主总线。

一个主控能够控制信号的传输和时钟频率。

3.1总线的构成
I2C总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。

在CPU与被控IC之间、IC与IC之间进行双向传送,最高传送速率100kbps。

各种被控制电路均并联在这条总线上,但就像电话机一样只有拨通各自的号码才能工作,所以每个电路和模块都
有唯一的地址,在信息的传输过程中,I2C总线上并接的每一模块电路既是主控器(或被控器),又是发送器(或接收器),这取决于它所要完成的功能。

CPU发出的控制信号分为地址码和控制量两部分,地址码用来选址,即接通需要控制的电路,确定控制的种类;控制量决定该调整的类别(如对比度、亮度等)及需要调整的量。

这样,各控制电路虽然挂在同一条总线上,却彼此独立,互不相关。

I2C总线在传送数据过程中共有三种类型信号,它们分别是:开始信号、结束信号和应答信号。

开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。

结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。

应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。

CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。

若未收到应答信号,由判断为受控单元出现故障。

4程序部分代码实现以及原理图分析
4.1程序部分代码实现
由于代码比较长,在这里我们只简要介绍输入输出接口变量。

I2C
模块可以划分为字节发送模块、字节接收模块、开始条件模块、停止条件模块。

其中,字节发送模块、字节接收模块和停止条件模块为基本模块。

在开始条件模块中,因为需要发送从器件地址,所以要调用字节发送模块。

//I2C接口时序模拟部分
module IIC_Interface_Bus(
clk,
rst_n,
Syn_Sign,
Byte_Write,
Byte_Read,
Page_Write,
Page_Read,
scl,
sda,
ackflag,
outdata
);
//AT24C08的地址和数据,根据硬件进行更改。

`define DEVICE_READ 8'b1010_0001//被寻址器件地址(读操作)
`define DEVICE_WRITE 8'b1010_0000//被寻址器件地址(写操
作)
//写入EEPROM的数据
`define WRITE_DATA0 8'd78//8'b0110_0010 0x62
`define WRITE_DATA1 8'd32//8'b0010_0001 0x21
`define WRITE_DATA2 8'd26//8'b0100_0011 0x43
`define WRITE_DATA3 8'd79//8'b0110_0101 0x45
`define WRITE_DATA4 8'd43//8'b1000_0111 0x87
`define BYTE_ADDR 8'b0000_0100 //要写入/读出EEPROM 的地址寄存器
input clk;//50MHz
input rst_n; //复位信号,低电平有效
input Syn_Sign;//同步信号
input Byte_Write,Byte_Read,Page_Write,Page_Read;//按键1按下执行写入操作,2按下执行读操作,3按下执行连写操作,4按下执行连读操作
output scl; //AT24C08的时钟端口
inout sda; //AT24C08的数据端口
output [2:0]ackflag; //后面显示接收到数据的标志
output [7:0] outdata; //数码管显示的数据
//分频部分,通过分频获取串行总线器件的时钟信号
reg[2:0] cnt; //cnt=0:scl上升沿,cnt=1:scl高电平中间,cnt=2:scl下降沿,cnt=3:scl低电平中间
reg[8:0] cnt_delay; //500循环计数,产生iic所需要的时钟100khz - Max:400KHZ
reg scl_r; //时钟脉冲寄存器
parameter pre_cnt = 500;//
4.2原理图分析
图(1)
如图(1)所示,主要分三大模块,分别是I2C 总线接口模块、按键输入控制模块、数码管显示模块。

按键输入控制I2C模块的页读、页写、字节读、字节写功能;由I2C总线读取EEPROM中的数据并传送给数码管显示模块,通过数码管显示读取EEPROM中的数据。

5实验实物测试、结果分析
图(2)
如图(2)所示,通过I2C总线读取预先存储在EEPROM的数据2632,通过数码管显示,我们可以看到结果完全正确。

6总结、心得体会
通过本次的课程设计使我进一步认识到FPGA在实际应用的作用。

同时感谢老师给以的指导,以及同学的帮助。

在本次设计比较顺利,一次设计三大模块I2C总线接口模块、按键输入控制模块、数码管显示模块,首先分析各个模块的需求以及需要的接口。

然后分别编写模块的代码,调试无误后,生成原理图板块。

最后将三个模块依次连接好运行调试,无误后下载的FPGA板了运行,我们观测结果。

不断反复调试,知道无误为止。

通过设计I2C总线,使我在软件应用,程序调试方面有了极大地提高,从中受益匪浅。

7附主要的参考文献
[1]周立功.EDA实验与实践.北京:北京航空航天大学出版社,2007.4~40
[2]吴继华.王诚.Altera FPGA/CPLD设计.北京:人民邮电出版社,2005.1~28
[3]廖义奎.ARM与FPGA综合设计及应用.北京:中国电力出版社,2008.152~201 [4]罗苑棠.CPLD/FPGA常用模块与综合系统设计实例精讲.北京:电子工业出版社,2007.10~13
[4]用Verilog HDL 实现I2C 总线功能文章作者:天津科技大学电子信息与自动化学院路永坤文章出处:电子技术应用。

相关文档
最新文档