SCCB的总线时序与I2C基本相同,它的响应信号ACK被称为一个传输单元的第9位,分为Don’t care和NA。Don’t care位由从机产生;NA位由主机产生,由于SCCB不支持多字节的读写,NA位必须为高电平。另外,SCCB没有重复起始的概念,因此在SCCB的读周期中,当主机发送完片内寄存器地址后,必须发送总线停止条件。不然在发送读命令时,从机将不能产生Don’t care响应信号。
由于I2C和SCCB的一些细微差别,所以采用GPIO模拟SCCB总线的方式。SCL所连接的引脚始终设为输出方式,而SDA所连接的引脚在数据传输过程中,通过设置IODIR的值,动态改变引脚的输入/输出方式。SCCB的写周期直接使用I2C总线协议的写周期时序;而SC-CB的读周期,则增加一个总线停止条件 
//--------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------
2.2 SCCB通信规范
SCCB(Serial Camera Control Bus)是OminiVision公司定义的主从模式串行通信协议,用于控制该公司图像传感器系列芯片的内部寄存器。该协议有通信使能信号SIO_E、时钟信号SIO_C和数据信号SIO_D,在简化引脚的封装中不再提供SIO_E引脚,协议也变成了两线串行通信。协议支持的最高串行通信速率是400 Kb/s,规定图像传感器在通信中只能作为SLAVE工作。一SCCBMASTER可以控制1~8个SLAVE工作,由不同的ID来识别,在只有一个SLAVE时固定SLAVE的ID为42H(写)和43H(读)。该协议符合网络摄像机CPU的I2C口时序子集,设计中OV529作为SCCB的MASTER,并且只带1个SLAVE OV7720。协议要求数据线必须在时钟信号高电平期间稳定,在低电平时更新。协议支持3字节写、2字节写和2字节读三种传输模式。传输数据时每个字节包括9位串行数据位,除了8位数据,还有第9位不相关位或NA位,用在有多个SLAVE的系统来标识通信是否完成。SLAVE可以用两种方式应答该位,一种是正在被写的SLAVE在收到数据后驱动该位为0表示成功;另一种是SLAVE不应答该位,这种情况下所有SLAVE的第9位保持悬空。在3字节写周期MASTER必须提供子地址,即芯片中寄存器的地址,第3字节为所写数据。读周期不提供子地址,但必须由MASTER把数据后的NA位(第9位)驱动为高电平。所以在每个读周期前必须有3字节或2字节写操作,使SLAVE获得寄存器地址,其中的2字节写周期并没有写数据,它的用途是在读操作前提供给SLAVE子地址。 3 硬件系统实现 3.1 微控制器模块 微控制器模块是该系统的核心部件,采用Atmel公司的ARM7芯片AT91SAM7X256作为系统的主控芯片。它是一款Atmel 32位ARM RISC处理器小引脚数FLASH微处理器,主频为55 MHz,处理速度快,功能强,性价比高,能很好地满足嵌入式Linux系统的需求。它在系统中的主要作用是在系统上电时配置其他芯片的功能寄存器,在正常工作状态下调度整个系统工作,通过片内以太网控制器控制物理层芯片发送码流,并通过片内的SPI总线实现对外围DATAFLASH和SDRAM的控制。 3.2 网络模块 AT91SAM7X256的在片以太网卡端口与网络物理层芯片DM9161E的MII接口通信。发送数据时首先置发送使能信号ETXEN有效。数据发送端ETX0~ETX1与DM9161E的ETX0~ETX1引脚对应连接,作为数据发送通道,以DM9161E的时钟信号REF_CLK发送数据。数据接收端ERX0~ERX1与DM9161E的RXD0~RXD1引脚对应连接,作为数据接收通道。管理时钟信号EMDC和管理数据输入/输出信号EMDIO用于芯片控制参数的写入和读取。DM9161E的MDINTR端用来产生中断信号。片内以太网卡通过DMA通道进行数据发送,不影响AT91SAM7X256的正常运行。首先正确设置传送控制寄存器和传送地址寄存器的传送数据块字节数、数据块存储首地址等参数,随后依次从指定数据存储区地址读取数据,送入内部发送缓冲器中,由MAC对数据进行封装发送,同时记录已传送字节数,直到数据块发送完毕。当发送完一组数据后,发出DMA中断请求,由AT91SAM-7X256进行相应的处理。整个网络子系统电路由AT91SAM7X256控制和调度。 3.3 相机控制模块 相机控制模块包括图像采集传感器OV7720和相机控制芯片OV529。OV7720内含A/D转换和DSP,能够直接将图像信号数字化,并通过相机接口向OV529直接输出并行的数字化图像信号。 OV529自带的MCU进行各种控制,它通过串行相机控制总线(SCCB)与OV7720交互控制信息实现对图像传感器的控制和数据采集。OV529包含一个压缩引擎,对从OV7720采集的图像信息帧进行压缩,压缩后的信号经OV529的串行通信传给主控芯片AT91SAM7X512,再经AT91SAM7X512上的MAC层处理,通过网络接口将视频流发送到网络上。 4 软件设计 嵌入式Linux系统由4个部分组成:引导内核启动的文件bootloader,Linux内核文件kernel,虚拟磁盘文件ramdisk和用户空间文件use-r。它们分别被放在DATAFLASH内的4个分区模块中。根据不同模块的具体功能采用不同的文件系统:bootloader,kernel,ramdisk。移植完成后不需要动态改变,使用较节省空间的ROMFS只读文件系统。user模块内放置一些可以动态更新的配置文件等。需要进行较多次的读/写操作,所以使用支持动态擦写保存的JFFS2文件系统。 4.1 CGI控制程序设计 应用程序接口(Common Gateway Interface,CGI),提供Web Server执行外部程序的通道,CGI程序编译成可执行文件,放在服务器端运行,服务器根据用户的请求调用相应的CGI程序,并将CGI程序得到的动态信息封装到页面中,发送到用户浏览器上。该系统CGI的工作过程是在PC机端的IE浏览器中输入网络摄像机IP地址,嵌入式网络服务器根据要求,将相应的控制页面反馈给IE浏览器,用户填写表单,然后提交,CGI程序提取信息,并根据得到的信息作相应的处理,如调节相机的转向、焦距等。CGI模块的设计主要包括三部分:嵌入式Web服务器的配置、HTML页面的编写、CGI程序的设计。嵌入式Web服务器采用的是Apache,其配置是以配置文件的形式提供,放在Ramdisk中,其配置主要涉及配置根文件路径、配置CGI外部程序所放的路径和配置环境变量三个方面。网页编写采用HTML与SHTML相结合的方式。HTML的解析速度较快,SHTML可以在普通网页中嵌入外部CGI程序,通过这种方式将系统的默认配置反馈给客服端。CGI程序采用的是C语言和Shell脚本相结合的方式,具体编写过程与Linux下编程相同。 4.2 解码程序 该部分已成功做成Toolbox插件,该插件只要在PC机上注册安装后,就可方便地被网页调用,从而实现在PC机上实时观看视频。安装后的实图如图2所示。

