VmodCAM图像采集 VGA显示

先上图

总体框图

VmodCAM图像采集 VGA显示_第1张图片

效果图

 效果不是很好,因为暂时用的是zedboard自带的VGA,其只能RGB只有3*3*3的彩色度

VmodCAM图像采集 VGA显示_第2张图片

 

VmodCAM原理图

 VmodCAM的zedboard管脚约束见:http://blog.csdn.net/xiabodan/article/details/26144749

 VmodCAM的zedboard初始化见    :http://blog.csdn.net/xiabodan/article/details/26346935                  

              初始化采用SDK 中C编程,没有用HDL,原因嘛,想体验一下HDL与SDK混合使用的感觉,结果感觉就是很他妈复杂,太繁琐了,还不如直接多敲点verilog算了。废话不说,做都做了只能将就吧。

              其中遇到一个问题就是在HDL中的代码用到了RAM IP核,在导入EDK的create or import peripheral ->inport existing peripheral ->To XPS project ->Name->(选中HDL和Netlist),在后续的步骤中需要添加*.ngc文件,*.ngc文件就是core generate 生成相应IP时产生的网表文件(有了网表文件是可以不需要HDL文件的)。

VmodCAM图像采集 VGA显示_第3张图片V

转接板VmodCAM转接板

转接板VmodCAM转接板接在FMC上的:前段时间没事做了一块FMC的转接板,正好用上。

VmodCAM图像采集 VGA显示_第4张图片

VGA原理图

                   vga用的是zedboard上自带的vga分辨率有限,接下来准备用HDMI

VmodCAM图像采集 VGA显示_第5张图片

vga管脚约束

# VGA out
NET vga_blue<0>       LOC = Y21  | IOSTANDARD=LVCMOS33;  # "VGA-B1"
NET vga_blue<1>       LOC = Y20  | IOSTANDARD=LVCMOS33;  # "VGA-B2"
NET vga_blue<2>       LOC = AB20 | IOSTANDARD=LVCMOS33;  # "VGA-B3"
NET vga_blue<3>       LOC = AB19 | IOSTANDARD=LVCMOS33;  # "VGA-B4"
NET vga_green<0>      LOC = AB22 | IOSTANDARD=LVCMOS33;  # "VGA-G1"
NET vga_green<1>      LOC = AA22 | IOSTANDARD=LVCMOS33;  # "VGA-G2"
NET vga_green<2>      LOC = AB21 | IOSTANDARD=LVCMOS33;  # "VGA-G3"
NET vga_green<3>      LOC = AA21 | IOSTANDARD=LVCMOS33;  # "VGA-G4"
NET vga_red<0>        LOC = V20  | IOSTANDARD=LVCMOS33;  # "VGA-R1"
NET vga_red<1>        LOC = U20  | IOSTANDARD=LVCMOS33;  # "VGA-R2"
NET vga_red<2>        LOC = V19  | IOSTANDARD=LVCMOS33;  # "VGA-R3"
NET vga_red<3>        LOC = V18  | IOSTANDARD=LVCMOS33;  # "VGA-R4"
NET vga_hsync         LOC = AA19 | IOSTANDARD=LVCMOS33;  # "VGA-HS"
NET vga_vsync         LOC = Y19  | IOSTANDARD=LVCMOS33;  # "VGA-VS"

VmodCAM管脚约束

NET "OV7670_PWDN"    LOC = "Y11"  | IOSTANDARD=LVTTL | SLEW=SLOW; # JA0
NET "OV7670_RESET"   LOC = "AB11" | IOSTANDARD=LVTTL | SLEW=SLOW; # JA4
NET "OV7670_D<0>"    LOC = "J20"  | IOSTANDARD=LVTTL | SLEW=SLOW; # JA1
NET "OV7670_D<1>"    LOC = "K21"  | IOSTANDARD=LVTTL | SLEW=SLOW; # JA5
NET "OV7670_D<2>"    LOC = "M22"  | IOSTANDARD=LVTTL | SLEW=SLOW; # JA2
NET "OV7670_D<3>"    LOC = "J22"  | IOSTANDARD=LVTTL | SLEW=SLOW; # JA6
NET "OV7670_D<4>"    LOC = "P20"  | IOSTANDARD=LVTTL | SLEW=SLOW; # JA3
NET "OV7670_D<5>"    LOC = "P21"  | IOSTANDARD=LVTTL | SLEW=SLOW; # JA7

