9. ov7725摄像头hdmi图像显示¶
上一章节完成并实现了OV7725图像采集+VGA实时显示,在本章节使用HDMI显示替换VGA显示,实现OV7725图像采集+HDMI实时显示。
9.1. 理论学习¶
参见“OV7725摄像头VGA图像显示”的“理论学习”小节。
9.2. 实战演练¶
9.2.1. 实验目标¶
使用SDRAM做图像数据缓存,将OV7725摄像头采集到的图像数据在HDMI显示器上实时显示。分辨率为640*480。
9.2.2. 硬件资源¶
参见“OV7725摄像头VGA图像显示”的“硬件资源”小节。
9.3. 程序设计¶
9.3.1. 整体说明¶
在本小节我们讲解一下实验工程的整体框架,整体框图和子功能模块介绍,具体见图 59‑1、表格 59‑1。
图 59‑1 OV7725-HDMI图像显示整体框图
表格 59‑1 OV7725-HDMI图像显示各子模块功能描述
模块名称 |
功能描述 |
---|---|
ov7725_hdmi_640x480 |
实验工程顶层模块 |
clk_gen |
时钟生成模块 |
ov7725_top |
OV7725相关部分 |
sdram_top |
SDRAM读写控制器 |
vga_ctrl |
VGA驱动模块 |
hdmi_ctrl |
HDMI驱动模块 |
由图表可知,OV7725-HDMI图像显示工程包含6个模块,ov7725_hdmi_640x480作为实验工程的顶层模块,内部实例化各子功能模块,连接对应信号,对外接收摄像头采集的图像数据,将处理后的数据存入SDRAM,在HDMI显示器上显示出来;clk_gen模块,调用IP核生成,产生整个实验工程 的工作时钟;ov7725_top模块,是ov7725部分各子功能模块的集合,实现ov7725摄像头的配置、图像采集与处理;sdram_top模块为SDRAM读写控制器,存储处理后的图像数据;vga_ctrl模块实现VGA显示器的驱动控制,读取SDRAM存储的图像数据;hdmi_ctrl模块将vga_ ctrl模块传入的图像数据转换为hdmi图像信号,并在HDMI显示屏上显示出来。
到了这里,实验工程的整体框架我们介绍完毕,对于内部的各个子功能模块的设计与实现,我们会在后面的小结进行详细讲解,但对于调用IP核生成的时钟生成模块clk_gen、OV7725图像采集模块ov7725_top、SDRAM读写控制器sdram_top、VGA驱动模块vga_ctrl、HDMI驱动模块hd mi_ctrl,在前面的章节已经做过 详细介绍,在这里不在过多叙述。对于SCCB通讯协议模块,可使用I2C驱动模块代替。
9.3.1.1. 顶层模块¶
顶层模块是使用工程必不可少的一部分,内部实例化个子功能模块,外部进行工程输入输出信号的连接,作用巨大。但顶层模块代码写起来较为简单,无需波形图绘制,只需连接对应端口即可。顶层模块参考代码具体见代码清单 59‑1。
代码清单 59‑1 顶层模块参考代码(ov7725_hdmi_640x480.v)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | module ov7725_hdmi_640x480
(
input wire sys_clk , //输入系统时钟,50MHz
input wire sys_rst_n , //输入复位信号,低电平有效
//CMOS
input wire [7:0] ov7725_data , //摄像头采集图像数据
input wire ov7725_vsync , //摄像头采集图像场同步信号
input wire ov7725_href , //摄像头采集图像行同步信号
input wire ov7725_pclk , //摄像头像素时钟
output wire ov7725_rst_n , //
output wire ov7725_pwdn , //
output wire sccb_scl , //SCCB串行时钟
inout wire sccb_sda , //SCCB串行数据
//SDRAM
output wire sdram_clk , //SDRAM 芯片时钟
output wire sdram_cke , //SDRAM 时钟有效
output wire sdram_cs_n , //SDRAM 片选
output wire sdram_ras_n , //SDRAM 行有效
output wire sdram_cas_n , //SDRAM 列有效
output wire sdram_we_n , //SDRAM 写有效
output wire [1:0] sdram_dqm , //SDRAM 数据掩码
output wire [1:0] sdram_ba , //SDRAM Bank地址
output wire [12:0] sdram_addr , //SDRAM 行/列地址
inout wire [15:0] sdram_dq , //SDRAM 数据
//HDMI
output wire tmds_clk_p ,
output wire tmds_clk_n , //HDMI时钟差分信号
output wire [2:0] tmds_data_p ,
output wire [2:0] tmds_data_n //HDMI图像差分信号
);
////
//\* Parameter and Internal Signal \//
////
//parameter define
parameter H_PIXEL = 640;
parameter V_PIXEL = 480;
//wire define
wire clk_125m ;
wire clk_125m_shift ;
wire clk_25m ;
wire locked1 ;
wire clk_74m ;
wire clk_371m ;
wire locked2 ;
wire rst_n ;
wire sdram_init_done ;
wire cfg_done ;
wire sys_init_done ;
wire [15:0] image_data ;
wire image_data_en ;
wire [15:0] vga_rgb ;
wire rdreq ;
wire vga_hs ;
wire vga_vs ;
wire vga_de ;
wire [7:0] vga_r ;
wire [7:0] vga_g ;
wire [7:0] vga_b ;
assign ov7725_pwdn = 1'b0;
assign ov7725_rst_n = 1'b1;
assign rst_n = (sys_rst_n & locked1 & locked2);
assign sys_init_done = sdram_init_done & cfg_done;
////
//\* Instantiate \//
////
//------------- clk_gen_inst -------------
clk_gen clk_gen_inst
(
.areset (~sys_rst_n ),
.inclk0 (sys_clk ),
.c0 (clk_125m ),
.c1 (clk_125m_shift ),
.c2 (clk_25m ),
.locked (locked1 )
);
//------------- clk_hdmi_inst -------------
clk_hdmi clk_hdmi_inst
(
.areset (~sys_rst_n ),
.inclk0 (sys_clk ),
.c0 (clk_74m ),
.c1 (clk_371m ),
.locked (locked2 )
);
//------------- ov7725_top_inst -------------
ov7725_top ov7725_top_inst
(
.sys_clk (clk_25m ), //系统时钟
.sys_rst_n (rst_n ), //复位信号
.sys_init_done (sys_init_done ), //系统初始化完成(SDRAM + 摄像头)
.ov7725_pclk (ov7725_pclk ), //摄像头像素时钟
.ov7725_href (ov7725_href ), //摄像头行同步信号
.ov7725_vsync (ov7725_vsync ), //摄像头场同步信号
.ov7725_data (ov7725_data ), //摄像头图像数据
.cfg_done (cfg_done ), //寄存器配置完成
.sccb_scl (sccb_scl ), //SCL
.sccb_sda (sccb_sda ), //SDA
.ov7725_wr_en (image_data_en ), //图像数据有效使能信号
.ov7725_data_out (image_data ) //图像数据
);
//------------- sdram_top_inst -------------
sdram_top sdram_top_inst
(
.sys_clk (clk_125m ), //sdram 控制器参考时钟
.clk_out (clk_125m_shift ), //用于输出的相位偏移时钟
.sys_rst_n (rst_n ), //系统复位
//用户写端口
.wr_fifo_wr_clk (ov7725_pclk ), //写端口FIFO: 写时钟
.wr_fifo_wr_req (image_data_en ), //写端口FIFO: 写使能
.wr_fifo_wr_data (image_data ), //写端口FIFO: 写数据
.sdram_wr_b_addr (24'd0 ), //写SDRAM的起始地址
.sdram_wr_e_addr (H_PIXEL*V_PIXEL), //写SDRAM的结束地址
.wr_burst_len (10'd512 ), //写SDRAM时的数据突发长度
.wr_rst ( ), //写端口复位
//用户读端口
.rd_fifo_rd_clk (clk_74m ), //读端口FIFO: 读时钟
.rd_fifo_rd_req (rdreq ), //读端口FIFO: 读使能
.rd_fifo_rd_data (vga_rgb ), //读端口FIFO: 读数据
.sdram_rd_b_addr (24'd0 ), //读SDRAM的起始地址
.sdram_rd_e_addr (H_PIXEL*V_PIXEL), //读SDRAM的结束地址
.rd_burst_len (10'd512 ), //从SDRAM中读数据时的突发长度
.rd_fifo_num ( ), //读fifo中的数据量
.rd_rst ( ), //读端口复位
//用户控制端口
.read_valid (1'b1 ), //SDRAM 读使能
.pingpang_en (1'b1 ), //SDRAM 乒乓操作使能
.init_end (sdram_init_done), //SDRAM 初始化完成标志
//SDRAM 芯片接口
.sdram_clk (sdram_clk ), //SDRAM 芯片时钟
.sdram_cke (sdram_cke ), //SDRAM 时钟有效
.sdram_cs_n (sdram_cs_n ), //SDRAM 片选
.sdram_ras_n (sdram_ras_n ), //SDRAM 行有效
.sdram_cas_n (sdram_cas_n ), //SDRAM 列有效
.sdram_we_n (sdram_we_n ), //SDRAM 写有效
.sdram_ba (sdram_ba ), //SDRAM Bank地址
.sdram_addr (sdram_addr ), //SDRAM 行/列地址
.sdram_dq (sdram_dq ), //SDRAM 数据
.sdram_dqm (sdram_dqm ) //SDRAM 数据掩码
);
//------------- vga_ctrl_inst -------------
vga_ctrl vga_ctrl_inst
(
.vga_clk (clk_74m ), //输入工作时钟,频率25MHz
.sys_rst_n (rst_n ), //输入复位信号,低电平有效
.pix_data ({vga_rgb[15:11], 3'd0, vga_rgb[10:5], 2'd0,
vga_rgb[4:0], 3'd0}), //输入像素点色彩信息
.pix_data_req(rdreq ), //数据请求信号
.hsync (vga_hs ), //输出行同步信号
.vsync (vga_vs ), //输出场同步信号
.rgb_valid (vga_de ), //数据有效信号
.red (vga_r ),
.green (vga_g ),
.blue (vga_b ) //图像色彩有效信息
);
//------------- hdmi_ctrl_inst -------------
hdmi_ctrl hdmi_ctrl_inst
(
.clk_1x (clk_74m ), //输入系统时钟
.clk_5x (clk_371m ), //输入5倍系统时钟
.sys_rst_n (rst_n ), //复位信号,低有效
.rgb_blue (vga_b ), //蓝色分量
.rgb_green (vga_g ), //绿色分量
.rgb_red (vga_r ), //红色分量
.hsync (vga_hs ), //行同步信号
.vsync (vga_vs ), //场同步信号
.de (vga_de ), //使能信号
.hdmi_clk_p (tmds_clk_p ),
.hdmi_clk_n (tmds_clk_n ), //时钟差分信号
.hdmi_r_p (tmds_data_p[2]),
.hdmi_r_n (tmds_data_n[2]), //红色分量差分信号
.hdmi_g_p (tmds_data_p[1]),
.hdmi_g_n (tmds_data_n[1]), //绿色分量差分信号
.hdmi_b_p (tmds_data_p[0]),
.hdmi_b_n (tmds_data_n[0]) //蓝色分量差分信号
);
endmodule
|
本实验工程调用的模块大多为复用前面的模块,模块仿真在前面章节已经通过验证,此处不再进行仿真验证。
9.3.1.2. RTL视图¶
至此实验工程基本完成,在Quartus中对代码进行编译,编译若有错误,请读者根据错误提示信息作出更改,直至编译通过,编译通过后查看RTL视图,与顶层模块框图对比,两者一致,各信号连接正确。RTL视图,具体见图 59‑2。
图 59‑2 RTL视图
9.4. 上板调试¶
9.4.1. 引脚约束¶
仿真验证通过后,准备上板验证,上板验证之前先要进行引脚约束。工程中各输入输出信号与开发板引脚对应关系如表格 59‑2所示。
表格 59‑2 引脚分配表
信号名 |
信号类型 |
对应引脚 |
备注 |
---|---|---|---|
sys_clk |
Input |
E1 |
时钟 |
sys_rst_n |
Input |
M15 |
复位 |
ov7725_data[7] |
Input |
L13 |
OV7725摄像头采集图像数据 |
ov7725_ data[6] |
Input |
F13 |
OV7725摄像头采集图像数据 |
ov7725_ data[5] |
Input |
B16 |
OV7725摄像头采集图像数据 |
ov7725_ data[4] |
Input |
C15 |
OV7725摄像头采集图像数据 |
ov7725_ data[3] |
Input |
D16 |
OV7725摄像头采集图像数据 |
ov7725_ data[2] |
Input |
F14 |
OV7725摄像头采集图像数据 |
ov7725_ data[1] |
Input |
F15 |
OV7725摄像头采集图像数据 |
ov7725_ data[0] |
Input |
G15 |
OV7725摄像头采集图像数据 |
ov7725_href |
Input |
J13 |
摄像头行同步信号 |
ov7725_vsync |
Input |
C16 |
摄像头场同步信号 |
ov7725_pclk |
Input |
M16 |
摄像头数据像素时钟 |
ov7725_pwdn |
Output |
G11 |
摄像头时钟选择信号 |
ov7725_rst_n |
Output |
F16 |
摄像头复位信号 |
sccb_scl |
Output |
P15 |
摄像头SCCB_SCL线 |
sccb_sda |
Inout |
N14 |
摄像头SCCB_SDA线 |
sdram_clk |
Output |
R4 |
SDRAM芯片时钟 |
sdram_cke |
Output |
R9 |
SDRAM时钟有效信号 |
sdram_cs_n |
Output |
R12 |
SDRAM片选信号 |
sdram_cas_n |
Output |
R10 |
SDRAM列地址选通脉冲 |
sdram_ras_n |
Output |
R11 |
SDRAM行地址选通脉冲 |
sdram_we_n |
Output |
L9 |
SDRAM写允许位 |
sdram_ba[0] |
Output |
R13 |
SDRAM的L-Bank地址线 |
sdram_ba[1] |
Output |
R14 |
SDRAM的L-Bank地址线 |
sdram_addr[0] |
Output |
P11 |
SDRAM地址总线 |
sdram_addr[1] |
Output |
P14 |
SDRAM地址总线 |
sdram_addr[2] |
Output |
N9 |
SDRAM地址总线 |
sdram_addr[3] |
Output |
N11 |
SDRAM地址总线 |
sdram_addr[4] |
Output |
T14 |
SDRAM地址总线 |
sdram_addr[5] |
Output |
T13 |
SDRAM地址总线 |
sdram_addr[6] |
Output |
T12 |
SDRAM地址总线 |
sdram_addr[7] |
Output |
T11 |
SDRAM地址总线 |
sdram_addr[8] |
Output |
T10 |
SDRAM地址总线 |
sdram_addr[9] |
Output |
P9 |
SDRAM地址总线 |
sdram_addr[10] |
Output |
T15 |
SDRAM地址总线 |
sdram_addr[11] |
Output |
N12 |
SDRAM地址总线 |
sdram_addr[12] |
Output |
M11 |
SDRAM地址总线 |
sdram_dqm[0] |
Output |
M10 |
SDRAM数据掩码 |
sdram_dqm[1] |
Output |
M9 |
SDRAM数据掩码 |
sdram_dq[0] |
Output |
R3 |
SDRAM数据总线 |
sdram_dq[1] |
Output |
T9 |
SDRAM数据总线 |
sdram_dq[2] |
Output |
R5 |
SDRAM数据总线 |
sdram_dq[3] |
Output |
R6 |
SDRAM数据总线 |
sdram_dq[4] |
Output |
R7 |
SDRAM数据总线 |
sdram_dq[5] |
Output |
M8 |
SDRAM数据总线 |
sdram_dq[6] |
Output |
R8 |
SDRAM数据总线 |
sdram_dq[7] |
Output |
N8 |
SDRAM数据总线 |
sdram_dq[8] |
Output |
P8 |
SDRAM数据总线 |
sdram_dq[9] |
Output |
T8 |
SDRAM数据总线 |
sdram_dq[10] |
Output |
T7 |
SDRAM数据总线 |
sdram_dq[11] |
Output |
T6 |
SDRAM数据总线 |
sdram_dq[12] |
Output |
T5 |
SDRAM数据总线 |
sdram_dq[13] |
Output |
T4 |
SDRAM数据总线 |
sdram_dq[14] |
Output |
T3 |
SDRAM数据总线 |
sdram_dq[15] |
Output |
T2 |
SDRAM数据总线 |
tmds_clk_p |
Output |
R16 |
时钟差分信号 |
tmds_clk_n |
Output |
P16 |
时钟差分信号 |
tmds_data_p[2] |
Output |
K15 |
红色分量差分信号 |
tmds_data_n[2] |
Output |
K16 |
红色分量差分信号 |
tmds_data_p[1] |
Output |
L15 |
绿色分量差分信号 |
tmds_data_n[1] |
Output |
L15 |
绿色分量差分信号 |
tmds_data_p[0] |
Output |
N15 |
蓝色分量差分信号 |
tmds_data_n[0] |
Output |
N16 |
蓝色分量差分信号 |
下面进行管脚分配,管脚的分配方法在前面章节已有所讲解,在此就不再过多叙述,管脚的分配如下图 59‑3、图 59‑4所示。
图 59‑3 管脚分配
图 59‑4 管脚分配
9.4.1.1. 结果验证¶
如图 59‑5所示,开发板连接12V直流电源、USB-Blaster下载器JTAG端口、HDMI显示器和OV7725摄像头。线路正确连接后,打开开关为板卡上电。
图 59‑5 程序下载连线图
如图 59‑6所示,使用“Programmer”为开发板下载程序。
图 59‑6 程序下载图
程序下载完成后,HDMI显示屏上会显示出OV7725摄像头采集到的图像,分辨率为640*480,如图 59‑7所示。
图 59‑7 OV7725+HDMI图像显示
9.5. 章末总结¶
本章节详细介绍了OV7725摄像头的相关知识,并将OV7725摄像头与HDMI相结合,实现了OV7725采集图像的实时显示,本章节对于OV7725的使用知识冰山一角,OV7725还有更多强大功能,读者查阅数据手册深入学习。