Basys 3 FPGA OV7670摄像机

这个 FPGA项目 将会帮助您 将Basys 3 FPGA与OV7670 CMOS相机接口 甚高密度脂蛋白。它可以让您快速 开始实时处理DSP项目 图像/视频处理 不用担心相机界面.  

Basys 3 FPGA OV7670摄像机
使用的相机芯片是 便宜的CMOS相机 (〜3-5USD),名为OV7670。相机具有656x488像素的图像阵列,其中640x480像素处于活动状态。这项工作是基于 Mike Field-他为Nexys 2和Zedboard设计的详细信息 在Xilinx ISE中。摄像机与Basys 3 FPGA的连接如上图所示。

这个项目是为了 将Xilinx ISE for Zedboard中的设计迁移到具有640x480、320x240和160x120可重新配置图像大小的Basys 3 FPGA的Vivado Design Suite

要与OV7670相机接口,以下是最关键的步骤和模块:
1.摄像机配置(OV7670_controller.vhd): 要正确配置OV7670摄像机,请检查 其数据表 知道它支持配置和捕获数据的通信协议。在这种情况下,它类似于I2C SSCB接口,因此需要I2C代码与摄像机通信,对其进行配置并获取图像数据。可以在以下位置找到类似I2C的接口的更多详细信息 i2c_sender.vhd。要正确配置它,请检查设备控制寄存器列表。除了输出格式(RGB,QVGA,QCIF等),RGB格式(RGB565,RGB555等),时序信号(PCLK,HREF,VSYNC)的配置之外,   包括MTX1-MTX6的矩阵系数是决定输出图像质量的重要因素。有关控制寄存器值的更多详细信息,请参见: OV7670_registers.vhd。
Basys 3 FPGA OV7670摄像机
类似于I2C的SCCB接口,用于与OV7670摄像机进行通信

2.捕获图像数据(OV7670_capture.vhd): 配置相机后,下一步是捕获图像数据。再过一次,请检查相机的数据表,以查看所选输出格式的输出时序图。例如,在此项目中,选择了RGB565格式,因此RGB565的输出时序图用于从相机的输出信号中正确捕获RGB数据。根据以下时序图, OV7670_capture.vhd 被设计。
Basys 3 FPGA OV7670摄像机

3.保存图像数据(frame_buffer.vhd): 在能够配置相机并正确捕获图像数据之后,图像数据将存储在中间存储器中。 Basys 3 FPGA的问题在于Basys 3 FPGA的内存大小不足以容纳640x480图像大小。要在不超过Basys 3 FPGA的BRAM的情况下,为具有640x480全尺寸图像的相机和VGA控制器使用相同的设置,诀窍是仅保存 对于640x480尺寸,每4像素1个像素。然后,我们可以将帧缓冲区大小减小4倍,以适合Basys 3 FPGA,同时在VGA监视器上具有640x480的完整图像大小。对于320x240和160x120尺寸,可以通过按向左按钮以320x240图像尺寸显示,而在Basys 3 FPGA上按向右键可以选择在VGA监视器上以160x120帧尺寸显示。
为此,在Vivado中,您可以将块存储器文件(frame_buffer.xco-由Xilinx ISE中的Core Generator生成)升级到Vivado合适的LogiCore IP 块内存 v8.4(frame_buffer.xci),同时将内存大小减少4倍,或使用Vivado IP目录中的块内存生成器创建深度为131072(17位地址)的新帧缓冲区。 
Basys 3 FPGA OV7670摄像机
这样,您将获得新更新的17位帧缓冲区 RAM地址如下:
-- FPGA4student.com: Basys 3 FPGA OV7670摄像机
-- Frame Buffer by Vivado IP LogiCore
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

LIBRARY blk_mem_gen_v8_4_0;
USE blk_mem_gen_v8_4_0.blk_mem_gen_v8_4_0;

