11. ov5640摄像头vga图像显示

在前面章节,我们学习了摄像头的相关知识,并对OV7725摄像头做了详细介绍,实现了OV7725-VGA、OV7725-HDMI和OV7725-TFT的实时图像显示。

在本章节,我们将对另一款更高端的摄像头OV5640进行相关知识的学习,并实现OV5640-VGA的实时图像显示。

11.1. 理论学习

11.1.1. 摄像头简介

参见“OV7725摄像头VGA显示”章节的“摄像头简介”部分。

11.1.2. OV5640简介

本小节主要讲解实验工程使用的OV5640摄像头,摄像头实物具体见图 60‑1。

OV5640002

图 61‑1 OV5640摄像头实物图

该摄像头主要由镜头、图像传感器、板载电路及下方的信号引脚组成。镜头部件包含一个镜头座和一个可旋转调节距离的凸透镜,通过旋转可以调节焦距,正常使用时,镜头座覆盖在电路板上遮光,光线只能经过镜头传输到正中央的图像传感器,它采集得的图像数据直接传输给FPGA芯片,FPGA将接收到的图像数据缓存到SDRAM 中,在VGA图像显示有效区域,VGA驱动自SDRAM读取图像数据在显示屏上进行显示。

图像传感器是摄像头的核心部件,上述摄像头中的图像传感器是一款型号为 OV5640的 CMOS 类型数字图像传感器。该传感器支持输出最大为 500万像素的图像 (2592x1944分辨率),支持使用 VGA时序输出图像数据,输出图像的数据格式支持 YUV(422/420)、YCbCr422、 RGB565 以及 JPEG 格式,若直接输出 JPEG 格式的图像时可大大减少数据量,方便网络传输。它还可以对采集得的图像进行补偿,支持伽玛曲线、 白平衡、饱和度、色度等基础处理。根据不同的分辨率配置,传感器输出图像数据的帧率从 15-60帧可调,工作时功率在 150mW-200mW之间。

11.1.2.1. OV5640 引脚及功能框架图

OV5640 模组带有自动对焦功能,引脚的分布见图 61‑2。

OV5640003

图 61‑2 OV5640传感器引脚分布图

信号引脚功能介绍如下表格 61‑1。

表格 61‑1 OV5640管脚

管脚名称

管脚类型

管脚描述

SIO_C

输入

SCCB 总线的时钟线,可类比 I2C的 SCL

SIO_D

I/O

SCCB 总线的数据线,可类比 I2C的 SDA

RESET

输入

系统复位管脚,低电平有效

PWDN

输入

掉电/省电模式,高电平有效

HREF

输出

行同步信号

VSYNC

输出

帧同步信号

PCLK

输出

像素同步时钟输出信号

XCLK

输入

外部时钟输入端口,可接外部晶振

Y2„Y9

输出

像素数据输出端口

下面我们结合图 61‑3的 OV5640 功能框图讲解这些信号引脚。

OV5640004

图 61‑3 OV5640功能框图

  1. 控制寄存器

标号处的是 OV5640 的控制寄存器,它根据这些寄存器配置的参数来运行,而这些参数是由外部控制器通过 SIO_C 和 SIO_D 引脚写入的, SIO_C与 SIO_D 使用的通讯协议跟 I2C十分类似。

  1. 通信、控制信号及时钟

标号处包含了 OV5640的通信、控制信号及外部时钟,其中 PCLK、 HREF 及VSYNC分别是像素同步时钟、行同步信号以及帧同步信号,这与液晶屏控制中的信号是很类似的。 RESETB引脚为低电平时,用于复位整个传感器芯片,PWDN 用于控制芯片进入低功耗模式。注意最后的一个 XCLK引脚,它跟 PCLK是完全不同的, XCLK 是用于驱动整个传感器芯片的时钟信号,是外部输入到OV5640的信号;而 PCLK是 OV5640输出数据时的同步信号,它是由 OV5640 输出的信号。 XCLK可以外接晶振或由外部控制器提供。

  1. 感光矩阵

标号处的是感光矩阵,光信号在这里转化成电信号,经过各种处理,这些信号存储成由一个个像素点表示的数字图像。

  1. 数据输出信号

标号处包含了 DSP 处理单元,它会根据控制寄存器的配置做一些基本的图像处理运算。这部分还包含了图像格式转换单元及压缩单元,转换出的数据最终通过Y0-Y9引脚输出,一般来说我们使用 8根据数据线来传输,这时仅使用 Y2-Y9 引脚, OV5640与外部器件的连接方式见图 61‑4。

OV5640005

图 61‑4 8位数据线接法

  1. 数据输出信号

标号⑤处为 VCM 处理单元,他会通过图像分析来实现图像的自动对焦功能。要实现自动对焦还需要下载自动对焦固件到模组,后面摄像头实验详细介绍这个功能。

11.1.2.2. SCCB 时序

参见“OV7725摄像头VGA显示”章节的“SCCB时序”部分。

11.1.3. OV5640的寄存器

控制 OV5640涉及到它很多的寄存器,可直接查询《ov5640datasheet》了解,通过这些寄存器的配置,可以控制它输出图像的分辨率大小、图像格式及图像方向等。要注意的是 OV5640寄存器地址为 16位。

官方还提供了一个《OV5640_自动对焦照相模组应用指南(DVP_接口)__R2.13C.pdf》的文档,它针对不同的配置需求,提供了配置范例,见图 61‑5。其中 write_SCCB 是一个利用 SCCB向寄存器写入数据的函数,第一个参数为要写入的寄存器的地址,第二个参数为要写入的内容。

OV5640006

图 61‑5 调节帧率的寄存器配置范例

像素数据输出时序

