1. OV7725摄像头
1.1 简介
OV7725是OmniVision(豪威科技)公司生产的CMOS图像传感器,该传感器功耗低、可靠性高一级采集速率快,主要应用在玩具、安防监控、电脑多媒体等领域。
OV7725感光阵列达到640*480,功能最快60fps VGA分辨率的图像采集。传感器内部集成了图像处理的功能,包括自动曝光控制(AEC)、自动增益控制(AGC)和自动白平衡(AWB)等。
1.2 SCCB接口
SCCB(Serial Camera Control Bus,串行摄像头控制总线)是由OV公司定义和发展的三线式串行总线。
该总线控制着OV系列摄像头的大部分功能,包括图像数据格式、分辨率以及图像处理参数等。
OV公司为了减少传感器引脚的封装,现在SCCB总线大多采用两线式接口总线。(类似IIC总线)
SCCB与IIC的差异
1、SCCB传输协议中,第9位为不必关心位,而IIC写传输协议为应答位。
2、SCCB每次传输过程不超过3个阶段(Phase),即不能连续读写。
3、SCCB读传输协议中没有重复开始的概念,在写完寄存器地址后,发起停止信号。
1.3 图像输出时序
OV7725支持多种不同分辨率图像的输出,包括VGA(640x480)、QVGA(320x240)、以及CIF(一种常用的标准化图像格式,分辨率为352x288)到40x30之间的任意尺寸。
OV7725支持多种不同的数据像素格式,包括YUV(亮度参数和色度参数量分开表示的像素格式)、RGB(其中RGB格式包括RGB565、RGB555)以及8位的RAW(原始图像数据)和10位的RAW。
2. 程序设计
使用FPGA开发板及OV7725摄像头实现图像采集,并通过VGA显示器显示,以及RGBLCD液晶屏(800*480)实时显示。
2.1 系统框图
2.2 SDRAM乒乓存储
2.3 源码
module ov7725_rgb565_640x480_vga(
input sys_clk , //系统时钟
input sys_rst_n , //系统复位,低电平有效
//摄像头接口
input cam_pclk , //cmos 数据像素时钟
input cam_vsync , //cmos 场同步信号
input cam_href , //cmos 行同步信号
input [7:0] cam_data , //cmos 数据
output cam_rst_n , //cmos 复位信号,低电平有效
output cam_sgm_ctrl, //cmos 时钟选择信号, 1:使用摄像头自带的晶振
output cam_scl , //cmos SCCB_SCL线
inout cam_sda , //cmos SCCB_SDA线
//SDRAM接口
output sdram_clk , //SDRAM 时钟
output sdram_cke , //SDRAM 时钟有效
output sdram_cs_n , //SDRAM 片选
output sdram_ras_n , //SDRAM 行有效
output sdram_cas_n , //SDRAM 列有效
output sdram_we_n , //SDRAM 写有效
output [1:0] sdram_ba , //SDRAM Bank地址
output [1:0] sdram_dqm , //SDRAM 数据掩码
output [12:0] sdram_addr , //SDRAM 地址
inout [15:0] sdram_data , //SDRAM 数据
//VGA接口
output vga_hs , //行同步信号
output vga_vs , //场同步信号
output [15:0] vga_rgb //红绿蓝三原色输出
);
//parameter define
parameter SLAVE_ADDR = 7'h21 ; //OV7725的器件地址7'h21
parameter BIT_CTRL = 1'b0 ; //OV7725的字节地址为8位 0:8位 1:16位
parameter CLK_FREQ = 26'd25_000_000; //i2c_dri模块的驱动时钟频率 25MHz
parameter I2C_FREQ = 18'd250_000 ; //I2C的SCL时钟频率,不超过400KHz
parameter CMOS_H_PIXEL = 24'd640 ; //CMOS水平方向像素个数,用于设置SDRAM缓存大小
parameter CMOS_V_PIXEL = 24'd480 ; //CMOS垂直方向像素个数,用于设置SDRAM缓存大小
//wire define
wire clk_100m ; //100mhz时钟,SDRAM操作时钟
wire clk_100m_shift ; //100mhz时钟,SDRAM相位偏移时钟
wire clk_25m ; //25mhz时钟,提供给vga驱动时钟
wire locked ;
wire rst_n ;
wire i2c_exec ; //I2C触发执行信号
wire [15:0] i2c_data ; //I2C要配置的地址与数据(高8位地址,低8位数据)
wire cam_init_done ; //摄像头初始化完成
wire i2c_done ; //I2C寄存器配置完成信号
wire i2c_dri_clk ; //I2C操作时钟
wire wr_en ; //sdram_ctrl模块写使能
wire [15:0] wr_data ; //sdram_ctrl模块写数据
wire rd_en ; //sdram_ctrl模块读使能
wire [15:0] rd_data ; //sdram_ctrl模块读数据
wire sdram_init_done ; //SDRAM初始化完成
wire sys_init_done ; //系统初始化完成(sdram初始化+摄像头初始化)
//*****************************************************
//** main code
//*****************************************************
assign rst_n = sys_rst_n & locked;
//系统初始化完成:SDRAM和摄像头都初始化完成
//避免了在SDRAM初始化过程中向里面写入数据
assign sys_init_done = sdram_init_done & cam_init_done;
//不对摄像头硬件复位,固定高电平
assign cam_rst_n = 1'b1;
//cmos 时钟选择信号,0:使用引脚XCLK提供的时钟 1:使用摄像头自带的晶振
assign cam_sgm_ctrl = 1'b1;
//锁相环
pll_clk u_pll_clk(
.areset (~sys_rst_n),
.inclk0 (sys_clk),
.c0 (clk_100m),
.c1 (clk_100m_shift),
.c2 (clk_25m),
.locked (locked)
);
//I2C配置模块
i2c_ov7725_rgb565_cfg u_i2c_cfg(
.clk (i2c_dri_clk),
.rst_n (rst_n),
.i2c_done (i2c_done),
.i2c_exec (i2c_exec),
.i2c_data (i2c_data),
.init_done (cam_init_done)
);
//I2C驱动模块
i2c_dri
#(
.SLAVE_ADDR (SLAVE_ADDR),
.CLK_FREQ (CLK_FREQ ),
.I2C_FREQ (I2C_FREQ )
)
u_i2c_dri(
.clk (clk_25m ),
.rst_n (rst_n ),
.i2c_exec (i2c_exec ),
.bit_ctrl (BIT_CTRL ),
.i2c_rh_wl (1'b0), //固定为0,只用到了IIC驱动的写操作
.i2c_addr (i2c_data[15:8]),
.i2c_data_w (i2c_data[7:0]),
.i2c_data_r (),
.i2c_done (i2c_done ),
.scl (cam_scl ),
.sda (cam_sda ),
.dri_clk (i2c_dri_clk) //I2C操作时钟
);
//CMOS图像数据采集模块
cmos_capture_data u_cmos_capture_data(
.rst_n (rst_n & sys_init_done), //系统初始化完成之后再开始采集数据
.cam_pclk (cam_pclk),
.cam_vsync (cam_vsync),
.cam_href (cam_href),
.cam_data (cam_data),
.cmos_frame_vsync (),
.cmos_frame_href (),
.cmos_frame_valid (wr_en), //数据有效使能信号
.cmos_frame_data (wr_data) //有效数据
);
//SDRAM 控制器顶层模块,封装成FIFO接口
//SDRAM 控制器地址组成: {bank_addr[1:0],row_addr[12:0],col_addr[8:0]}
sdram_top u_sdram_top(
.ref_clk (clk_100m), //sdram 控制器参考时钟
.out_clk (clk_100m_shift), //用于输出的相位偏移时钟
.rst_n (rst_n), //系统复位
//用户写端口
.wr_clk (cam_pclk), //写端口FIFO: 写时钟
.wr_en (wr_en), //写端口FIFO: 写使能
.wr_data (wr_data), //写端口FIFO: 写数据
.wr_min_addr (24'd0), //写SDRAM的起始地址
.wr_max_addr (CMOS_H_PIXEL*CMOS_V_PIXEL),//写SDRAM的结束地址
.wr_len (10'd512), //写SDRAM时的数据突发长度
.wr_load (~rst_n), //写端口复位: 复位写地址,清空写FIFO
//用户读端口
.rd_clk (clk_25m), //读端口FIFO: 读时钟
.rd_en (rd_en), //读端口FIFO: 读使能
.rd_data (rd_data), //读端口FIFO: 读数据
.rd_min_addr (24'd0), //读SDRAM的起始地址
.rd_max_addr (CMOS_H_PIXEL*CMOS_V_PIXEL),//读SDRAM的结束地址
.rd_len (10'd512), //从SDRAM中读数据时的突发长度
.rd_load (~rst_n), //读端口复位: 复位读地址,清空读FIFO
//用户控制端口
.sdram_read_valid (1'b1), //SDRAM 读使能
.sdram_pingpang_en (1'b1), //SDRAM 乒乓操作使能
.sdram_init_done (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_data (sdram_data), //SDRAM 数据
.sdram_dqm (sdram_dqm) //SDRAM 数据掩码
);
//VGA驱动模块
vga_driver u_vga_driver(
.vga_clk (clk_25m),
.sys_rst_n (rst_n),
.vga_hs (vga_hs),
.vga_vs (vga_vs),
.vga_rgb (vga_rgb),
.pixel_data (rd_data),
.data_req (rd_en), //请求像素点颜色数据输入
.pixel_xpos (),
.pixel_ypos ()
);
endmodule
详细代码OV7725摄像头显示VGA免费下载
2.4 LCD显示
系统框图
源码
此处只给出与VGA不同部分的代码,其余代码参考VGA。
module ov7725_rgb565_640x480_lcd(
input sys_clk , //系统时钟
input sys_rst_n , //系统复位,低电平有效
//摄像头接口
input cam_pclk , //cmos 数据像素时钟
input cam_vsync , //cmos 场同步信号
input cam_href , //cmos 行同步信号
input [7:0] cam_data , //cmos 数据
output cam_rst_n , //cmos 复位信号,低电平有效
output cam_sgm_ctrl, //cmos 时钟选择信号, 1:使用摄像头自带的晶振
output cam_scl , //cmos SCCB_SCL线
inout cam_sda , //cmos SCCB_SDA线
//SDRAM接口
output sdram_clk , //SDRAM 时钟
output sdram_cke , //SDRAM 时钟有效
output sdram_cs_n , //SDRAM 片选
output sdram_ras_n , //SDRAM 行有效
output sdram_cas_n , //SDRAM 列有效
output sdram_we_n , //SDRAM 写有效
output [1:0] sdram_ba , //SDRAM Bank地址
output [1:0] sdram_dqm , //SDRAM 数据掩码
output [12:0] sdram_addr , //SDRAM 地址
inout [15:0] sdram_data , //SDRAM 数据
//lcd接口
output lcd_hs , //LCD 行同步信号
output lcd_vs , //LCD 场同步信号
output lcd_de , //LCD 数据输入使能
output [15:0] lcd_rgb , //LCD RGB565颜色数据
output lcd_bl , //LCD 背光控制信号
output lcd_rst , //LCD 复位信号
output lcd_pclk //LCD 采样时钟
);
//parameter define
parameter SLAVE_ADDR = 7'h21 ; //OV7725的器件地址7'h21
parameter BIT_CTRL = 1'b0 ; //OV7725的字节地址为8位 0:8位 1:16位
parameter CLK_FREQ = 26'd33_333_333; //i2c_dri模块的驱动时钟频率 33.3MHz
parameter I2C_FREQ = 18'd250_000 ; //I2C的SCL时钟频率,不超过400KHz
parameter CMOS_H_PIXEL = 24'd640 ; //CMOS水平方向像素个数,用于设置SDRAM缓存大小
parameter CMOS_V_PIXEL = 24'd480 ; //CMOS垂直方向像素个数,用于设置SDRAM缓存大小
//wire define
wire clk_100m ; //100mhz时钟,SDRAM操作时钟
wire clk_100m_shift ; //100mhz时钟,SDRAM相位偏移时钟
wire clk_33_3m ; //33.3mhz时钟,提供给lcd驱动时钟
wire locked ;
wire rst_n ;
wire i2c_exec ; //I2C触发执行信号
wire [15:0] i2c_data ; //I2C要配置的地址与数据(高8位地址,低8位数据)
wire cam_init_done ; //摄像头初始化完成
wire i2c_done ; //I2C寄存器配置完成信号
wire i2c_dri_clk ; //I2C操作时钟
wire wr_en ; //sdram_ctrl模块写使能
wire [15:0] wr_data ; //sdram_ctrl模块写数据
wire rd_en ; //sdram_ctrl模块读使能
wire [15:0] rd_data ; //sdram_ctrl模块读数据
wire sdram_init_done ; //SDRAM初始化完成
wire sys_init_done ; //系统初始化完成(sdram初始化+摄像头初始化)
//*****************************************************
//** main code
//*****************************************************
assign rst_n = sys_rst_n & locked;
//系统初始化完成:SDRAM和摄像头都初始化完成
//避免了在SDRAM初始化过程中向里面写入数据
assign sys_init_done = sdram_init_done & cam_init_done;
//不对摄像头硬件复位,固定高电平
assign cam_rst_n = 1'b1;
//cmos 时钟选择信号, 1:使用摄像头自带的晶振
assign cam_sgm_ctrl = 1'b1;
//锁相环
pll_clk u_pll_clk(
.areset (~sys_rst_n),
.inclk0 (sys_clk),
.c0 (clk_100m),
.c1 (clk_100m_shift),
.c2 (clk_33_3m),
.locked (locked)
);
//I2C配置模块
i2c_ov7725_rgb565_cfg u_i2c_cfg(
.clk (i2c_dri_clk),
.rst_n (rst_n),
.i2c_done (i2c_done),
.i2c_exec (i2c_exec),
.i2c_data (i2c_data),
.init_done (cam_init_done)
);
//I2C驱动模块
i2c_dri
#(
.SLAVE_ADDR (SLAVE_ADDR), //参数传递
.CLK_FREQ (CLK_FREQ ),
.I2C_FREQ (I2C_FREQ )
)
u_i2c_dri(
.clk (clk_33_3m ),
.rst_n (rst_n ),
//i2c interface
.i2c_exec (i2c_exec ),
.bit_ctrl (BIT_CTRL ),
.i2c_rh_wl (1'b0), //固定为0,只用到了IIC驱动的写操作
.i2c_addr (i2c_data[15:8]),
.i2c_data_w (i2c_data[7:0]),
.i2c_data_r (),
.i2c_done (i2c_done ),
.scl (cam_scl ),
.sda (cam_sda ),
//user interface
.dri_clk (i2c_dri_clk) //I2C操作时钟
);
//CMOS图像数据采集模块
cmos_capture_data u_cmos_capture_data(
.rst_n (rst_n & sys_init_done), //系统初始化完成之后再开始采集数据
.cam_pclk (cam_pclk),
.cam_vsync (cam_vsync),
.cam_href (cam_href),
.cam_data (cam_data),
.cmos_frame_vsync (),
.cmos_frame_href (),
.cmos_frame_valid (wr_en), //数据有效使能信号
.cmos_frame_data (wr_data) //有效数据
);
//SDRAM 控制器顶层模块,封装成FIFO接口
//SDRAM 控制器地址组成: {bank_addr[1:0],row_addr[12:0],col_addr[8:0]}
sdram_top u_sdram_top(
.ref_clk (clk_100m), //sdram 控制器参考时钟
.out_clk (clk_100m_shift), //用于输出的相位偏移时钟
.rst_n (rst_n), //系统复位
//用户写端口
.wr_clk (cam_pclk), //写端口FIFO: 写时钟
.wr_en (wr_en), //写端口FIFO: 写使能
.wr_data (wr_data), //写端口FIFO: 写数据
.wr_min_addr (24'd0), //写SDRAM的起始地址
.wr_max_addr (CMOS_H_PIXEL*CMOS_V_PIXEL), //写SDRAM的结束地址
.wr_len (10'd512), //写SDRAM时的数据突发长度
.wr_load (~rst_n), //写端口复位: 复位写地址,清空写FIFO
//用户读端口
.rd_clk (clk_33_3m), //读端口FIFO: 读时钟
.rd_en (rd_en), //读端口FIFO: 读使能
.rd_data (rd_data), //读端口FIFO: 读数据
.rd_min_addr (24'd0), //读SDRAM的起始地址
.rd_max_addr (CMOS_H_PIXEL*CMOS_V_PIXEL), //读SDRAM的结束地址
.rd_len (10'd512), //从SDRAM中读数据时的突发长度
.rd_load (~rst_n), //读端口复位: 复位读地址,清空读FIFO
//用户控制端口
.sdram_read_valid (1'b1), //SDRAM 读使能
.sdram_pingpang_en (1'b1), //SDRAM 乒乓操作使能
.sdram_init_done (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_data (sdram_data), //SDRAM 数据
.sdram_dqm (sdram_dqm) //SDRAM 数据掩码
);
//LCD驱动显示模块
lcd_rgb_top u_lcd_rgb_top(
.lcd_clk (clk_33_3m),
.sys_rst_n (rst_n),
.lcd_hs (lcd_hs),
.lcd_vs (lcd_vs),
.lcd_de (lcd_de),
.lcd_rgb (lcd_rgb),
.lcd_bl (lcd_bl),
.lcd_rst (lcd_rst),
.lcd_pclk (lcd_pclk),
.cmos_data (rd_data),
.data_req (rd_en) //请求像素点颜色数据输入
);
endmodule
module lcd_rgb_top(
input lcd_clk, //LCD驱动时钟
input sys_rst_n, //复位信号
//lcd接口
output lcd_hs, //LCD 行同步信号
output lcd_vs, //LCD 场同步信号
output lcd_de, //LCD 数据输入使能
output [15:0] lcd_rgb, //LCD RGB565颜色数据
output lcd_bl, //LCD 背光控制信号
output lcd_rst, //LCD 复位信号
output lcd_pclk, //LCD 采样时钟
input [15:0] cmos_data, //CMOS传感器像素点数据
output data_req //请求像素点颜色数据输入
);
//wire define
wire [15:0] lcd_data_w ; //像素点数据
wire data_req_w ; //请求像素点颜色数据输入
wire [ 9:0] pixel_xpos_w; //像素点横坐标
wire [ 9:0] pixel_ypos_w; //像素点纵坐标
//*****************************************************
//** main code
//*****************************************************
lcd_driver u_lcd_driver( //lcd驱动模块
.lcd_clk (lcd_clk),
.sys_rst_n (sys_rst_n),
.lcd_hs (lcd_hs),
.lcd_vs (lcd_vs),
.lcd_de (lcd_de),
.lcd_rgb (lcd_rgb),
.lcd_bl (lcd_bl),
.lcd_rst (lcd_rst),
.lcd_pclk (lcd_pclk),
.pixel_data (lcd_data_w),
.data_req (),
.pixel_xpos (pixel_xpos_w),
.pixel_ypos (pixel_ypos_w)
);
lcd_display u_lcd_display( //lcd显示模块
.lcd_clk (lcd_clk),
.sys_rst_n (sys_rst_n),
.pixel_xpos (pixel_xpos_w),
.pixel_ypos (pixel_ypos_w),
.cmos_data (cmos_data),
.lcd_data (lcd_data_w),
.data_req (data_req)
);
endmodule
module lcd_driver(
input lcd_clk, //lcd模块驱动时钟
input sys_rst_n, //复位信号
//RGB LCD接口
output lcd_hs, //LCD 行同步信号
output lcd_vs, //LCD 场同步信号
output lcd_de, //LCD 数据输入使能
output [15:0] lcd_rgb, //LCD RGB565颜色数据
output lcd_bl, //LCD 背光控制信号
output lcd_rst, //LCD 复位信号
output lcd_pclk, //LCD 采样时钟
input [15:0] pixel_data, //像素点数据
output data_req , //请求像素点颜色数据输入
output [10:0] pixel_xpos, //像素点横坐标
output [10:0] pixel_ypos //像素点纵坐标
);
//parameter define
parameter H_SYNC = 11'd128; //行同步
parameter H_BACK = 11'd88; //行显示后沿
parameter H_DISP = 11'd800; //行有效数据
parameter H_FRONT = 11'd40; //行显示前沿
parameter H_TOTAL = 11'd1056; //行扫描周期
parameter V_SYNC = 11'd2; //场同步
parameter V_BACK = 11'd33; //场显示后沿
parameter V_DISP = 11'd480; //场有效数据
parameter V_FRONT = 11'd10; //场显示前沿
parameter V_TOTAL = 11'd525; //场扫描周期
//reg define
reg [10:0] cnt_h;
reg [10:0] cnt_v;
//wire define
wire lcd_en;
//*****************************************************
//** main code
//*****************************************************
assign lcd_bl = 1'b1; //RGB LCD显示模块背光控制信号
assign lcd_rst = 1'b1; //RGB LCD显示模块系统复位信号
assign lcd_pclk = lcd_clk; //RGB LCD显示模块采样时钟
//RGB LCD 采用数据输入使能信号同步时,行场同步信号需要拉高
assign lcd_de = lcd_en; //LCD输入的颜色数据采用数据输入使能信号同步
assign lcd_hs = 1'b1;
assign lcd_vs = 1'b1;
//使能RGB565数据输出
assign lcd_en = (((cnt_h >= H_SYNC+H_BACK) && (cnt_h < H_SYNC+H_BACK+H_DISP))
&&((cnt_v >= V_SYNC+V_BACK) && (cnt_v < V_SYNC+V_BACK+V_DISP)))
? 1'b1 : 1'b0;
//RGB565数据输出
assign lcd_rgb = lcd_en ? pixel_data : 16'd0;
//请求像素点颜色数据输入
assign data_req = (((cnt_h >= H_SYNC+H_BACK-1'b1) && (cnt_h < H_SYNC+H_BACK+H_DISP-1'b1))
&& ((cnt_v >= V_SYNC+V_BACK) && (cnt_v < V_SYNC+V_BACK+V_DISP)))
? 1'b1 : 1'b0;
//像素点坐标
assign pixel_xpos = data_req ? (cnt_h - (H_SYNC + H_BACK - 1'b1)) : 11'd0;
assign pixel_ypos = data_req ? (cnt_v - (V_SYNC + V_BACK - 1'b1)) : 11'd0;
//行计数器对像素时钟计数
always @(posedge lcd_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
cnt_h <= 11'd0;
else begin
if(cnt_h < H_TOTAL - 1'b1)
cnt_h <= cnt_h + 1'b1;
else
cnt_h <= 11'd0;
end
end
//场计数器对行计数
always @(posedge lcd_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
cnt_v <= 11'd0;
else if(cnt_h == H_TOTAL - 1'b1) begin
if(cnt_v < V_TOTAL - 1'b1)
cnt_v <= cnt_v + 1'b1;
else
cnt_v <= 11'd0;
end
end
endmodule
module lcd_display(
input lcd_clk, //lcd驱动时钟
input sys_rst_n, //复位信号
input [10:0] pixel_xpos, //像素点横坐标
input [10:0] pixel_ypos, //像素点纵坐标
input [15:0] cmos_data, //CMOS传感器像素点数据
output [15:0] lcd_data, //LCD像素点数据
output data_req //请求像素点颜色数据输入
);
//parameter define
parameter H_LCD_DISP = 11'd800; //LCD分辨率——行
parameter H_CMOS_DISP = 11'd640; //CMOS分辨率——行
localparam BLACK = 16'b00000_000000_00000; //RGB565 黑色
//reg define
reg data_val ; //数据有效信号
//wire define
wire [10:0] display_border_pos_l; //左侧边界的横坐标
wire [10:0] display_border_pos_r; //右侧边界的横坐标
//*****************************************************
//** main code
//*****************************************************
//左侧边界的横坐标计算 (800-640)/2-1 = 79
assign display_border_pos_l = (H_LCD_DISP - H_CMOS_DISP)/2-1;
//右侧边界的横坐标计算 640 + (800-640)/2-1 = 719
assign display_border_pos_r = H_CMOS_DISP + (H_LCD_DISP - H_CMOS_DISP)/2-1;
//请求像素点颜色数据输入 范围:79~718,共640个时钟周期
assign data_req = ((pixel_xpos >= display_border_pos_l) &&
(pixel_xpos < display_border_pos_r)) ? 1'b1 : 1'b0;
//在数据有效范围内,将摄像头采集的数据赋值给LCD像素点数据
assign lcd_data = data_val ? cmos_data : BLACK;
//有效数据滞后于请求信号一个时钟周期,所以数据有效信号在此延时一拍
always @(posedge lcd_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
data_val <= 1'b0;
else
data_val <= data_req;
end
endmodule