引言
在现代电子系统中,有为数众多的IC 需要进行相互之间以及与外界的通信。为了简化电路的设计,Philips 公司开发了一种用于内部IC 控制的简单的双向两线串行总线I2C。该总线具有接口线少、通信效率高等特点[1]。AD9883A为美国Analog Devices 公司生产的3 路8 位模数转换器件,最高转换率达140Msps(百万次采样/秒),多用于捕获个人计算机或工作站的RGB 信号。近年来,在视频信号处理领域得到广泛的应用。AD9883A内含25 个寄存器00H~18H,用来对AD9883A 进行初始化和控制。针对不同的应用环境,这些寄存器需写入相应的值,才能使AD9883A 正常工作。AD9883A 的初始化是其工程应用的前提[2]。其初始化过程依靠AD9883A的SDA(57脚)和SCL(56脚)两引脚进行,时序符合I2C总线的时序标准。对AD9883A芯片可以使用单片机或者由FPGA产生I2C时序进行配置,下面分别介绍这些方法,并详细介绍在实际工程中采用的基于FPGA的I2C配置模块。
1 I2C总线传输协议简介[3]
I2C 是Philips 公司推出的芯片间串行传输总线,用两根连线(SDA 和SCL)即可实现完善的全双工同步数据传送,具有规范完整、结构独立和使用简单等特点。I2C 总线的时钟线SCL和数据线SDA均为双向传输线。数据线上每传输一位数据都要求时钟线上有一个时钟脉冲与其相对应。I2C 总线的典型接法如图 1 所示,注意连接时需要共地。
总线工作时的具体时序如下:
① 起始信号。在时钟信号SCL为高电平期间,数据线SDA出现由高电平向低电平的变化,用于启动I2C总线,准备开始传送数据。
② 停止信号。在时钟信号SCL为高电平期间,数据线SDA出现由低电平向高电平的变化,用于停止I2C总线上的数据传输。
③ 应答信号。I2C总线的第9个脉冲对应应答位。若SDA线上显示低电平,则为总线“应答”;若SDA线上显示高电平,则为“非应答”。
④ 数据位传输。I2C总线起始信号或应答信号之后的第1~8个时钟脉冲,对应一个字节的8位数据传输。在脉冲高电平期间,数据串行传输;在脉冲低电平期间,数据准备,允许总线上的数据电平变化。
2 采用单片机进行初始化
一方面,可直接采用带有I2C总线接口的单片机对AD9883A 进行初始化,如Philips公司的P89LPC932A1。它是一款单片封装的微控制器,适合于许多要求高集成度、低成本的场合,可以满足多方面的性能要求。P89LPC932A1 采用了高性能的处理器结构,指令执行时间只需2~4 个时钟周期;6 倍于标准80C51器件。P89LPC932A1 集成了许多系统级的功能,可大大减少元件的数目、减小电路板面积并降低系统的成本。
图1 I2C总线典型接法示意图
另一方面,对于不带I2C总线接口的单片机,可以采用模拟I2C 总线技术,使用其普通I/O 口来模拟I2C总线时序,实现对外围器件的读、写操作。例如,AT89S51 内部共有15条I/O线,选择I/O口P1.6和P1.5来模拟I2C总线接口。对于单主系统(只有一个主控器件),目前已经设计出模拟I2C总线的通用软件包[4]。
3 基于FPGA的I2C模块的设计与实现
3.1 模型介绍
该I2C模块用来对视频模/数转换芯片AD9883A通过I2C时序进行初始化,SDA要输出的只是一些无需改动的初始化数据。I2C模块信号线示意图如图2所示。
当复位键按下时,SCL、SDA重新发送起始信号进行初始化;SCL、SDA时序由CLK作为时钟输入,由内部有限状态机产生。
图2 I2C模块信号线示意图
3.2 IP核程序
整个程序用Verilog语言编写,系统输入时钟用8 MHz晶振实现,CLK经过200分频生成CLK_I2C,再经过4分频生成SCL时钟,这样整个数据传输速率为100 kbps。下面给出启动、停止、应答3个状态的程序,其中SDA定义为INOUT类型端口,如assign SDA=(~in_set)? data :1'bz。当in_set为0时,SDA为输出,输出数值为data数值;当in_set为1时,SDA为输入端口,此时可以检验来自AD9883A的应答信号。
(1) 启动信号的产生
task start;
begin
if(!SCL)
begin
in_set<=1'b0;
data<=1'b1;
//在SCL为0时,SDA为输出状态且输出为1
end
else
begin
in_set<=1'b0;
data<=1'b0;
//在SCL为高电平时,SDA为输出状态且由0
//变为1,完成启动信号时序
main_state<=control_add;
//启动信号完成后,主状态进入发送控制字节
//状态
end
end
endtask
(2) 停止信号的产生
task stop;
begin
if(!SCL)
begin
in_set<=1'b0;
data<=1'b0;
end
else
begin
num_stop<=1'b0;
main_state<=idle;
//初始化完成后主状态进入空闲状态,释放I2C总线
end
end
endtask
(3) 应答信号的识别
在每次发送完8个字节数据之后,进入应答状态;如果此时SDA引脚输入为低电平,则数据发送成功,否则失败。
task ack;
begin
if(!SCL)
in_set<=1'b1;
else
begin
in_set<=1'b1;//此时SDA为输入引脚,判断应答信号
if(SDA==0)
main_state<=main_state+6'b00_0001;
//发送成功后进入下一状态,发送下个字节数据
else
main_state<=stop;//发送失败后进入停止状态
end
end
endtask
3.3 仿真及调试结果
将自主开发的I2C IP核程序在QuartusII软件下仿真,结果如图3所示。在启动信号之后,发送AD9883A的二进制控制字节1001_1000(写操作)。由于只是仿真,所以在SCL第9个时钟周期,SDA呈现高阻,进入停止状态。
图3 软件仿真波形
硬件调试中选用Altera公司的EP1C6Q24C08型号的FPGA,在QuartusII中自带的嵌入式逻辑分析仪SignalTapII中,可以看出图4所示的调试结果。当主状态main_state为00H时,程序进入启动状态;当主状态main_state为3EH时,发送AD9883A控制字节1001_1000,在SCL的第9个时钟周期,SDA为0,即应答信号为低,说明发送成功;当主状态main_state为01H时,开始发送初始化数据。
图4 硬件调试波形图
4结论
以FPGA作为核心处理器件,完成了产生I2C时序的IP核的设计,满足I2C总线的时序要求;将其应用在实际工程中,完成了对I2C接口的模/数转换芯片AD9883A的初始化配置,效果良好。