NET "OV7670_D<6>"    LOC = "T16"  | IOSTANDARD=LVTTL | SLEW=SLOW; # JB0
NET "OV7670_D<7>"    LOC = "T17"  | IOSTANDARD=LVTTL | SLEW=SLOW; # JB4
NET "OV7670_XCLK"    LOC = "P22"  | IOSTANDARD=LVTTL | SLEW=SLOW; # JB1
NET "OV7670_PCLK"    LOC = "J16"  | IOSTANDARD=LVTTL | SLEW=SLOW; # JB5
NET "OV7670_HREF"    LOC = "N18"  | IOSTANDARD=LVTTL | SLEW=SLOW; # JB2
NET "OV7670_VSYNC"   LOC = "N17"  | IOSTANDARD=LVTTL | SLEW=SLOW; # JB6
NET "OV7670_SIOD"    LOC = "P17"  | IOSTANDARD=LVTTL | SLEW=SLOW | PULLUP; # JB3
NET "OV7670_SIOC"    LOC = "P18"  | IOSTANDARD=LVTTL | SLEW=SLOW; # JB7
NET "OV7670_PCLK"    CLOCK_DEDICATED_ROUTE = FALSE;

EDK硬件设计

EDK中硬件只需要将我们的HDL设计添加进来(包括图像采集,VGA显示)。再添加一个IIC用于VmodCAM的配置就行了。当然其他的外设可以根据需要自己设计

VmodCAM图像采集 VGA显示_第6张图片

 

HDL软件

代码包见:http://download.csdn.net/detail/xiabodan/7489075

vga

----------------------------------------------------------------------------------
-- Engineer:  
-- Description: Generate analog 640x480 VGA, double-doublescanned from 19200 bytes of RAM
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity vga is
    Port ( 
		clk25       : in  STD_LOGIC;
		vga_red     : out STD_LOGIC_VECTOR(3 downto 0);
		vga_green   : out STD_LOGIC_VECTOR(3 downto 0);
		vga_blue    : out STD_LOGIC_VECTOR(3 downto 0);
		vga_hsync   : out STD_LOGIC;
		vga_vsync   : out STD_LOGIC;
		frame_addr  : out STD_LOGIC_VECTOR(18 downto 0);
		frame_pixel : in  STD_LOGIC_VECTOR(11 downto 0)
	 );
end vga;

architecture Behavioral of vga is
   -- Timing constants
   constant hRez       : natural := 640;
   constant hStartSync : natural := 640+16;
   constant hEndSync   : natural := 640+16+96;
   constant hMaxCount  : natural := 800;
	
   constant vRez       : natural := 480;
   constant vStartSync : natural := 480+10;
   constant vEndSync   : natural := 480+10+2;
   constant vMaxCount  : natural := 480+10+2+33;
	
	constant hsync_active : std_logic := '0';
	constant vsync_active : std_logic := '0';

   signal hCounter : unsigned( 9 downto 0) := (others => '0');
   signal vCounter : unsigned( 9 downto 0) := (others => '0');
	signal address  : unsigned(18 downto 0) := (others => '0');
	signal blank    : std_logic := '1';

begin
	frame_addr <= std_logic_vector(address);
	
   process(clk25)
   begin
		if rising_edge(clk25) then
			-- Count the lines and rows      
			if hCounter = hMaxCount-1 then
				hCounter <= (others => '0');
				if vCounter = vMaxCount-1 then
					vCounter <= (others => '0');
				else
					vCounter <= vCounter+1;
				end if;
			else
				hCounter <= hCounter+1;
			end if;

			if blank = '0' then
				vga_red   <= frame_pixel(11 downto 8);
				vga_green <= frame_pixel( 7 downto 4);
				vga_blue  <= frame_pixel( 3 downto 0);
			else
				vga_red   <= (others => '0');
				vga_green <= (others => '0');
				vga_blue  <= (others => '0');
			end if;
	
			if vCounter  >= vRez then
				address <= (others => '0');
				blank <= '1';
			else 
				if hCounter  < 640 then
					blank <= '0';
					address <= address+1;
				else
					blank <= '1';
				end if;
			end if;
	
			-- Are we in the hSync pulse? (one has been added to include frame_buffer_latency)
			if hCounter > hStartSync and hCounter <= hEndSync then
				vga_hSync <= hsync_active;
			else
				vga_hSync <= not hsync_active;
			end if;

			-- Are we in the vSync pulse?
			if vCounter >= vStartSync and vCounter < vEndSync then
				vga_vSync <= vsync_active;
			else
				vga_vSync <= not vsync_active;
			end if;
		end if;
	end process;
