先上图
总体框图
效果图
效果不是很好,因为暂时用的是zedboard自带的VGA,其只能RGB只有3*3*3的彩色度
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文件的)。
V
转接板VmodCAM转接板
转接板VmodCAM转接板接在FMC上的:前段时间没事做了一块FMC的转接板,正好用上。
VGA原理图
vga用的是zedboard上自带的vga分辨率有限,接下来准备用HDMI
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的配置就行了。当然其他的外设可以根据需要自己设计
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********* "); 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 ",MT9D112_R_MESSAGE[i],(ReadCamera_R[0]<<8)|ReadCamera_R[1]); } printf("*****************end********************** "); } 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******************** "); printf(" Here we go "); printf(" Config the Camera "); 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 ",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 "); } 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 "); printf(" Camera Configure ByteCount Frame is:%d ",ByteCount/4); printf("******************************************************** "); return ByteCount; } else { printf(" Camera Configure ByteCount Frame is:%d ",ByteCount/4); print("Error: Camera Configure fail! "); printf("******************************************************** "); } } 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 "); 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! "); 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! "); // else // xil_printf("0x%02x 0x%02x ", 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 "); } 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 "); } 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********** "); print(" ----------test begin------------- "); 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-- "); printf("********************end******************* "); 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------ ", 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规范)