1 I2C总线技术简介
I2C总线是一种由SDA(串行数据线)和SCL(串行时钟线)组成的串行总线,它利用这两根总线在MCU(微控制单元)与被控IC之间进行双向数据传送,各种被控电路均并联在这条总线上。当总线备用时,两根线都是高电平,只有当总线关闭时,SCL才转变为低电平。在标准模式下,I2C总线的数据传输速度可达100 kbit/s,在高速模式下则可达400 kbit/s。由于在I2C总线上每传输一位数据都有1个时钟脉冲相对应,所以,I2C总线的时钟周期一般在2.5 s~10 s之间。
I2C总线为同步传输总线,其中与数据传输有关的信号有开始信号、停止信号、应答信号和位传输等4种类型。开始信号是在SCL为高电平期间,SDA出现由高电平向低电平的变化,由此启动I2C总线,如图1(a)所示。停止信号是在SCL为高电平期间,SDA出现由低电平向高电平的变化,它意味着即将停止I2C总线的数据传输,如图1(b)所示。应答信号是指接收数据的IC在接收到发送方发送的8 bit数据后,应向发送数据的IC发出特定的低电平脉冲,表示已经完成本次数据的接收。数据位传输是在I2C总线启动后或应答信号后的第1~8个时钟脉冲对应于1个字节的8个bit位的数据传输。SCL在高电平期间,数据串行传输;SCL在低电平期间,容许SDA上的电平发生转换,为数据发送做准备。
图1 I2C总线开始信号和停止信号
I2C总线在进行数据传输时,每一帧数据均为1个字节,并且按照由高到低的顺序发送1个字节的8个bit。对于每个bit数据的传输,要求在时钟信号为高电平期间,数据线上的数据必须保持稳定的逻辑电平状态。只有在时钟线为低电平时,才允许数据线上的电平状态发生变化。另外,在启动I2C总线后,传输的字节数没有限制,只要求每传输一个字节,对方回应一个应答信号。
I2C总线的工作方式分为多主工作方式和单主工作方式。其中,在单主方式下,I2C总线上只有1个主器件成为主节点,该节点会永远占用I2C总线,而不会出现总线竞争的现象。在这种情况下,主器件若没有I2C总线接口,就可以利用其IO来模拟I2C总线接口。在视频采集系统中,采用的就是单主工作方式,FPGA为I2C总线的主节点。
2 SAA7111芯片简介
SAA7111是一款功能强大的模拟前端和数字视频译码器,常应用在嵌入式视频应用的高度集成的电路中。内部包含两路模拟处理通道,能实现视频源的选择、抗混叠滤波、A/D转换、自动嵌位、自动增益控制、时钟产生、多制式解码以及亮度、对比度和饱和度的控制,从而将PAL、NTSC等不同制式的模拟复合视频数据解码成亮度、色度和相关同步的数字信号,而这些功能是依靠外部控制器对它内部寄存器的设置来实现的,本系统中就是利用FPGA实现对它内部寄存器的设置。SAA7111原理框图如图2所示。
图2 SAA7111功能方框图
工作时,模拟视频图像从SAA7111的4个输入端口(AI11,AI12,AI21,AI22)中的一个端口输入,经模拟处理后,一路通过缓冲器从模拟输出端(AOUT)输出用于监视,另一路经A/D后产生数字色度信号、亮度信号,分别进行亮度信号处理、色度信号处理。亮度信号处理的结果,一路送到色度信号处理器进行综合处理,产生Y、U、V信号,经格式化后从VPO输出,输出的信号格式有422YUV或CCIR-656(8位)等;另一路进入同步分离器,经数字PLL,产生相应的行、场同步信号HS、VS及像素时钟信号LLC和LLC2等信号,这些信号是实现视频数据采集的依据。
3 SAA7111初始化的FPGA设计
在视频处理系统中,SAA7111是视频的输入处理部分,主要实现模拟输入视频信号的数字化;但在它工作之前,FPGA应通过SAA7111的I2C总线接口对其进行初始化。在SAA7111正常工作后,FPGA再根据SAA7111输出的行、场信号和像素时钟信号,实现视频的数字采集,并将采集的数据传输到后续的处理芯片中。关于SAA7111和外围器件的详细连接可参考SAA7111的芯片资料。SAA7111和FPGA的连接图如图3所示。
图3 SAA7111和FPGA的连接
FPGA对SAA7111进行初始化,必须解决以下几个问题:首先是产生I2C总线的时钟信号;其次是实现I2C总线的开始信号、停止信号、位传输信号和判断应答信号;再次是要确定SAA7111不同寄存器的设置数据。
3.1 I2C总线时钟的产生
一般情况下,FPGA的时钟频率较高,常为几十MHz,而I2C总线的时钟频率为几百kHz,用图4的方式可借助于FPGA的时钟获得I2C总线的时钟。需要说明的是,图中工作时钟的频率应为I2C总线时钟频率的M倍。这是因为系统中的任何一个I2C总线上的信号都是用M个工作时钟的周期来完成,而D触发器则是为了确保工作时钟的占空比为50%而设计的。
图4 12C总线时钟产生图
假设FPGA时钟为50 MHz,I2C总线时钟为200 kHz,M为8,则工作时钟为1.6 MHz,再考虑到D触发器相当于2分频,则
N= 50MHz/(200 kHz×8×2) = 16
3.2 关键信号的产生和传输
根据前面对I2C总线开始信号的讨论,再结合3.1节的设计将利用8个工作时钟产生一个I2C总线信号,很容易设计出I2C总线的开始信号。即规定:第1个脉冲上升沿到第3个脉冲上升沿之间,SCL为低、SDA为高;第3个脉冲上升沿到第5个脉冲上升沿之间,SCL为高、SDA为高;第5个脉冲上升沿到第7个脉冲上升沿之间,SCL为高、SDA为低;第7个脉冲上升沿到第9个脉冲上升沿之间,SCL为低、SDA为低。这样经过8个脉冲周期,就可产生一个开始信号。具体如图5所示。
图5 I2C总线开始信号设计时序
相应的VHDL源程序代码如下(假设为S1状态)
if clk'event and clk='1' then
case cnt is
when 0|1 scl<='0';sda<='1';cnt:=cnt+1;
when 2|3 scl<='1';sda<='1';cnt:=cnt+1;
when 4|5 scl<='1';sda<='0';cnt:=cnt+1;
when 6 scl<='0';sda<='0';ent:=ent+1;
when 7 cnt:=0;tempstate<=S2;
when others=>tmpstate<=S0;
end case;
end if;
其中:cnt为工作时钟clk的计数器变量,初始值为0;S2为启动I2C总线后的下一个的状态;tmpstate为状态变量。停止信号也很容易照此设计,在此不再累赘。
而对于数据bit位的传输,根据I2C总线规范要求,在数据位的传输过程中,SDA信号在SCL信号为高电平期间不容许发生跳变,可用SCL高电平期间的前、后各1个脉冲来作为数据的建立时间和保持时间。由此得到如图6所示的数据bit的传输设计。
图6 I2C总线数据位reg的设计时序
传输‘reg'(代表“0”或“1”)的源程序代码如下(假设为S4状态):
if clk'event and clk='1' then
case cnt is
when 0 scl<='0';sda<='1';cnt:=cnt+1;
when 1 scl<='0';sda<=reg;cnt:=cnt+1;
when 2|3|4 scl<='1';cnt:=cnt+1;
when 5 scl<='0';cnt:=cnt+1;
when 6 sda<='1';cnt:=cnt+1;
when 7 cnt:=0;bitnum:=bitnum+1;tempstate<=S3;
when others=>tmpstate<=S0;
end case;
end if;
其中:reg为信号寄存器,可以直接与SDA线相连;bitnum为表示正在传输字节的第几个bit数据。这样,在一个bit位数据传输的基础上,使用一个8 bit的寄存器存储要传输的字节,很容易实现1字节数据的传输。比如,在类型为std_logic_vector(7 downto 0)的寄存器ByteReg中存放着待发的数据,则传输1字节数据相应的源程序代码如下(假设为S3状态):
if clk'event and clk='1'then
if bitnum>7 then
bitnum:=0;sendnum:=sendnum+1;
tmpstate<=S5;
else
ent:=0;reg<=ByteReg(bitnum);
tmpstate<=S4;
end if;
end if;
其中,S5用来等待来自SAA7111的应答信号。需要注意的是,在程序中要将SDA设置成inout类型的端口,在发送数据时是输出端口,而在检查SAA7111的ACK信号时,又是输入端口。至于发送完一个字节的数据后,要等待SAA7111返回的ACK信号,就是检查来自SDA上的逻辑状态是否为低电平信号“0”,在此不再累赘。
3.3 SAA7111寄存器的设置
对SAA7111进行初始化本质上是对SAA7111内部的每个寄存器的每一位写入相应的数值,SAA7111的32个寄存器(00H~1FH)中有22个是可编程的,有些是可读寄存器,保存着芯片和厂商的标识等信息,真正需要编程的只有19个,其中每个寄存器都有一个子地址。在对多个连续的寄存器进行操作时,寄存器地址有自动加1功能,所以确定第1个子地址后,可以不考虑地址的变化,顺序写入各寄存器的数值即可实现寄存器的连续设置。另外,在对SAA7111初始化时,还需要确定从地址,而从地址由硬件连接图决定,当芯片引脚IICSA信号是低电平时,表示SAA7111的写地址为48H。芯片的各个寄存器的意义可以参考SAA7111的文档资料。
系统若设置为自动增益控制、625行50 Hz、PAL制式、YUV422的16位数字视频信号输出,则寄存器初始化值如表1所列。
SubAddress | Data | SubAddress | Data |
00H | 00H | 01H | 00H |
02H | C1H | 03H | 33H |
04H | 00H | 05H | 00H |
06H | EBH | 07H | E0H |
08H | 88H | 09H | 01H |
0AH | 80H | 0BH | 47H |
0CH | 40H | 0DH | 00H |
0EH | 01H | 0FH | 00H |
10H | 40H | 11H | 1CH |
12H | 03H |
4 SAA7111初始化的实现
SAA7111的工作模式、输入端口选择、色彩控制等图像采集的控制参数都是由其内部的寄存器决定,FPGA可通过SAA7111的I2C总线接口对其内部寄存器进行读写操作,具体的写时序如图7所示。
Start Slave | address W | ACK-s | SubAddress W | ACK-s | Data(Nbytes) | ACK-s | Pause |
5 结束语
本方案引入SAA7111视频输入处理芯片,简化了系统的硬件设计,通过FPGA对12C总线两条传输线的时序模拟,完成了对视频输入处理芯片的控制,正确实现了对SAA7111的初始化。实验结果表明该方案灵活、方便、可行,也很稳定。需要指出的是:由于FP.GA时钟频率过高,可利用分频技术,使得I2C总线时钟频率在规范要求的范围内,同时,在开发过程中要严格按照I2C总线的时序要求编写相关代码。
文章评论(0条评论)
登录后参与讨论