end Behavioral;


captrue

----------------------------------------------------------------------------------
-- Engineer: 
-- 
-- Description: Captures the pixels coming from the OV7670 camera and 
--              Stores them in block RAM
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity ov7670_capture is
    Port ( 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 ov7670_capture;

architecture Behavioral of ov7670_capture is
   signal d_latch      : std_logic_vector(15 downto 0) := (others => '0');
   signal address      : STD_LOGIC_VECTOR(18 downto 0) := (others => '0');
   signal address_next : STD_LOGIC_VECTOR(18 downto 0) := (others => '0');
   signal wr_hold      : std_logic_vector(1 downto 0)  := (others => '0');
   
begin
   addr <= address;
   process(pclk)
   begin
      if rising_edge(pclk) then
         -- This is a bit tricky href starts a pixel transfer that takes 3 cycles
         --        Input   | state after clock tick   
         --         href   | wr_hold    d_latch           d                 we address  address_next
         -- cycle -1  x    |    xx      xxxxxxxxxxxxxxxx  xxxxxxxxxxxxxxxx  x   xxxx     xxxx
         -- cycle 0   1    |    x1      xxxxxxxxRRRRRGGG  xxxxxxxxxxxxxxxx  x   xxxx     addr
         -- cycle 1   0    |    10      RRRRRGGGGGGBBBBB  xxxxxxxxRRRRRGGG  x   addr     addr
         -- cycle 2   x    |    0x      GGGBBBBBxxxxxxxx  RRRRRGGGGGGBBBBB  1   addr     addr+1

         if vsync = '0' then 
            address <= (others => '0');
            address_next <= (others => '0');
            wr_hold <= (others => '0');
         else
-- This should be a different order, but seems to be GRB!
--            dout    <= d_latch(11 downto 10) & d_latch(11 downto 10) & d_latch(15 downto 12) & d_latch(9 downto 8) & d_latch(9 downto 8); 
            dout    <= d_latch(15 downto 12) & d_latch(10 downto 7) & d_latch(4 downto 1); 
            address <= address_next;
            we      <= wr_hold(1);
            wr_hold <= wr_hold(0) & (href and not wr_hold(0));
            d_latch <= d_latch( 7 downto  0) & d;

            if wr_hold(1) = '1' then
               address_next <= std_logic_vector(unsigned(address_next)+1);
            end if;

         end if;
      end if;
   end process;
end Behavioral;


SDK 软件

IIC配置摄像头

#define XPAR_FMC_IIC_0_BASEADDR 0x41600000
#define XPAR_CAMER_IIC_A_BASEADDR 0x41660000
#define XPAR_CAMER_IIC_B_BASEADDR 0x41640000
#define CAMERA_ADDRESS_ID (0x78>>1)
#define MT9D112_CONFIG_BUFFER_ROWS ((sizeof(MT9D112_CONFIG_BUFFER))/(sizeof(MT9D112_CONFIG_BUFFER[0])))
#define MT9D112_R_READ_BUFFER_ROWS ((sizeof(MT9D112_R_READ_BUFFER))/(sizeof(MT9D112_R_READ_BUFFER[0])))
static const char *MT9D112_R_MESSAGE[] = {"R[0X3000]","R[0X3214]","R[0X341C]","R[0X341E]","R[0X3202]","R[0X3386]","R[0X338C]","R[0X3390]","R[0X3040]"};
u8 MT9D112_R_READ_BUFFER[][2] = {
				{0x30,0x00},
				{0x32,0x14},//Slew rate control
				{0x34,0x1c},//PLL dividers
				{0x34,0x1e},//PLL control
				{0x32,0x02},//stanbdy
				{0x33,0x86},
				{0x33,0x8c},
				{0x33,0x90},
				{0x30,0x40}
};
void Read_MT9D112_R_Message(u32 BaseAddress)
{
	u8 i=0;
	u8 ReadCamera_R[2];
	printf("*******camera initialize register*********\n");
	for(i=0;i<MT9D112_R_READ_BUFFER_ROWS;i++)
	{
		read_camera_config(BaseAddress,MT9D112_R_READ_BUFFER[i],ReadCamera_R);
		printf("    %s is: 0x%x\n",MT9D112_R_MESSAGE[i],(ReadCamera_R[0]<<8)|ReadCamera_R[1]);
	}
	printf("*****************end**********************\n");
}
u8 MT9D112_CONFIG_BUFFER[][4] = {
				0x30,0x00,0x00,0x00, // Chip version. Default 0x1580  !! only for read   !!
				0x33,0x86,0x05,0x01, // MCU Reset
				0x33,0x86,0x05,0x00, // MCU Release from reset
				0x32,0x14,0x0D,0x85, // Slew rate control, PCLK 5, D 5
				0x34,0x1E,0x8F,0x09, // PLL control; bypassed, powered down
				0x34,0x1C,0x02,0x50, // PLL dividers; M=80,N=2,fMCLK=fCLKIN*M/(N+1)/8=80MHz
				0x34,0x1E,0x8F,0x09, // PLL control; Power-up PLL; wait 1ms after this!
				0x34,0x1E,0x8F,0x08, // PLL control; Turn off bypass
				0x32,0x02,0x00,0x08, // Standby control; Wake up
				0x33,0x8C,0x27,0x97, // Output format; Context B shadow
				0x33,0x90,0x00,0x20, // RGB with BT656 codes
				0x33,0x8C,0x27,0x2F, // Sensor Row Start Context B
				0x33,0x90,0x00,0x04, // 4
				0x33,0x8C,0x27,0x33, // Sensor Row End Context B
				0x33,0x90,0x04,0xBB, // 1211
				0x33,0x8C,0x27,0x31, // Sensor Column Start Context B
				0x33,0x90,0x00,0x04, // 4
				0x33,0x8C,0x27,0x35, // Sensor Column End Context B
				0x33,0x90,0x06,0x4B, // 1611
				0x33,0x8C,0x27,0x07, // Output width; Context B
				0x33,0x90,0x02,0x80, // 640
				0x33,0x8C,0x27,0x09, // Output height; Context B
				0x33,0x90,0x01,0xE0, // 480
				0x33,0x8C,0x27,0x5F, // Crop X0; Context B
				0x33,0x90,0x00,0x00, // 0
				0x33,0x8C,0x27,0x63, // Crop Y0; Context B
				0x33,0x90,0x00,0x00, // 0
				0x33,0x8C,0x27,0x61, // Crop X1; Context B
				0x33,0x90,0x06,0x40, // 1600
				0x33,0x8C,0x27,0x65, // Crop Y1; Context B
				0x33,0x90,0x04,0xB0, // 1200
				0x33,0x8C,0x27,0x41, // Sensor_Fine_IT_min B
				0x33,0x90,0x01,0x69, // 361
				0x33,0x8C,0xA1,0x20, // Capture mode options
				0x33,0x90,0x00,0xF2, // Turn on AWB, AE, HG, Video
				0x33,0x8C,0xA1,0x03, // Refresh Sequencer Mode
				0x33,0x90,0x00,0x02, // Capture sequencer
				0x33,0x90,0x00,0x00, // Read until  in mode 0 (run)  ,This Frame is used for Read , do not write
				0x30,0x1A,0x02,0xCC, // reset/output control; parallel enable, drive pins, start streaming
};
int Vmod_Camera_IIC_Config(u32 BaseAddress)
{
	unsigned ByteCount=0;
	int i = 0;
	u8 ReadCamera_PLL_Config[2]; //Read the PLL configure register
	u8 ReadCamera_ChipVersion_Rdata[2];
	u8 ReadCamera_Refresh[2];
	u16 Chip_Version = 0;
	printf("**********************Camera  config********************\n");
	printf("	Here we go\n");
	printf("	Config the Camera\n");

	for(i=0;i<MT9D112_CONFIG_BUFFER_ROWS;i++)
	{
		if (0 == i)
		{
			read_camera_config(BaseAddress,MT9D112_CONFIG_BUFFER[i],ReadCamera_ChipVersion_Rdata);
			Chip_Version = (ReadCamera_ChipVersion_Rdata[0] << 8) | ReadCamera_ChipVersion_Rdata[1];
			printf("	Read Chip Version is:0x%x\n",Chip_Version);
		}
//		else if( 8 == i)
//		{
//			read_camera_config(XPAR_CAMER_IIC_A_BASEADDR,MT9D112_CONFIG_BUFFER[i],ReadCamera_PLL_Config);
//			ByteCount += XIic_Send(XPAR_CAMER_IIC_A_BASEADDR,CAMERA_ADDRESS_ID,MT9D112_CONFIG_BUFFER[i],4,XIIC_STOP);
//		}
		else if(6 == i)
		{
			DelayMs(50);
			ByteCount += XIic_Send(BaseAddress,CAMERA_ADDRESS_ID,MT9D112_CONFIG_BUFFER[i],4,XIIC_STOP);
		}
		else if((MT9D112_CONFIG_BUFFER_ROWS-2) == i)
		{
			read_camera_config(BaseAddress,MT9D112_CONFIG_BUFFER[i],ReadCamera_Refresh);
			while(ReadCamera_Refresh[1] !=0)
				read_camera_config(BaseAddress,MT9D112_CONFIG_BUFFER[i],ReadCamera_Refresh);
			printf("	Refresh Sequencer Mode Complete\n");
		}
		else
			ByteCount += XIic_Send(BaseAddress,CAMERA_ADDRESS_ID,MT9D112_CONFIG_BUFFER[i],4,XIIC_STOP);
	}
	if((MT9D112_CONFIG_BUFFER_ROWS-2)*4 == ByteCount)
	{
		print("		Camera  Configure success\n");
		printf("	Camera  Configure ByteCount Frame is:%d\n",ByteCount/4);
		printf("********************************************************\n");
		return ByteCount;
	}
	else
	{
		printf("	Camera  Configure ByteCount Frame is:%d\n",ByteCount/4);
		print("Error: Camera  Configure fail!\n");
		printf("********************************************************\n");
	}
}
void read_camera_config (u32 BaseAddress, u8 *sub_addr, u8 *RdData)
{
	u8 sent_byte_count;
	u8 received_byte_count;

	RdData[0] = 0;
	RdData[1] = 0;

//	xil_printf("Read         \t");

	sent_byte_count = XIic_Send(BaseAddress, 0x78>>1, sub_addr, 2, XIIC_STOP); //write sub-address

	if (sent_byte_count != 2)
		print("Error: send the address fail when read camera register!\n");

	received_byte_count = XIic_Recv(BaseAddress, 0x79>>1, RdData, 2, XIIC_STOP); //read 2 byte datas

	if (received_byte_count != 2)
		print("Error: read data fail  when read camera register!      \n");
//	else
//		xil_printf("0x%02x 0x%02x\r\n", RdData[0], RdData[1]);


}

主函数

/*
 * Copyright (c) 2009-2012 Xilinx, Inc.  All rights reserved.
 *
 * Xilinx, Inc.
 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
 * COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
 * ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
 * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
 * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
 * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
 * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
 * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
 * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
 * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 */
#include <stdio.h>
#include "xparameters.h"
#include "xgpio.h"
#include "xgpiops.h"
#include "xiic.h"
#include "xiic_l.h"
#include "iic_config.h"
#include "public.h"
#include <malloc.h>
/*
 * system define
 */
#define VMODCAMERA
#define CAMER_GPIO_CTL_ADDRESS 0x41220000
#define EEPROM_ADDRESS 0x50	/* 0xA0 as an 8 bit number. */
/*
 * The page size determines how much data should be written at a time.
 * The ML300 board supports a page size of 32 and 16.
 * The write function should be called with this as a maximum byte count.
 */
#define PAGE_SIZE   3
/*
 * The Starting address in the IIC EEPROM on which this test is performed.
 */
#define EEPROM_TEST_START_ADDRESS   0x80

/*
 *  PS GPIO define
 */
#define PS_LD9_PINNUM       7
#define PS_INPIN_DERECTION  0
#define PS_OUTPIN_DERECTION 1
#define PS_GPIO_OUTENBLE    1
/*
 * AXI GPIO define
 */
#define AXI_GPIO_CHANNEL_1  1
#define AXI_GPIO_CHANNEL_2  2
/*
 * instance define
 */
static XIic IicInstance;		    /* The instance of the AXI IIC device. */
static XGpio AXI_GPIOInstancePtr;   /* The instance of the AXI GPIO device.*/
static XGpioPs PS_GPIOInstancePtr;  /* The instance of the PS GPIO device. */
//static XGpio *CAMER_GPIOInstancePtr; /* The instance of the AXI GPIO device.*/
/*
 * global variable declare
 */
typedef  enum {
	BTNC = 0,BTND,BTNU,BTNR,BTNL,
	SW0,SW1,SW2,SW3,SW4,SW5,SW6,SW7
}GPIO2_RDATA;
static const char *BTNx[5] = {"BTNC","BTND","BTNU","BTNR","BTNL"};
/*
 * function  declare
 */
GPIO2_RDATA XGpioBtn();
void Axi_Gpio_initial(XGpio *AXI_GPIOInstancePtr);
void ps_gpio_initial(XGpioPs *PS_GPIOInstancePtr);
void IIC_Test();

void Axi_Gpio_initial(XGpio *AXI_GPIOInstancePtr)
{
	int Status = 0;
	 	 	 /*
	 	          *  initial AXI GPIO and set the derection
	 	          */
	 	    Status = XGpio_Initialize(AXI_GPIOInstancePtr,XPAR_AXI_GPIO_0_DEVICE_ID );
	 	    XGpio_SetDataDirection(AXI_GPIOInstancePtr, AXI_GPIO_CHANNEL_1,0); //output
	 	    XGpio_SetDataDirection(AXI_GPIOInstancePtr, AXI_GPIO_CHANNEL_2,0x0c000000); //BTNS and BTND is input and other is output
	 	    if(XST_SUCCESS != Status )
	 	    {
	 	    	print ("AXIGPIO initial failed \n\r ");
	 	    }
		    XGpio_DiscreteWrite(AXI_GPIOInstancePtr,AXI_GPIO_CHANNEL_1,0x04);//
		    /*   GPIO[31]	GPIO[30]	GPIO[29]	GPIO[28] 	GPIO[0]
		     *   CB_PWDN     VDD_EN      CA_RST     CA_PWDN      CB_RST
		     *     0          1            0          0			  0
		     *     0          1            1          0			  1
		     */

		    XGpio_DiscreteWrite(AXI_GPIOInstancePtr,AXI_GPIO_CHANNEL_1,0xFFFFFFFF);//
		    XGpio_DiscreteWrite(AXI_GPIOInstancePtr,AXI_GPIO_CHANNEL_2,0x4000AA00);//power on the four 8-leds , rst the camera
		    DelayMs(200);
		    XGpio_DiscreteWrite(AXI_GPIOInstancePtr,AXI_GPIO_CHANNEL_2,0x60005501);//power on the other four8-leds,release the rst of the camera
}
void ps_gpio_initial(XGpioPs *PS_GPIOInstancePtr)
{
	 	 	 /*
		      *  initial PS GPIO
		      */
	int Status = 0;
			XGpioPs_Config *PS_GPIOConfigPtr;
		    PS_GPIOConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
		    Status = XGpioPs_CfgInitialize(PS_GPIOInstancePtr, PS_GPIOConfigPtr, PS_GPIOConfigPtr->BaseAddr);
		    if (XST_SUCCESS != Status)
		    {
		    	print("PSGPIO initial failed \n\r");
		    }
		    XGpioPs_SetDirectionPin(PS_GPIOInstancePtr, PS_LD9_PINNUM,PS_OUTPIN_DERECTION); /*set MIO9 output*/
		    XGpioPs_SetOutputEnablePin(PS_GPIOInstancePtr, PS_LD9_PINNUM ,PS_GPIO_OUTENBLE);/*enable MIO9 output*/
}

int main()
{
	    int Status ;
	 	 /*peripherals  initialize */
//	    init_platform();
	    printf("**********peripherals initialize**********\n");
	    print("    ----------test begin-------------\n");
	    Status = IIC_Initial(&IicInstance,XPAR_AXI_IIC_0_DEVICE_ID ); /* axi_0 initial*/
	    Axi_Gpio_initial(&AXI_GPIOInstancePtr);/* axi_gpio_0 initial*/
	    ps_gpio_initial(&PS_GPIOInstancePtr);  /* ps_gpio_0 initial*/
		XIic_WriteReg(XPAR_CAMER_IIC_A_BASEADDR, XIIC_RESETR_OFFSET,XIIC_RESET_MASK);//RESET the IIC bus
		XIic_WriteReg(XPAR_CAMER_IIC_B_BASEADDR, XIIC_RESETR_OFFSET,XIIC_RESET_MASK);//RESET the IIC bus
	    print("   --peripherals initialize success--\n");
	    printf("********************end*******************\n");
	    while(1)
	    {
//	    	IIC_Test();
	    	Status = XGpioBtn();
	    	if(BTNU == Status)
	    	{
	    		XIic_WriteReg(XPAR_CAMER_IIC_A_BASEADDR, XIIC_RESETR_OFFSET,XIIC_RESET_MASK);//RESET the IIC bus
	    		XIic_WriteReg(XPAR_CAMER_IIC_B_BASEADDR, XIIC_RESETR_OFFSET,XIIC_RESET_MASK);//RESET the IIC bus
	    		DelayMs(200);
	    		Vmod_Camera_IIC_Config(XPAR_CAMER_IIC_A_BASEADDR);
	    		DelayMs(200);
	    		Vmod_Camera_IIC_Config(XPAR_CAMER_IIC_B_BASEADDR);

	    	}
	    	if(BTNC == Status)
	    	{
	    		XIic_WriteReg(XPAR_CAMER_IIC_A_BASEADDR, XIIC_RESETR_OFFSET,XIIC_RESET_MASK);//RESET the IIC bus
	    		XIic_WriteReg(XPAR_CAMER_IIC_B_BASEADDR, XIIC_RESETR_OFFSET,XIIC_RESET_MASK);//RESET the IIC bus
	    		DelayMs(200);
	    		Read_MT9D112_R_Message(XPAR_CAMER_IIC_A_BASEADDR);
	    		DelayMs(200);
	    		Read_MT9D112_R_Message(XPAR_CAMER_IIC_B_BASEADDR);
	    	}

	    }
	    return 0;
}

GPIO2_RDATA XGpioBtn()
{
	 u32 AXI_Gpio_Channel_2_ReadData = 0;
	 u32 AXI_Gpio_Channel_2_ReadDirection = 0;
	 unsigned int index = 0;
	 DelayMs(50);
	 AXI_Gpio_Channel_2_ReadDirection = XGpio_GetDataDirection(&AXI_GPIOInstancePtr,2);             //Read the AXI_GPIO2 direction
	 XGpio_SetDataDirection(&AXI_GPIOInstancePtr, 2,0x0FFF8000 | AXI_Gpio_Channel_2_ReadDirection); //BTNX and SWx is input ,other is output
	 AXI_Gpio_Channel_2_ReadData = XGpio_DiscreteRead(&AXI_GPIOInstancePtr,AXI_GPIO_CHANNEL_2);     //Read the AXI_GPIO2 data
	 AXI_Gpio_Channel_2_ReadData = (AXI_Gpio_Channel_2_ReadData & 0x0FFF8000) >> 15 ;
// just return the only one button is be pressed
	 for(index=0;index<13;index++)
	 {
		 if((AXI_Gpio_Channel_2_ReadData & (1<<index)) != 0)
		 {
			 printf("--------%s is pressed------\n", BTNx[12-index]);
			 return (12 - index) ;
		 }
	 }

	 return -1;
}


 



 

 

参考:

         1、hamsterworks http://hamsterworks.co.nz/mediawiki/index.php/Zedboard_OV7670

         2、VmodCAM™ Reference Manuall

         3、1/4-Inch 2Mp System-On-A-Chip (SOC) CMOS  Digital Image Sensor

         4、VESA and Industry Standards and Guidelines  for Computer Display Monitor Timing(VGA规范)

你可能感兴趣的:(VM)