先上图
总体框图
效果图
效果不是很好,因为暂时用的是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*********\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规范)