对 OV5640采用 SCCB协议进行控制,而它输出图像时则使用 VGA时序(还可用
SVGA、 UXGA,这些时序都差不多),这跟控制液晶屏输入图像时很类似。 OV5640输出图像时,一帧帧地输出,在帧内的数据一般从左到右,从上到下,一个像素一个像素地输出(也可通过寄存器修改方向)。

例如图 61‑6,若我们使用 Y2-Y9数据线,图像格式设置为 RGB565,进行数据输出时, Y2-Y9数据线会在 1个像素同步时钟 PCLK的驱动下发送 1 字节的数据信号,所以2个 PCLK时钟可发送 1个 RGB565格式的像素数据。像素数据依次传输,每传输完一行数据时,行同步信号 HREF 会输出一个电平跳变信号,每传输完一帧图像时, VSYNC会输出一个电平跳变信号。

OV5640007

图 61‑6 DVP接口时序

11.2. 实战演练

11.2.1. 实验目标

使用SDRAM做图像数据缓存,将OV5640摄像头采集到的图像数据在VGA显示器上实时显示。分辨率640*480。

11.2.2. 硬件资源

参见“OV7725摄像头VGA图像显示”的“硬件资源”小节。

11.3. 程序设计

11.3.1. 整体说明

在本小节我们分两部分讲解一下实验工程的整体框架,第一部分是OV5640的相关模块,OV5640部分的整体框图和介绍,具体见图 61‑7、表格 61‑2。

OV5640008

图 61‑7 ov5640整体框图

表格 61‑2 OV5640各模块功能介绍

模块名称

功能描述

ov5640_top

OV5640顶层模块

i2c_ctrl

i2c驱动模块

ov5640_cfg

OV5640寄存器配置模块

ov5640_data

OV5640图像采集模块

由上述图表可知,第一部分的OV5640相关模块包含4个子模块,首先是ov5640_top模块,这一模块作为ov5640部分的顶层模块,内部实例化3个子功能模块,连接各子模块对应信号,外部对摄像头进行相关配置并接收摄像头采集的数据信息;ov5640_cfg模块,是寄存器配置模块,内部包含对ov5640 摄像头的配置信息;i2c_ctrl模块,i2c协议与SCCB协议几乎无差别,使用i2c协议代替SCCB接口协议向ov5640摄像头写入ov5640_cfg模块内部包含的寄存器配置信息;ov5640_data模块,是ov5640摄像头的图像采集模块,将摄像头传入的图像数据处理后写入SDRAM。

第一部分介绍完毕后,我们来说一下实验工程的第二部分。在第二部分中将第一部分的ov5640摄像头部分视为一个子模块,与其他子功能模块构成整个实验工程。整体框图和子功能模块介绍,具体见图 61‑8、表格 61‑3。

OV5640009

图 61‑8 OV5640-VGA图像显示整体框图

表格 61‑3 OV5640-VGA图像显示各子模块功能描述

模块名称

功能描述

ov5640_vga_640x480

实验工程顶层模块

clk_gen

时钟生成模块

ov5640_top

OV5640相关部分

sdram_top

SDRAM读写控制器

vga_ctrl

VGA驱动模块

由图表可知,OV5640-VGA图像显示工程包含表格模块,ov5640_vga_640x480作为实验工程的顶层模块,内部实例化各子功能模块,连接对应信号,对外接收摄像头采集的图像数据,将处理后的数据存入SDRAM,在VGA显示器上显示出来;clk_gen模块,调用IP核生成,产生整个实验工程的工作 时钟;ov5640_top模块,是ov5640部分各子功能模块的集合,实现ov5640摄像头的配置、图像采集与处理;sdram_top模块为SDRAM读写控制器,存储处理后的图像数据;vga_ctrl模块实现VGA显示器的驱动控制,读取SDRAM存储的图像数据并在VGA显示屏上显示出来。

到了这里,实验工程的整体框架我们介绍完毕,对于内部的各个子功能模块的设计与实现,我们会在后面的小结进行详细讲解,但对于调用IP核生成的时钟生成模块clk_gen、SDRAM读写控制器sdram_top和VGA驱动模块vga_ctrl,在前面的章节已经做过 详细介绍,在这里不在过多叙述。只对OV5640摄像头的寄存器配置模块和图像采集模块做简单介绍。

11.3.1.1. 图像采集模块

模块框图

图像采集模块的主要功能是接收并拼接OV5640摄像头传入的图像数据,模块框图和输入输出信号简介,具体见图 61‑9、表格 61‑4。

OV5640010

图 61‑9 图像采集模块框图

表格 61‑4 模块输入输出信号简介

信号

位宽

类型

功能描述

ov5640_pclk

1Bit

Input

摄像头传入工作时钟,频率24MHz

sys_rst_n

1Bit

Input

复位信号,低有效

ov5640_vsync

1Bit

Input

传入图像场同步信号

ov5640_href

1Bit

Input

传入图像行有效区域

ov5640_data

8Bit

Input

传入图像信息

ov5640_wr_en

1Bit

Output

图像信息写入SDRAM使能信号

ov5640_data_out

16Bit

Output

写入SDRAM图像信息

代码编写

模块的设计与实现与OV7725摄像头图像采集模块相同,代码也是在OV7725摄像头图像采集模块代码基础上稍作修改得到。这里不再进行波形图的绘制与讲解,只列出模块参考代码。图像采集模块参考代码,具体见代码清单 61‑1。