5 结语 本文利用CMOS图像传感器设计了一款嵌入式网络摄像机。经测试,系统稳定、可靠、实时性好,图像清晰度明显好于同价位的产品,完全可满足目前网络摄像头市场对中、低端产品的要求,具有良好的市场前景。 //--------------------------------------------------------------------------------------------------------------------
SCCB(OmniVision serial camera control bus),即串行摄像机控制总线。OmniVision 公司已经定义和 采纳的SCCB总线是一种三线结构的串行总线,用于完成对绝大多数OmniVision 系列图像传芯片功能的控制。 在简化的引脚封装中,SCCB总线可以工作在改进的两线工作方式下。 两线SCCB接口有两条通迅连接线,即SIO_D(数据线)和 SIO_C(时钟线),下面是双总线功能原理图: 在双总线情况下,要求主控机有以下两种功能之一来支持SCCB通迅: 1、主控器件支持并能保持数据在三态模式; 2、如果不支持三态,
二、管脚功能 主控器件管脚描述 从控器件管脚描述 SCCB——E 信号 低电平有效,一个高到低的转换表明数据传输开始;一个低到高的转换表明数据传输结束;数据传输过程保持为低 电平;高电平表明总线处于空闲状态。在SCCB——E表明数据传输开始之前主机必须将数据线SIO——D置为1,这样可以避免 总线数据传输开始之前的总线不确定状态的出现。 SIO——C 信号 高电平有效,当处于空闲状态时必须被拉高;当启动传输后,SIO——C被拉低表明数据传输的开始,传输过程中高电平 表明一位数据正在传输,所以SIO——D的数据变化只能在SIO——C为低时发生,一位传输时间定义为tCYC,最小为10us。 三总线数据传输 SIO——D信号 可以被主机和从机驱动,当总线处于空闲时保持悬浮或三态; 在传输Don‘t-Car()e或NA位时,总线浮动和争用是允许的 SIO——C的一个高电平表明一位数据的传输,SIO——D只能在SIO——C的低电平期间发生变化,但在传输的开始和结束 也有例外,在SCCB——E断言并且SIO——C拉低之前,SIO——D可以被拉低,在SIO——C拉高之前和去断言之前,SIO——D 也可以被拉低。 数据传输的起始 SCCB——E由高到低的变化,表明数据传输的开始,在SCCB——E断言之前,主机必须把SIO——D拉高,这样可以避免 在数据传输之前传输一个不确定的总线状态;在SCCB——E去断言之后,主机必须把SIO——D拉高在一个定义的时间段 内,来再次避免一个不确定状态的总线状态传输。 在启动传输过程中有两个时间参数,TPRA和TPRC,TPRC被定义为SID——D预充电时间,这表明SIO——D必须先于 SCCB——E被拉高的时间,最小值为15ns,TPRA被是指在SIO——D拉低之前,SID——E必须被断言的时间,最小为1.25us。 数据传输的终止
TPSC是SCCB——E去断言后,SIO——D保持逻辑高电平的时间,最小为15ns,TPSA 是SIO——D去断言后,SCCB——E必须保持低电平的时间,最小为0ns。 传输阶段 SCCB读数据的Verilog实现 `START1 : begin
//Rd_Data <= 8'h0;
if( Shift_Start == 1 )
I2C_Start( Start_Buf);
else begin
if( Scl_r == 1'b1) begin
Scl_Ctrl <= 1'b1;
M_State <= `WR_ID1;
Shift_Start <= 1'b1;
// Scl_Ctrl <= 1'b0;
end
else M_State <= `START1;
end
end
`WR_ID1 : begin
if( Shift_Start == 1'b1 )
Shift8_Out( WR_id );
else begin
Shift_Start <= 1'b1;
M_State <= `WR_SB_AR1;
end
end
`WR_SB_AR1 : begin
if( Shift_Start == 1'b1 )
Shift8_Out ( 8'h11 );
else begin
Shift_Start <= 1'b1;
M_State <= `END2;
end
end
`END2 : begin
if( Scl_r == 1'b1 )
Scl_Ctrl <= 1'b0;
else if( Shift_Start == 1'b1)
I2C_End( End_Buf);
else begin
M_State <= `IDLE2;
// Shift_Start <= 1'b1;
end
end
`IDLE2 : begin
Scl_Ctrl <= 1'b0;//Scl 设置为高电平
Sda_io_Flag <= 1'b0;//Sda 设置为高阻
Sda_Reg <= 1'b1;
M_State <= `START2;
Shift_Start <= 1'b1;
end
`START2 : begin
// Rd_Data <= 8'h0;
if( Shift_Start == 1 )
I2C_Start( Start_Buf);
else begin
if( Scl_r == 1'b1) begin
Scl_Ctrl <= 1'b1;
M_State <= `RD_ID;
Shift_Start <= 1'b1;
// Scl_Ctrl <= 1'b0;
end
else M_State <= `START2;
end
end
`RD_ID : begin
if( Shift_Start == 1'b1)
Shift8_Out ( RD_id );
else begin
Shift_Start <= 1'b1;
M_State <= `RD_DATA;
// Sda_io_Flag <= 1'b1;
end
end
`RD_DATA : begin
if( Shift_Start == 1'b1 ) begin
Shift8_in( Rd_Data );
Sda_io_Flag <= 1'b1;
end
else begin
Sda_io_Flag <= 1'b0;
if( Scl_r == 1'b1 ) begin
M_State <= `END1;
Shift_Start <= 1'b1;
end
end
end `END1 : begin
if( Scl_r == 1'b1 )
Scl_Ctrl <= 1'b0;
else if( Shift_Start == 1'b1)
I2C_End( End_Buf);
else begin
M_State <= `IDLE1;
// Shift_Start <= 1'b1;
end
end
`IDLE1 : begin
Scl_Ctrl <= 1'b0;//Scl 设置为高电平
Sda_io_Flag <= 1'b0;//Sda 设置为高阻
Sda_Reg <= 1'b1;
M_State <= `START1;
Shift_Start <= 1'b1;
end
|