基于 ZYNQ 的双目视觉图像采集系统设计(五)

LCD 控制器设计:
        LCD 显示控制部分,用 x_cnt 和 y_cnt 两个计数器,产生一个二维的虚拟图像域。在这个虚拟图像域的某个特定区域(分辨率)内,是图像显示的有效区域。

	//x and y counter
reg[11:0] xcnt;
reg[11:0] ycnt;
	
always @(posedge clk or negedge rst_n)
	if(!rst_n) xcnt <= 12'd0;
	else if(xcnt >= VGA_HTT) xcnt <= 12'd0;
	else xcnt <= xcnt+1'b1;

always @(posedge clk or negedge rst_n)
	if(!rst_n) ycnt <= 12'd0;
	else if(xcnt == VGA_HTT) begin
		if(ycnt >= VGA_VTT) ycnt <= 12'd0;
		else ycnt <= ycnt+1'b1;
	end
	else ;

VGA 显示芯片需要有场同步(vag_vsy)和行同步信号(vga_hsy)。

	//hsy and vsy generate	
always @(posedge clk or negedge rst_n)
	if(!rst_n) vga_hsy <= 1'b0;
	else if(xcnt < VGA_HST) vga_hsy <= 1'b1;
	else vga_hsy <= 1'b0;
	
always @(posedge clk or negedge rst_n)
	if(!rst_n) vga_vsy <= 1'b0;
	else if(ycnt < VGA_VST) vga_vsy <= 1'b1;
	else vga_vsy <= 1'b0;	

有效显示区域是在 xcnt 和 ycnt 处于某个取值范围内,其产生逻辑代码如下。

	//vga valid signal generate
reg vga_valid;

always @(posedge clk or negedge rst_n)
	if(!rst_n) vga_valid <= 1'b0;
	else if((xcnt >= (VGA_HST+VGA_HBP)) && (xcnt < (VGA_HST+VGA_HBP+VGA_HVT))
				&& (ycnt >= (VGA_VST+VGA_VBP)) && (ycnt < (VGA_VST+VGA_VBP+VGA_VVT)))
		 vga_valid <= 1'b1;
	else vga_valid <= 1'b0;

assign adv7123_blank_n = vga_valid;
assign adv7123_sync_n = 1'b0;

       实际有效显示区域的图像数据从 DDR3 中读取,对应的图像就是 OV5640 采集到的 VGA图像。控制接口上,这个模块输出 lcd_rfclr 信号作为每个图像帧的同步信号,或者称之为复位信号,在每个有效显示图像开始前,这个信号都会拉高一段时间,axi_hp0_rd.v 模块可以用这个信号实现 FIFO 的复位,以及对应的控制信号的复位。读数据请求信号 lcd_rfreq1 和lcd_rfreq2 会产生连续的 640*480 个时钟周期的高电平,用于读取 DDR3 中缓存的两个摄像头的图像数据。16 位数据总线 lcd_rfdb1 和 lcd_rfdb2 则分别在每个读数据请求信号 lcd_rfreq1和 lcd_rfreq2 拉高后有效,对应数据送到显示器进行显示。lcd_rfreq1 和 lcd_rfreq2 信号的拉高则分别在液晶屏的左边半屏和右边半屏。

	//FIFO读请求信号和复位信号产生

always @(posedge clk or negedge rst_n)
	if(!rst_n) lcd_rfreq1 <= 1'b0;
	else if((xcnt >= (VGA_HST+VGA_HBP-2)) && (xcnt < (VGA_HST+VGA_HBP+640-2))
				&& (ycnt >= (VGA_VST+VGA_VBP+120)) && (ycnt < (VGA_VST+VGA_VBP+VGA_VVT-120)))
		 lcd_rfreq1 <= 1'b1;
	else lcd_rfreq1 <= 1'b0;
	
always @(posedge clk or negedge rst_n)
	if(!rst_n) lcd_rfreq2 <= 1'b0;
	else if((xcnt >= (VGA_HST+VGA_HBP+640-2)) && (xcnt < (VGA_HST+VGA_HBP+VGA_HVT-2))
				&& (ycnt >= (VGA_VST+VGA_VBP+120)) && (ycnt < (VGA_VST+VGA_VBP+VGA_VVT-120)))
		 lcd_rfreq2 <= 1'b1;
	else lcd_rfreq2 <= 1'b0;	