代码清单 61‑1 图像采集模块参考代码(ov5640_data.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
module ov5640_data
(
input wire sys_rst_n , //复位信号
// OV5640
input wire ov5640_pclk , //摄像头像素时钟
input wire ov5640_href , //摄像头行同步信号
input wire ov5640_vsync , //摄像头场同步信号
input wire [ 7:0] ov5640_data , //摄像头图像数据
// 写FIFO
output wire ov5640_wr_en , //图像数据有效使能信号
output wire [15:0] ov5640_data_out //图像数据
);

////
//\* Parameter and Internal Signal \//
////

//parameter define
parameter PIC_WAIT = 4'd10; //图像稳定前等待帧图像个数

//wire define
wire pic_flag ; //帧图像标志信号,每拉高一次,代表一帧完整图像

//reg define
reg ov5640_vsync_dly ; //摄像头输入场同步信号打拍
reg [3:0] cnt_pic ; //图像帧计数器
reg pic_valid ; //帧有效标志信号
reg [7:0] pic_data_reg ; //输入8位图像数据缓存
reg [15:0] data_out_reg ; //输出16位图像数据缓存
reg data_flag ; //输入8位图像数据缓存
reg data_flag_dly1 ; //图像数据拼接标志信号打拍

////
//\* Main Code \//
////

//ov5640_vsync_dly:摄像头输入场同步信号打拍
always@(posedge ov5640_pclk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
ov5640_vsync_dly <= 1'b0;
else
ov5640_vsync_dly <= ov5640_vsync;

//pic_flag:帧图像标志信号,每拉高一次,代表一帧完整图像
assign pic_flag = ((ov5640_vsync_dly == 1'b0)
&& (ov5640_vsync == 1'b1)) ? 1'b1 : 1'b0;

//cnt_pic:图像帧计数器
always@(posedge ov5640_pclk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_pic <= 4'd0;
else if(cnt_pic < PIC_WAIT)
cnt_pic <= cnt_pic + 1'b1;
else
cnt_pic <= cnt_pic;

//pic_valid:真有效标志
always@(posedge ov5640_pclk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
pic_valid <= 1'b0;
else if((cnt_pic == PIC_WAIT) && (pic_flag == 1'b1))
pic_valid <= 1'b1;
else
pic_valid <= pic_valid;

//data_out_reg,pic_data_reg,data_flag:输出16位图像数据缓冲
//输入8位图像数据缓存输入8位,图像数据缓存
always@(posedge ov5640_pclk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
begin
data_out_reg <= 16'd0;
pic_data_reg <= 8'd0;
data_flag <= 1'b0;
end
else if(ov5640_href == 1'b1)
begin
data_flag <= ~data_flag;
pic_data_reg <= ov5640_data;
data_out_reg <= data_out_reg;
if(data_flag == 1'b1)
data_out_reg <= {pic_data_reg,ov5640_data};
else
data_out_reg <= data_out_reg;
end
else
begin
data_flag <= 1'b0;
pic_data_reg <= 8'd0;
data_out_reg <= data_out_reg;
end

//data_flag_dly1:图像数据缓存打拍
always@(posedge ov5640_pclk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
data_flag_dly1 <= 1'b0;
else
data_flag_dly1 <= data_flag;

//ov5640_data_out:输出16位图像数据
assign ov5640_data_out = (pic_valid == 1'b1) ? data_out_reg : 16'b0;

//ov5640_wr_en:输出16位图像数据使能
assign ov5640_wr_en = (pic_valid == 1'b1) ? data_flag_dly1 : 1'b0;

endmodule

11.3.1.2. 寄存器配置模块

要想OV5640摄像头正常工作,需要先对摄像头进行寄存器配置,即向摄像头寄存器写入对应指令。由于需要配置较多寄存器,对于OV5640摄像头具体配置信息,这里不再列举,读者可查阅数据手册或相关资料。对于寄存器的配置方法,我们采用与“WM8978音频回环”章节的“iic配置模块”相同的方法。这里只列出寄 存器配置模块的模块框图和参考代码,对于波形图的绘制,读者可回顾“WM8978音频回环”章节的“i2c配置模块”的相关部分。

模块框图

寄存器配置模块框图,具体见图 61‑10;模块输入输出信号简介,具体见表格 61‑5。

OV5640011

图 61‑10 寄存器配置模块框图

表格 61‑5 寄存器配置模块输入输出信号简介

信号

位宽

类型

功能描述

sys_rst_n

1bit

input

复位信号,低有效

iic_end

1bit

input

一个寄存器配置完成

sys_clk

1bit

input

模块工作时钟

cfg_start

1bit

output

单个寄存器配置触发信号

cfg_data

23bit

output

寄存器地址+数据

cfg_done

1bit

output

寄存器配置完成信号

代码编写

寄存器配置模块参考代码,具体见代码清单 61‑2。

代码清单 61‑2 寄存器配置模块参考代码(ov5640_cfg.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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
module ov5640_cfg
(
input wire sys_clk , //系统时钟,由iic模块传入
input wire sys_rst_n , //系统复位,低有效
input wire cfg_end , //单个寄存器配置完成

output reg cfg_start , //单个寄存器配置触发信号
output wire [23:0] cfg_data , //ID,REG_ADDR,REG_VAL
output reg cfg_done //寄存器配置完成
);

////
//\* Parameter and Internal Signal \//
////

//parameter define
parameter REG_NUM = 8'd251 ; //总共需要配置的寄存器个数
parameter CNT_WAIT_MAX = 15'd20000 ; //寄存器配置等待计数最大值

//wire define
wire [23:0] cfg_data_reg[REG_NUM-1:0] ; //寄存器配置数据暂存

//reg define
reg [14:0] cnt_wait ; //寄存器配置等待计数器
reg [7:0] reg_num ; //配置寄存器个数


////
//\* Main Code \//
////

//cnt_wait:寄存器配置等待计数器
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_wait <= 15'd0;
else if(cnt_wait < CNT_WAIT_MAX)
cnt_wait <= cnt_wait + 1'b1;

//reg_num:配置寄存器个数
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
reg_num <= 8'd0;
else if(cfg_end == 1'b1)
reg_num <= reg_num + 1'b1;

//cfg_start:单个寄存器配置触发信号
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cfg_start <= 1'b0;
else if(cnt_wait == (CNT_WAIT_MAX - 1'b1))
cfg_start <= 1'b1;
else if((cfg_end == 1'b1) && (reg_num < REG_NUM))
cfg_start <= 1'b1;
else
cfg_start <= 1'b0;

//cfg_done:寄存器配置完成
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cfg_done <= 1'b0;
else if((reg_num == REG_NUM) && (cfg_end == 1'b1))
cfg_done <= 1'b1;

//cfg_data:ID,REG_ADDR,REG_VAL
assign cfg_data = (cfg_done == 1'b1) ? 24'b0 : cfg_data_reg[reg_num];

//----------------------------------------------------
//cfg_data_reg:寄存器配置数据暂存 ID REG_ADDR REG_VAL
assign cfg_data_reg[000] = {16'h3103, 8'h11};
assign cfg_data_reg[001] = {16'h3008, 8'h82};
assign cfg_data_reg[002] = {16'h3008, 8'h42};
assign cfg_data_reg[003] = {16'h3103, 8'h03};
assign cfg_data_reg[004] = {16'h3017, 8'hff};
assign cfg_data_reg[005] = {16'h3018, 8'hff};
assign cfg_data_reg[006] = {16'h3034, 8'h1A};
assign cfg_data_reg[007] = {16'h3037, 8'h13};
assign cfg_data_reg[008] = {16'h3108, 8'h01};
assign cfg_data_reg[009] = {16'h3630, 8'h36};

assign cfg_data_reg[010] = {16'h3631, 8'h0e};
assign cfg_data_reg[011] = {16'h3632, 8'he2};
assign cfg_data_reg[012] = {16'h3633, 8'h12};
assign cfg_data_reg[013] = {16'h3621, 8'he0};
assign cfg_data_reg[014] = {16'h3704, 8'ha0};
assign cfg_data_reg[015] = {16'h3703, 8'h5a};
assign cfg_data_reg[016] = {16'h3715, 8'h78};
assign cfg_data_reg[017] = {16'h3717, 8'h01};
assign cfg_data_reg[018] = {16'h370b, 8'h60};
assign cfg_data_reg[019] = {16'h3705, 8'h1a};

assign cfg_data_reg[020] = {16'h3905, 8'h02};
assign cfg_data_reg[021] = {16'h3906, 8'h10};
assign cfg_data_reg[022] = {16'h3901, 8'h0a};
assign cfg_data_reg[023] = {16'h3731, 8'h12};
assign cfg_data_reg[024] = {16'h3600, 8'h08};
assign cfg_data_reg[025] = {16'h3601, 8'h33};
assign cfg_data_reg[026] = {16'h302d, 8'h60};
assign cfg_data_reg[027] = {16'h3620, 8'h52};
assign cfg_data_reg[028] = {16'h371b, 8'h20};
assign cfg_data_reg[029] = {16'h471c, 8'h50};

assign cfg_data_reg[030] = {16'h3a13, 8'h43};
assign cfg_data_reg[031] = {16'h3a18, 8'h00};
assign cfg_data_reg[032] = {16'h3a19, 8'hf8};
assign cfg_data_reg[033] = {16'h3635, 8'h13};
assign cfg_data_reg[034] = {16'h3636, 8'h03};
assign cfg_data_reg[035] = {16'h3634, 8'h40};
assign cfg_data_reg[036] = {16'h3622, 8'h01};
assign cfg_data_reg[037] = {16'h3c01, 8'h34};
assign cfg_data_reg[038] = {16'h3c04, 8'h28};
assign cfg_data_reg[039] = {16'h3c05, 8'h98};

assign cfg_data_reg[040] = {16'h3c06, 8'h00};
assign cfg_data_reg[041] = {16'h3c07, 8'h08};
assign cfg_data_reg[042] = {16'h3c08, 8'h00};
assign cfg_data_reg[043] = {16'h3c09, 8'h1c};
assign cfg_data_reg[044] = {16'h3c0a, 8'h9c};
assign cfg_data_reg[045] = {16'h3c0b, 8'h40};
assign cfg_data_reg[046] = {16'h3810, 8'h00};
assign cfg_data_reg[047] = {16'h3811, 8'h10};
assign cfg_data_reg[048] = {16'h3812, 8'h00};
assign cfg_data_reg[049] = {16'h3708, 8'h64};

assign cfg_data_reg[050] = {16'h4001, 8'h02};
assign cfg_data_reg[051] = {16'h4005, 8'h1a};
assign cfg_data_reg[052] = {16'h3000, 8'h00};
assign cfg_data_reg[053] = {16'h3004, 8'hff};
assign cfg_data_reg[054] = {16'h300e, 8'h58};
assign cfg_data_reg[055] = {16'h302e, 8'h00};
assign cfg_data_reg[056] = {16'h4300, 8'h61};
assign cfg_data_reg[057] = {16'h501f, 8'h01};
assign cfg_data_reg[058] = {16'h440e, 8'h00};
assign cfg_data_reg[059] = {16'h5000, 8'ha7};

assign cfg_data_reg[060] = {16'h3a0f, 8'h30};
assign cfg_data_reg[061] = {16'h3a10, 8'h28};
assign cfg_data_reg[062] = {16'h3a1b, 8'h30};
assign cfg_data_reg[063] = {16'h3a1e, 8'h26};
assign cfg_data_reg[064] = {16'h3a11, 8'h60};
assign cfg_data_reg[065] = {16'h3a1f, 8'h14};
assign cfg_data_reg[066] = {16'h5800, 8'h23};
assign cfg_data_reg[067] = {16'h5801, 8'h14};
assign cfg_data_reg[068] = {16'h5802, 8'h0f};
assign cfg_data_reg[069] = {16'h5803, 8'h0f};

assign cfg_data_reg[070] = {16'h5804, 8'h12};
assign cfg_data_reg[071] = {16'h5805, 8'h26};
assign cfg_data_reg[072] = {16'h5806, 8'h0c};
assign cfg_data_reg[073] = {16'h5807, 8'h08};
assign cfg_data_reg[074] = {16'h5808, 8'h05};
assign cfg_data_reg[075] = {16'h5809, 8'h05};
assign cfg_data_reg[076] = {16'h580a, 8'h08};
assign cfg_data_reg[077] = {16'h580b, 8'h0d};
assign cfg_data_reg[078] = {16'h580c, 8'h08};
assign cfg_data_reg[079] = {16'h580d, 8'h03};

assign cfg_data_reg[080] = {16'h580e, 8'h00};
assign cfg_data_reg[081] = {16'h580f, 8'h00};
assign cfg_data_reg[082] = {16'h5810, 8'h03};
assign cfg_data_reg[083] = {16'h5811, 8'h09};
assign cfg_data_reg[084] = {16'h5812, 8'h07};
assign cfg_data_reg[085] = {16'h5813, 8'h03};
assign cfg_data_reg[086] = {16'h5814, 8'h00};
assign cfg_data_reg[087] = {16'h5815, 8'h01};
assign cfg_data_reg[088] = {16'h5816, 8'h03};
assign cfg_data_reg[089] = {16'h5817, 8'h08};

assign cfg_data_reg[090] = {16'h5818, 8'h0d};
assign cfg_data_reg[091] = {16'h5819, 8'h08};
assign cfg_data_reg[092] = {16'h581a, 8'h05};
assign cfg_data_reg[093] = {16'h581b, 8'h06};
assign cfg_data_reg[094] = {16'h581c, 8'h08};
assign cfg_data_reg[095] = {16'h581d, 8'h0e};
assign cfg_data_reg[096] = {16'h581e, 8'h29};
assign cfg_data_reg[097] = {16'h581f, 8'h17};
assign cfg_data_reg[098] = {16'h5820, 8'h11};
assign cfg_data_reg[099] = {16'h5821, 8'h11};

assign cfg_data_reg[100] = {16'h5822, 8'h15};
assign cfg_data_reg[101] = {16'h5823, 8'h28};
assign cfg_data_reg[102] = {16'h5824, 8'h46};
assign cfg_data_reg[103] = {16'h5825, 8'h26};
assign cfg_data_reg[104] = {16'h5826, 8'h08};
assign cfg_data_reg[105] = {16'h5827, 8'h26};
assign cfg_data_reg[106] = {16'h5828, 8'h64};
assign cfg_data_reg[107] = {16'h5829, 8'h26};
assign cfg_data_reg[108] = {16'h582a, 8'h24};
assign cfg_data_reg[109] = {16'h582b, 8'h22};

assign cfg_data_reg[110] = {16'h582c, 8'h24};
assign cfg_data_reg[111] = {16'h582d, 8'h24};
assign cfg_data_reg[112] = {16'h582e, 8'h06};
assign cfg_data_reg[113] = {16'h582f, 8'h22};
assign cfg_data_reg[114] = {16'h5830, 8'h40};
assign cfg_data_reg[115] = {16'h5831, 8'h42};
assign cfg_data_reg[116] = {16'h5832, 8'h24};
assign cfg_data_reg[117] = {16'h5833, 8'h26};
assign cfg_data_reg[118] = {16'h5834, 8'h24};
assign cfg_data_reg[119] = {16'h5835, 8'h22};

assign cfg_data_reg[120] = {16'h5836, 8'h22};
assign cfg_data_reg[121] = {16'h5837, 8'h26};
assign cfg_data_reg[122] = {16'h5838, 8'h44};
assign cfg_data_reg[123] = {16'h5839, 8'h24};
assign cfg_data_reg[124] = {16'h583a, 8'h26};
assign cfg_data_reg[125] = {16'h583b, 8'h28};
assign cfg_data_reg[126] = {16'h583c, 8'h42};
assign cfg_data_reg[127] = {16'h583d, 8'hce};
assign cfg_data_reg[128] = {16'h5180, 8'hff};
assign cfg_data_reg[129] = {16'h5181, 8'hf2};

assign cfg_data_reg[130] = {16'h5182, 8'h00};
assign cfg_data_reg[131] = {16'h5183, 8'h14};
assign cfg_data_reg[132] = {16'h5184, 8'h25};
assign cfg_data_reg[133] = {16'h5185, 8'h24};
assign cfg_data_reg[134] = {16'h5186, 8'h09};
assign cfg_data_reg[135] = {16'h5187, 8'h09};
assign cfg_data_reg[136] = {16'h5188, 8'h09};
assign cfg_data_reg[137] = {16'h5189, 8'h75};
assign cfg_data_reg[138] = {16'h518a, 8'h54};
assign cfg_data_reg[139] = {16'h518b, 8'he0};

assign cfg_data_reg[140] = {16'h518c, 8'hb2};
assign cfg_data_reg[141] = {16'h518d, 8'h42};
assign cfg_data_reg[142] = {16'h518e, 8'h3d};
assign cfg_data_reg[143] = {16'h518f, 8'h56};
assign cfg_data_reg[144] = {16'h5190, 8'h46};
assign cfg_data_reg[145] = {16'h5191, 8'hf8};
assign cfg_data_reg[146] = {16'h5192, 8'h04};
assign cfg_data_reg[147] = {16'h5193, 8'h70};
assign cfg_data_reg[148] = {16'h5194, 8'hf0};
assign cfg_data_reg[149] = {16'h5195, 8'hf0};

assign cfg_data_reg[150] = {16'h5196, 8'h03};
assign cfg_data_reg[151] = {16'h5197, 8'h01};
assign cfg_data_reg[152] = {16'h5198, 8'h04};
assign cfg_data_reg[153] = {16'h5199, 8'h12};
assign cfg_data_reg[154] = {16'h519a, 8'h04};
assign cfg_data_reg[155] = {16'h519b, 8'h00};
assign cfg_data_reg[156] = {16'h519c, 8'h06};
assign cfg_data_reg[157] = {16'h519d, 8'h82};
assign cfg_data_reg[158] = {16'h519e, 8'h38};
assign cfg_data_reg[159] = {16'h5480, 8'h01};

assign cfg_data_reg[160] = {16'h5481, 8'h08};
assign cfg_data_reg[161] = {16'h5482, 8'h14};
assign cfg_data_reg[162] = {16'h5483, 8'h28};
assign cfg_data_reg[163] = {16'h5484, 8'h51};
assign cfg_data_reg[164] = {16'h5485, 8'h65};
assign cfg_data_reg[165] = {16'h5486, 8'h71};
assign cfg_data_reg[166] = {16'h5487, 8'h7d};
assign cfg_data_reg[167] = {16'h5488, 8'h87};
assign cfg_data_reg[168] = {16'h5489, 8'h91};
assign cfg_data_reg[169] = {16'h548a, 8'h9a};

assign cfg_data_reg[170] = {16'h548b, 8'haa};
assign cfg_data_reg[171] = {16'h548c, 8'hb8};
assign cfg_data_reg[172] = {16'h548d, 8'hcd};
assign cfg_data_reg[173] = {16'h548e, 8'hdd};
assign cfg_data_reg[174] = {16'h548f, 8'hea};
assign cfg_data_reg[175] = {16'h5490, 8'h1d};
assign cfg_data_reg[176] = {16'h5381, 8'h1e};
assign cfg_data_reg[177] = {16'h5382, 8'h5b};
assign cfg_data_reg[178] = {16'h5383, 8'h08};
assign cfg_data_reg[179] = {16'h5384, 8'h0a};

assign cfg_data_reg[180] = {16'h5385, 8'h7e};
assign cfg_data_reg[181] = {16'h5386, 8'h88};
assign cfg_data_reg[182] = {16'h5387, 8'h7c};
assign cfg_data_reg[183] = {16'h5388, 8'h6c};
assign cfg_data_reg[184] = {16'h5389, 8'h10};
assign cfg_data_reg[185] = {16'h538a, 8'h01};
assign cfg_data_reg[186] = {16'h538b, 8'h98};
assign cfg_data_reg[187] = {16'h5580, 8'h06};
assign cfg_data_reg[188] = {16'h5583, 8'h40};
assign cfg_data_reg[189] = {16'h5584, 8'h10};

assign cfg_data_reg[190] = {16'h5589, 8'h10};
assign cfg_data_reg[191] = {16'h558a, 8'h00};
assign cfg_data_reg[192] = {16'h558b, 8'hf8};
assign cfg_data_reg[193] = {16'h501d, 8'h40};
assign cfg_data_reg[194] = {16'h5300, 8'h08};
assign cfg_data_reg[195] = {16'h5301, 8'h30};
assign cfg_data_reg[196] = {16'h5302, 8'h10};
assign cfg_data_reg[197] = {16'h5303, 8'h00};
assign cfg_data_reg[198] = {16'h5304, 8'h08};
assign cfg_data_reg[199] = {16'h5305, 8'h30};

assign cfg_data_reg[200] = {16'h5306, 8'h08};
assign cfg_data_reg[201] = {16'h5307, 8'h16};
assign cfg_data_reg[202] = {16'h5309, 8'h08};
assign cfg_data_reg[203] = {16'h530a, 8'h30};
assign cfg_data_reg[204] = {16'h530b, 8'h04};
assign cfg_data_reg[205] = {16'h530c, 8'h06};
assign cfg_data_reg[206] = {16'h5025, 8'h00};
assign cfg_data_reg[207] = {16'h3008, 8'h02};
assign cfg_data_reg[208] = {16'h3035, 8'h11};
assign cfg_data_reg[209] = {16'h3036, 8'h46};

assign cfg_data_reg[210] = {16'h3c07, 8'h08};
assign cfg_data_reg[211] = {16'h3820, 8'h47};
assign cfg_data_reg[212] = {16'h3821, 8'h00};
assign cfg_data_reg[213] = {16'h3814, 8'h31};
assign cfg_data_reg[214] = {16'h3815, 8'h31};
assign cfg_data_reg[215] = {16'h3800, 8'h00};
assign cfg_data_reg[216] = {16'h3801, 8'h00};
assign cfg_data_reg[217] = {16'h3802, 8'h00};
assign cfg_data_reg[218] = {16'h3803, 8'h04};
assign cfg_data_reg[219] = {16'h3804, 8'h0a};

assign cfg_data_reg[220] = {16'h3805, 8'h3f};
assign cfg_data_reg[221] = {16'h3806, 8'h07};
assign cfg_data_reg[222] = {16'h3807, 8'h9b};
assign cfg_data_reg[223] = {16'h3808, 8'h02};
assign cfg_data_reg[224] = {16'h3809, 8'h80};
assign cfg_data_reg[225] = {16'h380a, 8'h01};
assign cfg_data_reg[226] = {16'h380b, 8'he0};
assign cfg_data_reg[227] = {16'h380c, 8'h07};
assign cfg_data_reg[228] = {16'h380d, 8'h68};
assign cfg_data_reg[229] = {16'h380e, 8'h03};

assign cfg_data_reg[230] = {16'h380f, 8'hd8};
assign cfg_data_reg[231] = {16'h3813, 8'h06};
assign cfg_data_reg[232] = {16'h3618, 8'h00};
assign cfg_data_reg[233] = {16'h3612, 8'h29};
assign cfg_data_reg[234] = {16'h3709, 8'h52};
assign cfg_data_reg[235] = {16'h370c, 8'h03};
assign cfg_data_reg[236] = {16'h3a02, 8'h17};
assign cfg_data_reg[237] = {16'h3a03, 8'h10};
assign cfg_data_reg[238] = {16'h3a14, 8'h17};
assign cfg_data_reg[239] = {16'h3a15, 8'h10};

assign cfg_data_reg[240] = {16'h4004, 8'h02};
assign cfg_data_reg[241] = {16'h3002, 8'h1c};
assign cfg_data_reg[242] = {16'h3006, 8'hc3};
assign cfg_data_reg[243] = {16'h4713, 8'h03};
assign cfg_data_reg[244] = {16'h4407, 8'h04};
assign cfg_data_reg[245] = {16'h460b, 8'h35};
assign cfg_data_reg[246] = {16'h460c, 8'h22};
assign cfg_data_reg[247] = {16'h4837, 8'h22};
assign cfg_data_reg[248] = {16'h3824, 8'h02};
assign cfg_data_reg[249] = {16'h5001, 8'ha3};

assign cfg_data_reg[250] = {16'h3503, 8'h00};

//-------------------------------------------------------

endmodule

11.3.1.3. 顶层模块

顶层模块部分只列出参考代码,不再进行模块框图讲解和波形图的绘制,参考代码具体见代码清单 61‑3。

代码清单 61‑3 顶层模块参考代码(ov5640_vga_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
module ov5640_vga_640x480
(
input wire sys_clk , //系统时钟
input wire sys_rst_n , //系统复位,低电平有效
//摄像头接口
input wire ov5640_pclk , //摄像头数据像素时钟
input wire ov5640_vsync, //摄像头场同步信号
input wire ov5640_href , //摄像头行同步信号
input wire [7:0] ov5640_data , //摄像头数据
output wire ov5640_rst_n, //摄像头复位信号,低电平有效
output wire ov5640_pwdn , //摄像头时钟选择信号, 1:使用摄像头自带的晶振
output wire sccb_scl , //摄像头SCCB_SCL线
inout wire sccb_sda , //摄像头SCCB_SDA线
//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_ba , //SDRAM Bank地址
output wire [1:0] sdram_dqm , //SDRAM 数据掩码
output wire [12:0] sdram_addr , //SDRAM 地址
inout wire [15:0] sdram_dq , //SDRAM 数据
//VGA接口
output wire vga_hs , //行同步信号
output wire vga_vs , //场同步信号
output wire [15:0] vga_rgb //红绿蓝三原色输出
);

////
//\* Parameter and Internal Signal \//
////

//parameter define
parameter H_PIXEL = 24'd640 ; //水平方向像素个数,用于设置SDRAM缓存大小
parameter V_PIXEL = 24'd480 ; //垂直方向像素个数,用于设置SDRAM缓存大小

//wire define
wire clk_100m ; //100MHz时钟,SDRAM操作时钟
wire clk_100m_shift ; //100MHz时钟,SDRAM相位偏移时钟
wire clk_25m ; //25MHz时钟,提供给vga驱动时钟
wire locked ; //PLL锁定信号
wire rst_n ; //复位信号(sys_rst_n & locked)
wire cfg_done ; //摄像头初始化完成
wire wr_en ; //sdram写使能
wire [15:0] wr_data ; //sdram写数据
wire rd_en ; //sdram读使能
wire [15:0] rd_data ; //sdram读数据
wire sdram_init_done ; //SDRAM初始化完成
wire sys_init_done ; //系统初始化完成(SDRAM初始化+摄像头初始化)

////
//\* Main Code \//
////

//rst_n:复位信号(sys_rst_n & locked)
assign rst_n = sys_rst_n & locked;

//sys_init_done:系统初始化完成(SDRAM初始化+摄像头初始化)
assign sys_init_done = sdram_init_done & cfg_done;

//ov5640_rst_n:摄像头复位,固定高电平
assign ov5640_rst_n = 1'b1;

//ov5640_pwdn
assign ov5640_pwdn = 1'b0;

//------------- clk_gen_inst -------------
clk_gen clk_gen_inst(

.areset (~sys_rst_n ),
.inclk0 (sys_clk ),
.c0 (clk_100m ),
.c1 (clk_100m_shift ),
.c2 (clk_25m ),
.locked (locked )

);

//------------- ov5640_top_inst -------------
ov5640_top ov5640_top_inst(

.sys_clk (clk_25m ), //系统时钟
.sys_rst_n (rst_n ), //复位信号
.sys_init_done (sys_init_done ), //系统初始化完成(SDRAM + 摄像头)

.ov5640_pclk (ov5640_pclk ), //摄像头像素时钟
.ov5640_href (ov5640_href ), //摄像头行同步信号
.ov5640_vsync (ov5640_vsync ), //摄像头场同步信号
.ov5640_data (ov5640_data ), //摄像头图像数据

.cfg_done (cfg_done ), //寄存器配置完成
.sccb_scl (sccb_scl ), //SCL
.sccb_sda (sccb_sda ), //SDA
.ov5640_wr_en (wr_en ), //图像数据有效使能信号
.ov5640_data_out (wr_data ) //图像数据

);

//------------- sdram_top_inst -------------
sdram_top sdram_top_inst(

.sys_clk (clk_100m ), //sdram 控制器参考时钟
.clk_out (clk_100m_shift ), //用于输出的相位偏移时钟
.sys_rst_n (rst_n ), //系统复位
//用户写端口
.wr_fifo_wr_clk (ov5640_pclk ), //写端口FIFO: 写时钟
.wr_fifo_wr_req (wr_en ), //写端口FIFO: 写使能
.wr_fifo_wr_data (wr_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 (~rst_n ), //写端口复位: 复位写地址,清空写FIFO
//用户读端口
.rd_fifo_rd_clk (clk_25m ), //读端口FIFO: 读时钟
.rd_fifo_rd_req (rd_en ), //读端口FIFO: 读使能
.rd_fifo_rd_data (rd_data ), //读端口FIFO: 读数据
.sdram_rd_b_addr (24'd0 ), //读SDRAM的起始地址
.sdram_rd_e_addr (H_PIXEL*V_PIXEL), //读SDRAM的结束地址
.rd_burst_len (10'd512 ), //从SDRAM中读数据时的突发长度
.rd_rst (~rst_n ), //读端口复位: 复位读地址,清空读FIFO
//用户控制端口
.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_25m ), //输入工作时钟,频率25MHz
.sys_rst_n (rst_n ), //输入复位信号,低电平有效
.pix_data (rd_data ), //待显示数据输入

.pix_data_req (rd_en ), //数据请求信号
.hsync (vga_hs ), //输出行同步信号
.vsync (vga_vs ), //输出场同步信号
.rgb (vga_rgb ) //输出像素信息
);

endmodule

11.3.1.4. RTL视图

至此实验工程基本完成,在Quartus中对代码进行编译,编译若有错误,请读者根据错误提示信息作出更改,直至编译通过,编译通过后查看RTL视图,与顶层模块框图对比,两者一致,各信号连接正确。RTL视图,具体见图 61‑11。

OV5640012

图 61‑11 RTL视图

11.4. 上板调试

11.4.1. 引脚约束

仿真验证通过后,准备上板验证,上板验证之前先要进行引脚约束。工程中各输入输出信号与开发板引脚对应关系如表格 61‑6所示。

表格 61‑6 引脚分配表

信号名

信号类型

对应引脚

备注

sys_clk

Input

E1

时钟

sys_rst_n

Input

M15

复位

ov5640_data[7]

Input

L13

OV5640摄像头采集图像数据

ov5640_ data[6]

Input

F13

OV5640摄像头采集图像数据

ov5640_ data[5]

Input

B16

OV5640摄像头采集图像数据

ov5640_ data[4]

Input

C15

OV5640摄像头采集图像数据

ov5640_ data[3]

Input

D16

OV5640摄像头采集图像数据

ov5640_ data[2]

Input

F14

OV5640摄像头采集图像数据

ov5640_ data[1]

Input

F15

OV5640摄像头采集图像数据

ov5640_ data[0]

Input

G15

OV5640摄像头采集图像数据

ov5640_href

Input

J13

摄像头行同步信号

ov5640_vsync

Input

C16

摄像头场同步信号

ov5640_pclk

Input

M16

摄像头数据像素时钟

ov5640_pwdn

Output

G11

摄像头时钟选择信号

ov5640_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数据总线

vga_hs

Output

C2

行同步信号

vga_vs

Output

D1

场同步信号

vga_rgb[15]

Output

A5

RGB色彩信息(红)

vga_rgb[14]

Output

E6

RGB色彩信息(红)

vga_rgb[13]

Output

E7

RGB色彩信息(红)

vga_rgb[12]

Output

B8

RGB色彩信息(红)

vga_rgb[11]

Output

A8

RGB色彩信息(红)

vga_rgb[10]

Output

F8

RGB色彩信息(绿)

vga_rgb[9]

Output

E8

RGB色彩信息(绿)

vga_rgb[8]

Output

B7

RGB色彩信息(绿)

vga_rgb[7]

Output

A7

RGB色彩信息(绿)

vga_rgb[6]

Output

F7

RGB色彩信息(绿)

vga_rgb[5]

Output

F6

RGB色彩信息(绿)

vga_rgb[4]

Output

B6

RGB色彩信息(蓝)

vga_rgb[3]

Output

A6

RGB色彩信息(蓝)

vga_rgb[2]

Output

B5

RGB色彩信息(蓝)

vga_rgb[1]

Output

A2

RGB色彩信息(蓝)

vga_rgb[0]

Output

B4

RGB色彩信息(蓝)

下面进行管脚分配,管脚的分配方法在前面章节已有所讲解,在此就不再过多叙述,管脚的分配如下图 61‑12、图 61‑13所示。

OV5640013

图 61‑12 管脚分配

OV5640014

图 61‑13 管脚分配

11.4.1.1. 结果验证

如图 61‑14所示,开发板连接12V直流电源、USB-Blaster下载器JTAG端口、VGA显示器和OV5640摄像头。线路正确连接后,打开开关为板卡上电。

OV5640015

图 61‑14 程序下载连线图

如图 61‑15所示,使用“Programmer”为开发板下载程序。

OV5640016

图 61‑15 程序下载图

程序下载完成后,VGA显示屏上会显示出OV5640摄像头采集到的图像,分辨率为640*480,如图 61‑16所示。

OV5640017 OV5640018

图 61‑16 OV5640+VGA图像显示

11.5. 章末总结

本章节详细介绍了OV5640摄像头的相关知识,并将OV5640摄像头与VGA相结合,实现了OV5640采集图像的实时显示,OV5640相比OV7725功能更加强大,读者可查阅数据手册深入学习。

11.6. 拓展训练

查阅OV5640摄像头数据手册,了解相关寄存器在不同配置下的功能,更改寄存器配置,实现采集图像的上下翻转、左右镜像等功能,在VGA 显示器上实时显示。