ENTITY frame_buffer IS
  PORT (
    clka : IN STD_LOGIC;
    wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
    addra : IN STD_LOGIC_VECTOR(16 DOWNTO 0);
    dina : IN STD_LOGIC_VECTOR(11 DOWNTO 0);
    clkb : IN STD_LOGIC;
    addrb : IN STD_LOGIC_VECTOR(16 DOWNTO 0);
    doutb : OUT STD_LOGIC_VECTOR(11 DOWNTO 0)
  );
END frame_buffer;
4.在VGA监视器(vga.vhd)上显示实时视频/图像: 最后一步是在VGA监视器上显示保存在帧缓冲区中的图像数据,并且需要VGA控制器。以下是VGA时钟为25MHz的VGA控制器的时序图和表格。
Basys 3 FPGA OV7670摄像机

Basys 3 FPGA OV7670摄像机

最后,Basys 3 FPGA上的OV7670摄像机的顶级VHDL代码:

-- Based on the work for Zedboard FPGA by Mike Field <[email protected]>
-- OV7670 Camera with Basys 3 FPGA by FPGA4student.com
-- Module Name: top_level - Behavioral 
-- Description: Top level module of the Zedboard OV7670 design
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity top_level is
    Port ( clk100          : in  STD_LOGIC;
           btnl            : in  STD_LOGIC;
           btnc            : in  STD_LOGIC;
           btnr            : in  STD_LOGIC;
           config_finished : out STD_LOGIC;
           
           vga_hsync : out  STD_LOGIC;
           vga_vsync : out  STD_LOGIC;
           vga_r     : out  STD_LOGIC_vector(3 downto 0);
           vga_g     : out  STD_LOGIC_vector(3 downto 0);
           vga_b     : out  STD_LOGIC_vector(3 downto 0);
           
           ov7670_pclk  : in  STD_LOGIC;
           ov7670_xclk  : out STD_LOGIC;
           ov7670_vsync : in  STD_LOGIC;
           ov7670_href  : in  STD_LOGIC;
           ov7670_data  : in  STD_LOGIC_vector(7 downto 0);
           ov7670_sioc  : out STD_LOGIC;
           ov7670_siod  : 进出 STD_LOGIC;
           ov7670_pwdn  : out STD_LOGIC;
           ov7670_reset : out STD_LOGIC
           );