always @(posedge clk or negedge rst_n)
	if(!rst_n) lcd_rfclr <= 1'b1;
	else if(ycnt == 12'd0) lcd_rfclr <= 1'b1;
	else lcd_rfclr <= 1'b0;

       从 DDR3 中读取的有效数据,赋值给数据总线 vga_r、vga_g 和 vga_b,通过 VGA 驱动芯片转化为模拟电压值,最终送给显示器。

	//display corlor generate
reg[4:0] vga_rdb;
reg[5:0] vga_gdb;
reg[4:0] vga_bdb;

reg[15:0] lcd_db_rgb;	// LCD色彩显示寄存器

always @ (posedge clk or negedge rst_n)
	if(!rst_n) {vga_rdb,vga_gdb,vga_bdb} <= 16'd0;
	else if((ycnt >= (VGA_VST+VGA_VBP+120)) && (ycnt < (VGA_VST+VGA_VBP+VGA_VVT-120))) begin
		if((xcnt >= (VGA_HST+VGA_HBP-1)) && (xcnt < (VGA_HST+VGA_HBP+640-1))) {vga_rdb,vga_gdb,vga_bdb} <= lcd_rfdb1;
		else if((xcnt >= (VGA_HST+VGA_HBP+640-1)) && (xcnt < (VGA_HST+VGA_HBP+VGA_HVT-1))) {vga_rdb,vga_gdb,vga_bdb} <= lcd_rfdb2;
		else {vga_rdb,vga_gdb,vga_bdb} <= 16'd0;
	end
	else {vga_rdb,vga_gdb,vga_bdb} <= 16'd0;

//-----------------------------------------------------------
	//corlor data and clock generate
assign vga_r = vga_valid ? vga_rdb:5'd0;
assign vga_g = vga_valid ? vga_gdb:6'd0;	
assign vga_b = vga_valid ? vga_bdb:5'd0;	
     2 OV5640 摄像头模块通过 Zstar ISB 底板与 Zstar Zynq 开发板连接, VGA 也是通过 Zstar
ISB 底板与 Zstar Zynq 开发板连接, VGA 板同时需要连接到 VGA 显示器。连接如图所示。
检测结果:
lcd_driver.v
module lcd_driver(	
				//系统时钟与复位信号
			input clk_25m,
			input clk_50m,
			input clk_65m,
			input clk_75m,
			input clk_108m,
			input clk_130m,
			input rst_n,
				//VGA驱动接口
			output[4:0] vga_r,
			output[5:0] vga_g,
			output[4:0] vga_b,
			output[2:0] vga_rgb,
			output reg vga_hsy,vga_vsy,
			output vga_clk,
			output adv7123_blank_n,
			output adv7123_sync_n,
				//LCD与FIFO的接口
			output lcd_synclk,	
			input[15:0] lcd_rfdb1,	//FIFO读出数据总线
			input[15:0] lcd_rfdb2,	//FIFO读出数据总线
			output reg lcd_rfreq1,		//FIFO读请求信号
			output reg lcd_rfreq2,		//FIFO读请求信号
			output reg lcd_rfclr		//FIFO复位信号,高电平有效
			);


//-----------------------------------------------------------
wire clk;
assign vga_clk = ~clk;
assign lcd_synclk = clk;
assign vga_rgb = 3'b000;

//-----------------------------------------------------------
//`define VGA_640_480
//`define VGA_800_600
//`define VGA_1024_768
`define VGA_1280_720
//`define VGA_1280_960
//`define VGA_1280_1024
//`define VGA_1920_1080

//-----------------------------------------------------------
`ifdef VGA_640_480
	//VGA Timing 640*480 & 25MHz & 60Hz
	assign clk = clk_25m;
		
	parameter VGA_HTT = 12'd800-12'd1;	//Hor Total Time
	parameter VGA_HST = 12'd96;		//Hor Sync  Time
	parameter VGA_HBP = 12'd48;//+12'd16;		//Hor Back Porch
	parameter VGA_HVT = 12'd640;	//Hor Valid Time
	parameter VGA_HFP = 12'd16;		//Hor Front Porch

	parameter VGA_VTT = 12'd525-12'd1;	//Ver Total Time
	parameter VGA_VST = 12'd2;		//Ver Sync Time
	parameter VGA_VBP = 12'd33;//-12'd4;		//Ver Back Porch
	parameter VGA_VVT = 12'd480;	//Ver Valid Time
	parameter VGA_VFP = 12'd10;		//Ver Front Porch
`endif

`ifdef VGA_800_600
	//VGA Timing 800*600 & 50MHz & 72Hz
	assign clk = clk_50m;

	parameter VGA_HTT = 12'd1040-12'd1;	//Hor Total Time
	parameter VGA_HST = 12'd120;		//Hor Sync  Time
	parameter VGA_HBP = 12'd64;		//Hor Back Porch
	parameter VGA_HVT = 12'd800;	//Hor Valid Time
	parameter VGA_HFP = 12'd56;		//Hor Front Porch

	parameter VGA_VTT = 12'd666-12'd1;	//Ver Total Time
	parameter VGA_VST = 12'd6;		//Ver Sync Time
	parameter VGA_VBP = 12'd23;		//Ver Back Porch
	parameter VGA_VVT = 12'd600;	//Ver Valid Time
	parameter VGA_VFP = 12'd37;		//Ver Front Porch
`endif

`ifdef VGA_1024_768
	//VGA Timing 1024*768 & 65MHz & 60Hz
	assign clk = clk_65m;

	parameter VGA_HTT = 12'd1344-12'd1;	//Hor Total Time
	parameter VGA_HST = 12'd136;		//Hor Sync  Time
	parameter VGA_HBP = 12'd160;		//Hor Back Porch
	parameter VGA_HVT = 12'd1024;	//Hor Valid Time
	parameter VGA_HFP = 12'd24;		//Hor Front Porch

	parameter VGA_VTT = 12'd806-12'd1;	//Ver Total Time
	parameter VGA_VST = 12'd6;		//Ver Sync Time
	parameter VGA_VBP = 12'd29;		//Ver Back Porch
	parameter VGA_VVT = 12'd768;	//Ver Valid Time
	parameter VGA_VFP = 12'd3;		//Ver Front Porch
`endif

`ifdef VGA_1280_720
	//VGA Timing 1280*720 & 75MHz & 60Hz
	assign clk = clk_75m;

	parameter VGA_HTT = 12'd1648-12'd1;	//Hor Total Time
	parameter VGA_HST = 12'd80;		//Hor Sync  Time
	parameter VGA_HBP = 12'd216;		//Hor Back Porch
	parameter VGA_HVT = 12'd1280;	//Hor Valid Time
	parameter VGA_HFP = 12'd72;		//Hor Front Porch

	parameter VGA_VTT = 12'd750-12'd1;	//Ver Total Time
	parameter VGA_VST = 12'd5;		//Ver Sync Time
	parameter VGA_VBP = 12'd22;		//Ver Back Porch
	parameter VGA_VVT = 12'd720;	//Ver Valid Time
	parameter VGA_VFP = 12'd3;		//Ver Front Porch
`endif

`ifdef VGA_1280_1024
	//VGA Timing 1280*960 & 108MHz & 60Hz
	assign clk = clk_108m;

	parameter VGA_HTT = 12'd1688-12'd1;	//Hor Total Time
	parameter VGA_HST = 12'd112;		//Hor Sync  Time
	parameter VGA_HBP = 12'd248;		//Hor Back Porch
	parameter VGA_HVT = 12'd1280;	//Hor Valid Time
	parameter VGA_HFP = 12'd48;		//Hor Front Porch

	parameter VGA_VTT = 12'd1066-12'd1;	//Ver Total Time
	parameter VGA_VST = 12'd3;		//Ver Sync Time
	parameter VGA_VBP = 12'd38;		//Ver Back Porch
	parameter VGA_VVT = 12'd1024;	//Ver Valid Time
	parameter VGA_VFP = 12'd1;		//Ver Front Porch
`endif

`ifdef VGA_1280_960
	//VGA Timing 1280*1024 & 108MHz & 60Hz
	assign clk = clk_108m;

	parameter VGA_HTT = 12'd1800-12'd1;	//Hor Total Time
	parameter VGA_HST = 12'd112;		//Hor Sync  Time
	parameter VGA_HBP = 12'd312;		//Hor Back Porch
	parameter VGA_HVT = 12'd1280;	//Hor Valid Time
	parameter VGA_HFP = 12'd96;		//Hor Front Porch

	parameter VGA_VTT = 12'd1000-12'd1;	//Ver Total Time
	parameter VGA_VST = 12'd3;		//Ver Sync Time
	parameter VGA_VBP = 12'd36;		//Ver Back Porch
	parameter VGA_VVT = 12'd960;	//Ver Valid Time
	parameter VGA_VFP = 12'd1;		//Ver Front Porch
`endif

`ifdef VGA_1920_1080
	//VGA Timing 1920*1080 & 130MHz & 60Hz
	assign clk = clk_130m;

	parameter VGA_HTT = 12'd2000-12'd1;	//Hor Total Time
	parameter VGA_HST = 12'd12;		//Hor Sync  Time
	parameter VGA_HBP = 12'd40;		//Hor Back Porch
	parameter VGA_HVT = 12'd1920;	//Hor Valid Time
	parameter VGA_HFP = 12'd28;		//Hor Front Porch

	parameter VGA_VTT = 12'd1105-12'd1;	//Ver Total Time
	parameter VGA_VST = 12'd4;		//Ver Sync Time
	parameter VGA_VBP = 12'd18;		//Ver Back Porch
	parameter VGA_VVT = 12'd1080;	//Ver Valid Time
	parameter VGA_VFP = 12'd3;		//Ver Front Porch
`endif

//-----------------------------------------------------------
	//x and y counter
reg[11:0] xcnt;
reg[11:0] ycnt;
	
always @(posedge clk or negedge rst_n)
	if(!rst_n) xcnt <= 12'd0;
	else if(xcnt >= VGA_HTT) xcnt <= 12'd0;
	else xcnt <= xcnt+1'b1;

always @(posedge clk or negedge rst_n)
	if(!rst_n) ycnt <= 12'd0;
	else if(xcnt == VGA_HTT) begin
		if(ycnt >= VGA_VTT) ycnt <= 12'd0;
		else ycnt <= ycnt+1'b1;
	end
	else ;
		
//-----------------------------------------------------------
	//hsy and vsy generate	
always @(posedge clk or negedge rst_n)
	if(!rst_n) vga_hsy <= 1'b0;
	else if(xcnt < VGA_HST) vga_hsy <= 1'b1;
	else vga_hsy <= 1'b0;
	
always @(posedge clk or negedge rst_n)
	if(!rst_n) vga_vsy <= 1'b0;
	else if(ycnt < VGA_VST) vga_vsy <= 1'b1;
	else vga_vsy <= 1'b0;	
	
//-----------------------------------------------------------	
	//vga valid signal generate
reg vga_valid;

always @(posedge clk or negedge rst_n)
	if(!rst_n) vga_valid <= 1'b0;
	else if((xcnt >= (VGA_HST+VGA_HBP)) && (xcnt < (VGA_HST+VGA_HBP+VGA_HVT))
				&& (ycnt >= (VGA_VST+VGA_VBP)) && (ycnt < (VGA_VST+VGA_VBP+VGA_VVT)))
		 vga_valid <= 1'b1;
	else vga_valid <= 1'b0;

assign adv7123_blank_n = vga_valid;
assign adv7123_sync_n = 1'b0;

//--------------------------------------------------
	//FIFO读请求信号和复位信号产生

always @(posedge clk or negedge rst_n)
	if(!rst_n) lcd_rfreq1 <= 1'b0;
	else if((xcnt >= (VGA_HST+VGA_HBP-2)) && (xcnt < (VGA_HST+VGA_HBP+640-2))
				&& (ycnt >= (VGA_VST+VGA_VBP+120)) && (ycnt < (VGA_VST+VGA_VBP+VGA_VVT-120)))
		 lcd_rfreq1 <= 1'b1;
	else lcd_rfreq1 <= 1'b0;
	
always @(posedge clk or negedge rst_n)
	if(!rst_n) lcd_rfreq2 <= 1'b0;
	else if((xcnt >= (VGA_HST+VGA_HBP+640-2)) && (xcnt < (VGA_HST+VGA_HBP+VGA_HVT-2))
				&& (ycnt >= (VGA_VST+VGA_VBP+120)) && (ycnt < (VGA_VST+VGA_VBP+VGA_VVT-120)))
		 lcd_rfreq2 <= 1'b1;
	else lcd_rfreq2 <= 1'b0;	

always @(posedge clk or negedge rst_n)
	if(!rst_n) lcd_rfclr <= 1'b1;
	else if(ycnt == 12'd0) lcd_rfclr <= 1'b1;
	else lcd_rfclr <= 1'b0;

//-----------------------------------------------------------
	//display corlor generate
reg[4:0] vga_rdb;
reg[5:0] vga_gdb;
reg[4:0] vga_bdb;

reg[15:0] lcd_db_rgb;	// LCD色彩显示寄存器

always @ (posedge clk or negedge rst_n)
	if(!rst_n) {vga_rdb,vga_gdb,vga_bdb} <= 16'd0;
	else if((ycnt >= (VGA_VST+VGA_VBP+120)) && (ycnt < (VGA_VST+VGA_VBP+VGA_VVT-120))) begin
		if((xcnt >= (VGA_HST+VGA_HBP-1)) && (xcnt < (VGA_HST+VGA_HBP+640-1))) {vga_rdb,vga_gdb,vga_bdb} <= lcd_rfdb1;
		else if((xcnt >= (VGA_HST+VGA_HBP+640-1)) && (xcnt < (VGA_HST+VGA_HBP+VGA_HVT-1))) {vga_rdb,vga_gdb,vga_bdb} <= lcd_rfdb2;
		else {vga_rdb,vga_gdb,vga_bdb} <= 16'd0;
	end
	else {vga_rdb,vga_gdb,vga_bdb} <= 16'd0;

//-----------------------------------------------------------
	//corlor data and clock generate
assign vga_r = vga_valid ? vga_rdb:5'd0;
assign vga_g = vga_valid ? vga_gdb:6'd0;	
assign vga_b = vga_valid ? vga_bdb:5'd0;	


endmodule

  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
基于Zynq摄像头采集系统设计与实现涉及到硬件与软件的两个方面。 在硬件方面,首先需要选择合适的摄像头,并将其连接到Zynq的片上资源中。常见的连接方式包括CMOS接口或者MIPI接口。接下来,需要对信号进行适配,由于摄像头输出的信号格式可能与Zynq的输入格式不一致,所以需要添加适配器或转换器。接着,需要将摄像头采集到的图像通过高速总线传输到Zynq的处理系统中。可以选择使用DDR内存或者片上RAM作为存储缓冲区。最后,可以添加适当的硬件外设,如按钮、LED灯等,以方便控制与显示。 在软件方面,首先需要配置Zynq处理系统FPGA部分,包括设置时钟频率、引脚分配等。接着,需要编写驱动程序与操作系统,以便能够对摄像头进行初始化、配置和图像数据的获取。可以选择使用Linux操作系统,并在其上编写相应的驱动程序。然后,需要编写应用程序,以实现对摄像头采集控制、图像处理、存储等功能。可以使用OpenCV等常见图像处理库来帮助完成这些功能。 最后,要进行系统的测试与调试,包括验证摄像头Zynq的连接是否正常、图像采集是否准确、图像处理是否正确等。可以通过显示摄像头采集到的图像、输出处理结果等方式进行验证。如果发现问题,需要检查硬件电路和相应的软件程序,进行必要的更改与修复。 总之,基于Zynq摄像头采集系统设计与实现涉及到硬件与软件两个方面,需要选择合适的摄像头、进行连接与信号适配,编写驱动程序与操作系统开发应用程序,并进行系统测试与调试,以保证其正常运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值