毕设之ov7670多点采集进度1-vga
快要临近毕业了,所以现在要开始为毕设而努力,我的课题是基于ov7725摄像头多点采集。大学的最后几个月了,所以想写点东西记录下我的毕设过程,留个纪念,小弟我第一次写博文,并且语文水平烂的可以,请见谅。在视频图像qq群中认识了很多牛人,感谢bingo的分享(视频图像处理之ov7670开发档案),我决定拿ov7670来熟悉下图像采集的知识。Fpga的板子是从老师那拿来的。
因为对摄像头不怎么了解,所以先从我熟悉的VGA开始:
上学期学过点VHDL,也在vga上显示过数字钟。于是想尝试用verilog编写下,总之代码写的一塌糊涂,当看到彬哥的VGA模块之后,让我思路一下清晰了很多,真佩服他,怎么能写的这么好,哎,我好差劲。下面为彬哥写的vga代码:
详细介绍见彬哥的博文:http://www.cnblogs.com/crazybingo/archive/2011/07/28/2119948.html
我只写点我学到的东西,呵呵。
module vga_driver
#(
//VGA_800_640_60FPS_25MHz
//Horizontal Parameter(pixel)
parameter H_DISP = 10\’d640,
parameter H_FRONT = 10\’d16,
parameter H_SYNC = 10\’d96,
parameter H_BACK = 10\’d48,
parameter H_TOTAL = 10\’d800,
//Virtical Parameter(line)
parameter V_DISP = 10\’d480,
parameter V_FRONT = 10\’d10,
parameter V_SYNC = 10\’d2,
parameter V_BACK = 10\’d33,
parameter V_TOTAL = 10\’d525
)
(
inputclk_vga,// VGA像素时钟
inputrst_n, // 异步复位信号
input[15:0]vga_data,
output[15:0]vga_rgb,// 接收要显示的色彩
outputregvga_hs,// VGA管脚 行同步
outputregvga_vs,// VGA管脚 场同步
output[9:0]vga_xpos,// 像素横坐标位置
output[9:0]vga_ypos// 像素纵坐标位置
);
首先当看到上面的模块定义之后,我百思不得其解,我看到大多数verilog代码模块里面只进行了端口定义,#()又是什么东西?当看了彬哥的介绍之后,原来verilog语法也能够像单片机那样,有define的用法,通过修改注释define便可以轻松修改全局。具体如下所示:
//vga parameter define
`defineVGA_640_480_60FPS_25MHz
//`defineVGA_800_600_72FPS_50MHz
//`defineVGA_1024_768_60FPS_65MHz
`ifdefVGA_640_480_60FPS_25MHz
parameterDUTY_CYCLE=50;
parameterDIVIDE_DATA=2;//pll clk_c0分频参数定义
parameterMULTIPLY_DATA=1;
parameter DIVIDE_DATA1 = 25;//pll clk_c1分频参数定义
parameter MULTIPLY_DATA1 = 14;
parameter DIVIDE_DATA2 = 2500;//pll clk_c2分频参数定义
parameter MULTIPLY_DATA2 = 1;
parameterH_DISP=11\’d640;
parameterH_FRONT=11\’d16;
parameterH_SYNC =11\’d96;
parameterH_BACK =11\’d48;
parameterH_TOTAL=11\’d800;
parameterV_DISP =10\’d480;
parameterV_FRONT=10\’d10;
parameterV_SYNC =10\’d2;
parameterV_BACK =10\’d33;
parameterV_TOTAL=10\’d525;
`endif
`ifdef VGA_800_600_72FPS_50MHz
parameterDUTY_CYCLE=50;
parameterDIVIDE_DATA=1;
parameterMULTIPLY_DATA=1;
parameterH_DISP =11\’d800;
parameterH_FRONT=11\’d56;
parameterH_SYNC =11\’d120;
parameterH_BACK =11\’d64;
parameterH_TOTAL=11\’d1040;
parameterV_DISP =10\’d600;
parameterV_FRONT=10\’d37;
parameterV_SYNC =10\’d6;
parameterV_BACK =10\’d23;
parameterV_TOTAL=10\’d666;
`endif
`ifdefVGA_1024_768_60FPS_65MHz
parameterDUTY_CYCLE=50;
parameterDIVIDE_DATA=10;
parameterMULTIPLY_DATA=13;
parameterH_DISP =11\’d1024;
parameterH_FRONT=11\’d24;
parameterH_SYNC =11\’d136;
parameterH_BACK =11\’d160;
parameterH_TOTAL=11\’d1344;
parameterV_DISP =10\’d768;
parameterV_FRONT=10\’d3;
parameterV_SYNC =10\’d6;
parameterV_BACK =10\’d29;
parameterV_TOTAL=10\’d806;
`endif
并且通过顶层文件来实例化O.O
vga_driver
#
(
.H_DISP (H_DISP),
.H_FRONT(H_FRONT),
.H_SYNC (H_SYNC),
.H_BACK (H_BACK),
.H_TOTAL(H_TOTAL),
.V_DISP (V_DISP),
.V_FRONT(V_FRONT),
.V_SYNC (V_SYNC),
.V_BACK (V_BACK),
.V_TOTAL(V_TOTAL)
)
vga_driver_inst
(
.clk_vga(clk_vga),
.rst_n (sys_rst_n),
.vga_data(vga_data),
.vga_rgb(vga_rgb),
.vga_hs(vga_hs),
.vga_vs(vga_vs),
.vga_xpos(vga_xpos),
.vga_ypos(vga_ypos)
);
当然也能够修改pll参数的值,就能够得到你想要的时钟频率。
VGA控制模块:
module vga_driver
#(
//VGA_800_640_60FPS_25MHz
//Horizontal Parameter(pixel)
parameter H_DISP = 10\’d640,
parameter H_FRONT = 10\’d16,
parameter H_SYNC = 10\’d96,
parameter H_BACK = 10\’d48,
parameter H_TOTAL = 10\’d800,
//Virtical Parameter(line)
parameter V_DISP = 10\’d480,
parameter V_FRONT = 10\’d10,
parameter V_SYNC = 10\’d2,
parameter V_BACK = 10\’d33,
parameter V_TOTAL = 10\’d525
)
(
inputclk_vga,// VGA像素时钟
inputrst_n, // 异步复位信号
input[15:0]vga_data,
output[15:0]vga_rgb,// 接收要显示的色彩
outputregvga_hs,// VGA管脚 行同步
outputregvga_vs,// VGA管脚 场同步
output[9:0]vga_xpos,// 像素横坐标位置
output[9:0]vga_ypos// 像素纵坐标位置
);
//行同步信号设计
reg [9:0] hcnt;
always @(posedge clk_vga or negedge rst_n)
begin
if(!rst_n)
hcnt <= 0;
else
begin
if(hcnt < H_TOTAL-1\’b1)
hcnt <= hcnt + 1\’b1;
else
hcnt <= 0;
end
end
//—————–
always@(posedge clk_vga or negedge rst_n)
begin
if(!rst_n)
vga_hs <= 1;
else
begin
if((hcnt >= H_DISP+H_FRONT-1\’b1)&&(hcnt < H_DISP+H_FRONT+H_SYNC-1))
vga_hs <= 0;
else
vga_hs <= 1;
end
end
//场同步信号设计
reg [9:0] vcnt;
always @(posedge clk_vga or negedge rst_n)
begin
if(!rst_n)
vcnt <= 0;
else
begin
if(hcnt == H_DISP-1\’b1)
begin
if(vcnt < V_TOTAL-1\’b1)
vcnt <= vcnt + 1\’b1;
else
vcnt <= 0;
end
else
vcnt <= vcnt;
end
end
//—————–
always @(posedge clk_vga or negedge rst_n)
begin
if(!rst_n)
vga_vs <= 1;
else
begin
if((vcnt >= V_DISP+V_FRONT-1\’b1)&&(vcnt < V_DISP+V_FRONT+V_SYNC-1\’b1))
vga_vs <= 0;
else
vga_vs <= 1;
end
end
//——————————
assign vga_xpos = (hcnt < H_DISP)?hcnt[9:0]+1\’b1:10\’d0;
assign vga_ypos = (vcnt < V_DISP)?vcnt[9:0]+1\’b1:10\’d0;
assign vga_rgb = ((hcnt < H_DISP)&&(vcnt < V_DISP))?vga_data:16\’d0;
endmodule
VGA显示模块:
module vga_display
#(
parameterH_DISP =10\’d640,
parameterV_DISP =10\’d480
)
(
inputclk,
input rst_n,
input[9:0]vga_xpos,
input [9:0] vga_ypos,
input [15:0] cmos_odata,
output reg[15:0] vga_data
);
//define colors RGB–5|6|5
localparam RED = 16\’hF800;
localparam GREEN = 16\’h07E0;
localparam BLUE = 16\’h001F;
localparam WHITE = 16\’hFFFF;
localparam BLACK = 16\’h0000;
localparam YELLOW = 16\’hFFE0;
localparam CYAN = 16\’hF81F;
localparam ROYAL = 16\’h07FF;
//————————————————————————-
//你可以自己定义一个你想要的图案哈。
//`defineVGA_CAITIAO_3
//`define VGA_CAITIAO_8
//`define VGA_XUANCAI
`define VGA_OV7670
//————————-
//固定区域输出数据
//OV7670
`ifdef VGA_OV7670
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
vga_data <= 16\’h0;
else
begin
vga_data <= cmos_odata;
end
end
`endif
//红绿蓝3彩条
`ifdef VGA_CAITIAO_3
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
vga_data <= 16\’h0;
else
begin
if(vga_xpos >= 0 && vga_xpos<(H_DISP/3))
vga_data <= RED;
else if(vga_xpos >= (H_DISP/3)*1&&vga_xpos < (H_DISP/3)*2)
vga_data <= GREEN;
else
vga_data <= BLUE;
end
end
`endif
//8彩条
`ifdef VGA_CAITIAO_8
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
vga_data <= 16\’h0;
else
begin
if (vga_xpos >= 0 && vga_xpos < (H_DISP>>3))
vga_data <= RED;
else if(vga_xpos >= (H_DISP>>3)*1 && vga_xpos < (H_DISP>>3)*2)
vga_data <= GREEN;
else if(vga_xpos >= (H_DISP>>3)*2 && vga_xpos < (H_DISP>>3)*3)
vga_data <= BLUE;
else if(vga_xpos >= (H_DISP>>3)*3 && vga_xpos < (H_DISP>>3)*4)
vga_data <= WHITE;
else if(vga_xpos >= (H_DISP>>3)*4 && vga_xpos < (H_DISP>>3)*5)
vga_data <= BLACK;
else if(vga_xpos >= (H_DISP>>3)*5 && vga_xpos < (H_DISP>>3)*6)
vga_data <= YELLOW;
else if(vga_xpos >= (H_DISP>>3)*6 && vga_xpos < (H_DISP>>3)*7)
vga_data <= CYAN;
else// if(vga_xpos >= (H_DISP<<3)*7 && vga_xpos < (H_DISP<<3)*8)
vga_data <= ROYAL;
end
end
`endif
//很炫的图案
`ifdef VGA_XUANCAI
wire [19:0] vga_result = vga_xpos * vga_ypos;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
vga_data <= 16\’h0;
else
vga_data = vga_result[15:0];
end
`endif
Endmodule
VGA顶层文件
module vga_top
(
//clock and reset
input clk,
input rst_n,
//vga interface
output vga_adv_clk,
output vga_blank_n,
output vga_sync_n,
output vga_hs,
output vga_vs,
output [15:0] vga_rgb
);
assign vga_adv_clk = ~clk_vga;
assign vga_blank_n = 1\’b1;
assign vga_sync_n = 1\’b0;
//———————————-
//vga parameter define
`defineVGA_640_480_60FPS_25MHz
//`defineVGA_800_600_72FPS_50MHz
//`defineVGA_1024_768_60FPS_65MHz
`ifdefVGA_640_480_60FPS_25MHz
parameterDUTY_CYCLE=50;
parameterDIVIDE_DATA=2;
parameterMULTIPLY_DATA=1;
parameterH_DISP=11\’d640;
parameterH_FRONT=11\’d16;
parameterH_SYNC =11\’d96;
parameterH_BACK =11\’d48;
parameterH_TOTAL=11\’d800;
parameterV_DISP =10\’d480;
parameterV_FRONT=10\’d10;
parameterV_SYNC =10\’d2;
parameterV_BACK =10\’d33;
parameterV_TOTAL=10\’d525;
`endif
`ifdef VGA_800_600_72FPS_50MHz
parameterDUTY_CYCLE=50;
parameterDIVIDE_DATA=1;
parameterMULTIPLY_DATA=1;
parameterH_DISP =11\’d800;
parameterH_FRONT=11\’d56;
parameterH_SYNC =11\’d120;
parameterH_BACK =11\’d64;
parameterH_TOTAL=11\’d1040;
parameterV_DISP =10\’d600;
parameterV_FRONT=10\’d37;
parameterV_SYNC =10\’d6;
parameterV_BACK =10\’d23;
parameterV_TOTAL=10\’d666;
`endif
`ifdefVGA_1024_768_60FPS_65MHz
parameterDUTY_CYCLE=50;
parameterDIVIDE_DATA=10;
parameterMULTIPLY_DATA=13;
parameterH_DISP =11\’d1024;
parameterH_FRONT=11\’d24;
parameterH_SYNC =11\’d136;
parameterH_BACK =11\’d160;
parameterH_TOTAL=11\’d1344;
parameterV_DISP =10\’d768;
parameterV_FRONT=10\’d3;
parameterV_SYNC =10\’d6;
parameterV_BACK =10\’d29;
parameterV_TOTAL=10\’d806;
`endif
//——————
//system control instantiation
wire clk_vga;
wire sys_rst_n;
system_ctrl
#(
.DUTY_CYCLE(DUTY_CYCLE),
.DIVIDE_DATA(DIVIDE_DATA),
.MULTIPLY_DATA (MULTIPLY_DATA)
)
system_ctrl_inst
(
.clk(clk),
.rst_n(rst_n),
.clk_c0(clk_vga),
.sys_rst_n(sys_rst_n)
);
//——————-
//vga display instantiation
wire[9:0]vga_xpos;
wire[9:0]vga_ypos;
wire[15:0] vga_data;
vga_display
#(
.H_DISP(H_DISP),
.V_DISP(V_DISP)
)
vga_display_inst
(
.clk(clk_vga),
.rst_n(sys_rst_n),
.vga_xpos(vga_xpos),
.vga_ypos(vga_ypos),
.vga_data(vga_data)
);
//—————-
//vga driver instantiation
vga_driver
#
(
.H_DISP (H_DISP),
.H_FRONT(H_FRONT),
.H_SYNC (H_SYNC),
.H_BACK (H_BACK),
.H_TOTAL(H_TOTAL),
.V_DISP (V_DISP),
.V_FRONT(V_FRONT),
.V_SYNC (V_SYNC),
.V_BACK (V_BACK),
.V_TOTAL(V_TOTAL)
)
vga_driver_inst
(
.clk_vga(clk_vga),
.rst_n (sys_rst_n),
.vga_data(vga_data),
.vga_rgb(vga_rgb),
.vga_hs(vga_hs),
.vga_vs(vga_vs),
.vga_xpos(vga_xpos),
.vga_ypos(vga_ypos)
);
endmodule
这些代码都是彬哥的,哎,我是编不出这么好的东西的。