end top_level;
architecture Behavioral of top_level is

 COMPONENT VGA
 PORT(
  CLK25 : IN std_logic;    
                rez_160x120 : IN std_logic;
                rez_320x240 : IN std_logic;
  Hsync : OUT std_logic;
  Vsync : OUT std_logic;
  Nblank : OUT std_logic;      
  clkout : OUT std_logic;
  activeArea : OUT std_logic;
  Nsync : OUT std_logic
  );
 END COMPONENT;

 COMPONENT ov7670_controller
 PORT(
  clk : IN std_logic;
  resend : IN std_logic;    
  siod : INOUT std_logic;      
  config_finished : OUT std_logic;
  sioc : OUT std_logic;
  reset : OUT std_logic;
  pwdn : OUT std_logic;
  xclk : OUT std_logic
  );
 END COMPONENT;

 COMPONENT debounce
 PORT(
  clk : IN std_logic;
  i : IN std_logic;          
  o : OUT std_logic
  );
 END COMPONENT;

 COMPONENT frame_buffer
  PORT (
      clka : IN STD_LOGIC;
      wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
      addra : IN STD_LOGIC_VECTOR(16 DOWNTO 0);
      dina : IN STD_LOGIC_VECTOR(11 DOWNTO 0);
      clkb : IN STD_LOGIC;
      addrb : IN STD_LOGIC_VECTOR(16 DOWNTO 0);
      doutb : OUT STD_LOGIC_VECTOR(11 DOWNTO 0)
    );
 END COMPONENT;
 COMPONENT ov7670_capture
 PORT(
                rez_160x120 : IN std_logic;
                rez_320x240 : IN std_logic;
  pclk : IN std_logic;
  vsync : IN std_logic;
  href : IN std_logic;
  d : IN std_logic_vector(7 downto 0);          
  addr : OUT std_logic_vector(18 downto 0);
  dout : OUT std_logic_vector(11 downto 0);
  we : OUT std_logic
  );
 END COMPONENT;
 COMPONENT RGB
 PORT(
  Din : IN std_logic_vector(11 downto 0);
  Nblank : IN std_logic;          
  R : OUT std_logic_vector(7 downto 0);
  G : OUT std_logic_vector(7 downto 0);
  B : OUT std_logic_vector(7 downto 0)
  );
 END COMPONENT;
 component clocking
 port (
                CLK_100           : in     std_logic;
                -- Clock out ports
                CLK_50          : out    std_logic;
                CLK_25          : out    std_logic);
 end component;
 COMPONENT Address_Generator
 PORT(
  CLK25       : IN  std_logic;
                rez_160x120 : IN std_logic;
                rez_320x240 : IN std_logic;
  enable      : IN  std_logic;       
                vsync       : in  STD_LOGIC;
  address     : OUT std_logic_vector(18 downto 0)
  );
 END COMPONENT;
   signal clk_camera : std_logic;
   signal clk_vga    : std_logic;
   signal wren       : std_logic_vector(0 downto 0);
   signal resend     : std_logic;
   signal nBlank     : std_logic;
   signal vSync      : std_logic;
   signal nSync      : std_logic;
   
   signal wraddress  : std_logic_vector(18 downto 0);
   signal wrdata     : std_logic_vector(11 downto 0);
   
   signal rdaddress  : std_logic_vector(18 downto 0);
   signal rddata     : std_logic_vector(11 downto 0);
   signal red,green,blue : std_logic_vector(7 downto 0);
   signal activeArea : std_logic;
   
   signal rez_160x120 : std_logic;
   signal rez_320x240 : std_logic;
   signal size_select: std_logic_vector(1 downto 0);
   signal rd_addr,wr_addr  : std_logic_vector(16 downto 0);
begin
   vga_r <= red(7 downto 4);
   vga_g <= green(7 downto 4);
   vga_b <= blue(7 downto 4);
   
   rez_160x120 <= btnl;
   rez_320x240 <= btnr;
   your_instance_name : clocking
     port map
      (-- Clock in ports
       CLK_100 => CLK100,
       -- Clock out ports
       CLK_50 => CLK_camera,
       CLK_25 => CLK_vga);
       vga_vsync <= vsync;
   
 Inst_VGA: VGA PORT MAP(
  CLK25      => clk_vga,
                rez_160x120 => rez_160x120,
                rez_320x240 => rez_320x240,
  clkout     => open,
  Hsync      => vga_hsync,
  Vsync      => vsync,
  Nblank     => nBlank,
  Nsync      => nsync,
                activeArea => activeArea
 );
 Inst_debounce: debounce PORT MAP(
  clk => clk_vga,
  i   => btnc,
  o   => resend
 );
 Inst_ov7670_controller: ov7670_controller PORT MAP(
  clk             => clk_camera,
  resend          => resend,
  config_finished => config_finished,
  sioc            => ov7670_sioc,
  siod            => ov7670_siod,
  reset           => ov7670_reset,
  pwdn            => ov7670_pwdn,
  xclk            => ov7670_xclk
 );
 size_select <= btnl&btnr;

    with size_select select 
    rd_addr <= rdaddress(18 downto 2) when "00",
        rdaddress(16 downto 0) when "01",
        rdaddress(16 downto 0) when "10",
        rdaddress(16 downto 0) when "11";

   with size_select select 
    wr_addr <= wraddress(18 downto 2) when "00",
            wraddress(16 downto 0) when "01",
            wraddress(16 downto 0) when "10",
            wraddress(16 downto 0) when "11";
 Inst_frame_buffer: frame_buffer PORT MAP(
  addrb => rd_addr,
  clkb   => clk_vga,
  doutb        => rddata,
      
  clka   => ov7670_pclk,
  addra => wr_addr,
  dina      => wrdata,
  wea      => wren
 );
 Inst_ov7670_capture: ov7670_capture PORT MAP(
  pclk  => ov7670_pclk,
                rez_160x120 => rez_160x120,
                rez_320x240 => rez_320x240,
  vsync => ov7670_vsync,
  href  => ov7670_href,
  d     => ov7670_data,
  addr  => wraddress,
  dout  => wrdata,
  we    => wren(0)
 );
 Inst_RGB: RGB PORT MAP(
  Din => rddata,
  Nblank => activeArea,
  R => red,
  G => green,
  B => blue
 );
 Inst_Address_Generator: Address_Generator PORT MAP(
  CLK25 => clk_vga,
                rez_160x120 => rez_160x120,
                rez_320x240 => rez_320x240,
  enable => activeArea,
                vsync  => vsync,
  address => rdaddress
 );
