第七章 实战项目提升,完善简历
19.OV7725摄像头实时采集送HDMI显示(二)
在正式介绍OV7725 CMOS Sensor视频采集前,首先需要去详细说明OV7725的寄存器配置接口,这里有OmniVision公司推出的官方手册 “OV7725_software_application_note”可供大家参考。
根据手册我们了解到OV7725上电时默认是输出YUV422格式的视频流,但用户希望其根据不同需求又可以工作在不同模式下,那么这里显然需要去配置分辨率、内部时钟、亮度色彩等等参数,于是乎就引入了SCCB接口即Serial Camera Control Bus,串行相机控制总线。
实际上OV7725的SCCB接口就是嵌入式开发中常用的IIC接口,只不过OmniVision公司针对CMOS Sensor提供了一个专门术语,其中OV7725的SCCB接口有两个信号即时钟信号SCL和数据信号SDA,OV7725通过这两个信号完成内部寄存器的配置,达到输出预期视频流的目的。
尽管SCCB总线和IIC总线协议很相似,但OmniVision公司还是专门给出了SCCB接口的介绍手册“OmniVision Serial Camera Control Bus (SCCB) Functional Specification”,手册详细介绍了SCCB总线接口配置细节,也给出了其读写的时序逻辑,OmniVision公司旗下的所有系列CMOS Sensor均可以参照该手册的SCCB时序进行初始化寄存器配置。
SCCB总线通过串行方式发送8位数据,默认高位先发低位后发,发送完8位数据后,并通过器件的响应信号完成一次数据的传输,如图1所示官方手册在这里也给出了SCCB总线8位数据串行发送的时序图,其中SCCB_E作为IIC的使能信号类似于SPI总线的CS片选信号,在这里FPGA对OV7725进行一对一控制无需关注。
图1 SCCB总线8位数据串行发送的时序图
如图2所示是SCCB总线寄存器传输的时序图,首先写入设备地址,再写入寄存器地址或者读取寄存器的值,最后写入寄存器的值,每次传输数据都为8位,即ID Address + Sub Address/Read Data + Write Data的流程,手册上也对Phase1、Phase2、Phase3给出了官方说明:
Phase1:CMOS Sensor的唯一ID地址,OmniVision相机的设备地址是0x42,其中最后一位用来区分读取或者写入操作的,即写入时ID地址是0x42,读取时ID地址是0x43;
Phase2:对于SCCB总线的写入操作来说,Sub Address地址即为传感器需要配置的寄存器物理地址;对于SCCB总线的读取操作来说,Read Data即为传感器读取到指定寄存器物理地址的数据;
Phase3:针对Phase2所指定的寄存器物理地址,传输需要设定的寄存器数据;
图2 SCCB总线寄存器传输的时序图
对应的手册里也对读写流程进行了细分,如图3所示是SCCB总线寄存器的写入流程图,FPGA端先发送ID Address(0x42),再发送Sub Address,最后发送Write Data即完成写入指定寄存器数据的操作。
相对于写入操作,读取操作更为复杂一些,如图4所示是SCCB总线寄存器的读取流程图,FPGA端先发送ID Address(0x42)和发送Sub Address,再发送ID Address(0x43),最后读取到Read Data即完成读取指定寄存器数据的操作。
在OV7725正常工作前,必须先对传感器进行初始化,即通过配置寄存器使其工作在预期的工作模式以得到更好画质的图像。
图3 SCCB总线寄存器的写入流程图
图4 SCCB总线寄存器的读取流程图
虽然说SCCB是一种与IIC非常相近的通信协议,但是实际上还有些细微差别,在程序设计当中有些地方需要大家去注意,所以笔者在这里简单地做了总结:
- SCCB传输协议中第9位是不必关心位即不用关注该位的数据,而IIC写传输协议中则此位是应答位需要去判断从机是否发送低电平响应主机的传输;
- SCCB每次传输不超过3个阶段(Phase), 也就是说不能像IIC一样连续地去进行读写操作;
- SCCB读取传输协议中,没有重复开始的概念,即在写完寄存器地址后,发送停止信号;
在整理完“OmniVision Serial Camera Control Bus (SCCB) Functional Specification“即SCCB的接口功能手册上的有效信息后,明白了SCCB的读写时序逻辑后,显然我们需要去更进一步地了解在程序设计当中,需要初始化哪些寄存器,而这些寄存器对应的写入数据又是多少。
根据“OV7725_software_application_note“即OV7725软件应用手册介绍,我们能了解到OV7725实际上一共包含了172个读写寄存器,以用于CMOS Sensor的工作模式的配置,在这里有的寄存器只支持读取或者写入,有的既支持读取又支持写入,在传感器正常工作前,需要用户人为地进行初始化配置才能工作在预取模式下,在这里虽然对这172个寄存器都可以通过SCCB总线进行配置,但是也并非所有的寄存器都需要配置,有些寄存器直接保持默认值即可。
在OV7725初始化寄存器配置中,笔者依然延续之前例程如“初始化WM8731芯片“的设计方法,把需要配置的寄存器单独列出来分成一个模块,再在另一个模块中完成对SCCB的读写协议时序逻辑设计,这样更容易实现自顶向下模块化的编程。
如表1所示是config_ov7725_rgb565模块的信号列表,这个模块存储了70个寄存器物理地址和对应读写寄存器的参数值,在这里笔者把读取制造商ID号作为第零号和第一号寄存器也添加了进来。通常在驱动一款IC时,除了上板示波器观察视频流输出波形,ILA在线调试抓取波形等外,通过软件的方法读取制造商ID号也是最为行之有效的方法,以确认CMOS Sensor是否工作在正常模式下,整个SCCB的时序逻辑是否正确,这个技巧在“FLASH读写“例程中笔者也曾强调过。
信号列表 | ||
信号名 |
I/O |
位宽 |
lut_index |
I |
8 |
lut_data |
O |
16 |
lut_size |
O |
8 |
表1 config_ov7725_rgb565模块信号列表
如图7-32 所示是OV7725初始化寄存器值模块的代码设计,在这里把OV7725初始化配置成大家所熟知的RGB565视频流格式输出,对于这个模块中的70个读写寄存器在这里也做进一步的说明:
- 寄存器编号0和1是读取寄存器,寄存器物理地址0xh1c和0x1d分别是16位制造商ID号的高8位和低8位;
- 寄存器编号2到15是对CMOS Sensor分辨率、图像输出格式、像素时钟的配置。这些寄存器主要完成OV7725输出图像的分辨率、输出格式、内部时钟、行/场信号的电平配置等,这里配置视频输出模式为RGB565的640像素*480像素,笔者在这里对寄存器物理地址0x15配置参数值为0x02,即保持VSYNC信号和VGA驱动时序一致(OV7725默认输出场信号VSYNC为低电平时有效);
- 寄存器编号16到22是DSP图像处理器的初始化,这几个寄存器主要配置了CMOS Sensor内部DSP进行图像处理的参数包括色彩等;
- 寄存器编号23到33是对CMOS Sensor自动增益、自动曝光、自动白平衡参数的配置,在这里笔者配置称自动切换模式;
- 寄存器编号34到52是对CMOS Sensor边缘锐度、亮度、噪声抑制等参数的配置,这里使用了统一的OV7725寄存器配置方案;
- 寄存器编号53到69是对CMOS Sensor校准参数和其他参数的配置;
如图5所示是OV7725初始化寄存器值模块的代码设计,整个模块包含了70个寄存器,其中编号0、1为读寄存器、编号2-69为写寄存器,所以当lut_index为0或者1时,SCCB的驱动模块使用读取寄存器的时序逻辑,当lut_index不为0或者1时,SCCB的驱动模块则使用写入寄存器的时序逻辑。
图5 OV7725初始化寄存器值模块的代码设计
如表2所示是i2c_ov7725模块信号列表,也延续了前面的IIC总线协议的时序设计,但是在SCCB总线协议中主机FPGA无需再对从机ACK的应答位进行判断,并且协议不支持重复开始的操作即在读取寄存器时发送完寄存器物理地址后,要先结束总线通信再发起总线通信,其次这里设定2ms的等待时间用以等待OV7725上电后进入稳定工作状态。
最后注意到在OmniVision的官方手册中也规定了SCCB的时钟scl最大频率是400Khz,这里我们依旧选用IIC总线的250Khz时钟作为驱动时钟,如图6和7所示是OV7725寄存器读取和写入流程图,在i2c_ov7725模块只需要将流程图对应的时序逻辑进行代码还原即可。为了和config_ov7725_rgb565模块相对应,设置wrl_rdh_mode为读写寄存器模式选择信号,当i2c_config_index为0或者1时,wrl_rdh_mode指示读取,反之指示为写入,如图8是OV7725初始化寄存器设置模块的代码设计。
信号列表 | ||
信号名 |
I/O |
位宽 |
clk |
I |
1 |
rst_n |
I |
1 |
i2c_config_size |
I |
8 |
i2c_config_data |
I |
16 |
i2c_sda |
I/O |
1 |
i2c_scl |
O |
1 |
i2c_config_index |
O |
8 |
i2c_config_done |
O |
1 |
表2 i2c_ov7725模块信号列表
图6 OV7725寄存器读取流程图
图7 OV7725寄存器写入流程图
图8 OV7725初始化寄存器设置模块的代码设计
如图9所示是OV7725初始化读取制造商ID的ILA波形图,大家可以清楚地看到初始化结束后rd_id_data值为16'h7fa2和手册给出的一致,也充分地证明了整个初始化模块时序逻辑设计正确。
图9 OV7725初始化读取制造商ID的ILA波形图