end Behavioral;

Basys 3 FPGA上OV7670摄像机的引脚分配XDC文件:

## FPGA4student.com: Interfacing Basys 3 FPGA with OV7670 Camera
## Pin assignment
## Clock signal
set_property PACKAGE_PIN W5 [get_ports clk100]       
 set_property IOSTANDARD LVCMOS33 [get_ports clk100]
 create_clock -add -name sys_clk_pin -period 10。00 -waveform {0 5} [get_ports clk100]

    ##VGA Connector
    set_property PACKAGE_PIN G19 [get_ports {vga_r[0]}]                
        set_property IOSTANDARD LVCMOS33 [get_ports {vga_r[0]}]
    set_property PACKAGE_PIN H19 [get_ports {vga_r[1]}]                
        set_property IOSTANDARD LVCMOS33 [get_ports {vga_r[1]}]
    set_property PACKAGE_PIN J19 [get_ports {vga_r[2]}]                
        set_property IOSTANDARD LVCMOS33 [get_ports {vga_r[2]}]
    set_property PACKAGE_PIN N19 [get_ports {vga_r[3]}]                
        set_property IOSTANDARD LVCMOS33 [get_ports {vga_r[3]}]
    set_property PACKAGE_PIN N18 [get_ports {vga_b[0]}]                
        set_property IOSTANDARD LVCMOS33 [get_ports {vga_b[0]}]
    set_property PACKAGE_PIN L18 [get_ports {vga_b[1]}]                
        set_property IOSTANDARD LVCMOS33 [get_ports {vga_b[1]}]
    set_property PACKAGE_PIN K18 [get_ports {vga_b[2]}]                
        set_property IOSTANDARD LVCMOS33 [get_ports {vga_b[2]}]
    set_property PACKAGE_PIN J18 [get_ports {vga_b[3]}]                
        set_property IOSTANDARD LVCMOS33 [get_ports {vga_b[3]}]
    set_property PACKAGE_PIN J17 [get_ports {vga_g[0]}]                
        set_property IOSTANDARD LVCMOS33 [get_ports {vga_g[0]}]
    set_property PACKAGE_PIN H17 [get_ports {vga_g[1]}]                
        set_property IOSTANDARD LVCMOS33 [get_ports {vga_g[1]}]
    set_property PACKAGE_PIN G17 [get_ports {vga_g[2]}]                
        set_property IOSTANDARD LVCMOS33 [get_ports {vga_g[2]}]
    set_property PACKAGE_PIN D17 [get_ports {vga_g[3]}]                
        set_property IOSTANDARD LVCMOS33 [get_ports {vga_g[3]}]
    set_property PACKAGE_PIN P19 [get_ports vga_hsync]                        
        set_property IOSTANDARD LVCMOS33 [get_ports vga_hsync]
    set_property PACKAGE_PIN R19 [get_ports vga_vsync]                        
        set_property IOSTANDARD LVCMOS33 [get_ports vga_vsync]
## LEDs
set_property PACKAGE_PIN U16 [get_ports {config_finished}]     
 set_property IOSTANDARD LVCMOS33 [get_ports {config_finished}]   
##Buttons
set_property PACKAGE_PIN U18 [get_ports btnc]      
 set_property IOSTANDARD LVCMOS33 [get_ports btnc]
set_property PACKAGE_PIN W19 [get_ports btnl]                        
     set_property IOSTANDARD LVCMOS33 [get_ports btnl]
set_property PACKAGE_PIN T17 [get_ports btnr]      
         set_property IOSTANDARD LVCMOS33 [get_ports btnr]
## OV7670 Camera header pins
##Pmod Header JB
##Sch name = JB1
set_property PACKAGE_PIN A14 [get_ports {ov7670_pwdn}]     
 set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_pwdn}]
##Sch name = JB2
set_property PACKAGE_PIN A16 [get_ports {ov7670_data[0]}]     
 set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_data[0]}]
##Sch name = JB3
set_property PACKAGE_PIN B15 [get_ports {ov7670_data[2]}]     
 set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_data[2]}]
##Sch name = JB4
set_property PACKAGE_PIN B16 [get_ports {ov7670_data[4]}]     
 set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_data[4]}]
##Sch name = JB7
set_property PACKAGE_PIN A15 [get_ports {ov7670_reset}]     
 set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_reset}]
##Sch name = JB8
set_property PACKAGE_PIN A17 [get_ports {ov7670_data[1]}]     
 set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_data[1]}]
##Sch name = JB9
set_property PACKAGE_PIN C15 [get_ports {ov7670_data[3]}]     
 set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_data[3]}]
##Sch name = JB10 
set_property PACKAGE_PIN C16 [get_ports {ov7670_data[5]}]     
 set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_data[5]}]
##Pmod Header JC
##Sch name = JC1
set_property PACKAGE_PIN K17 [get_ports {ov7670_data[6]}]     
 set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_data[6]}]
##Sch name = JC2
set_property PACKAGE_PIN M18 [get_ports ov7670_xclk]     
 set_property IOSTANDARD LVCMOS33 [get_ports ov7670_xclk]
##Sch name = JC3
set_property PACKAGE_PIN N17 [get_ports ov7670_href]     
 set_property IOSTANDARD LVCMOS33 [get_ports ov7670_href]
##Sch name = JC4
set_property PACKAGE_PIN P18 [get_ports ov7670_siod]     
 set_property IOSTANDARD LVCMOS33 [get_ports ov7670_siod]
 set_property PULLUP TRUE [get_ports ov7670_siod]
##Sch name = JC7
set_property PACKAGE_PIN L17 [get_ports {ov7670_data[7]}]     
 set_property IOSTANDARD LVCMOS33 [get_ports {ov7670_data[7]}]
##Sch name = JC8
set_property PACKAGE_PIN M19 [get_ports ov7670_pclk]     
 set_property IOSTANDARD LVCMOS33 [get_ports ov7670_pclk]
    set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets {ov7670_pclk_IBUF}]
##Sch name = JC9
set_property PACKAGE_PIN P17 [get_ports ov7670_vsync]     
 set_property IOSTANDARD LVCMOS33 [get_ports ov7670_vsync]
##Sch name = JC10
set_property PACKAGE_PIN R18 [get_ports ov7670_sioc]     
 set_property IOSTANDARD LVCMOS33 [get_ports ov7670_sioc]

从带有Basys 3 FPGA的OV7670摄像机捕获的图像显示在VGA监视器上:

640x480:
Basys 3 FPGA OV7670摄像机
320x240:
Basys 3 FPGA OV7670摄像机
160x120:

Basys 3 FPGA OV7670摄像机

Basys 3 FPGA上OV7670摄像机的视频演示:

可以下载Vivado中Basys 3 FPGA上OV7670摄像机的完整项目文件 这里.
推荐的 FPGA项目:
FPGA Verilog 甚高密度脂蛋白课程

1条评论:

热门FPGA项目