赞
踩
我的代码和正点原子的只有三处不同
这里只提供xdc的代码,其他代码请直接看正点原子的开源代码
开源代码链接及其路径:领航者v2/2_Embedded_System/ZYNQ_SDK_7010/26_ov5640_hdmi
XDC
#----------------------摄像头接口的时钟--------------------------- #72M create_clock -period 13.888 -name cam_pclk_0 [get_ports cam_pclk_0] set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets cam_pclk_0_IBUF_BUFG] set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets cam_pclk_0_IBUF] set_property PACKAGE_PIN M17 [get_ports cam_vsync_0] set_property IOSTANDARD LVCMOS33 [get_ports cam_vsync_0] set_property PACKAGE_PIN J20 [get_ports cam_pclk_0] set_property IOSTANDARD LVCMOS33 [get_ports cam_pclk_0] set_property PACKAGE_PIN G19 [get_ports cam_pwdn_0] set_property IOSTANDARD LVCMOS33 [get_ports cam_pwdn_0] set_property PACKAGE_PIN N20 [get_ports cam_href_0] set_property IOSTANDARD LVCMOS33 [get_ports cam_href_0] set_property PACKAGE_PIN M18 [get_ports cam_rst_n_0] set_property IOSTANDARD LVCMOS33 [get_ports cam_rst_n_0] set_property PACKAGE_PIN H20 [get_ports {cam_data_0[7]}] set_property PACKAGE_PIN K19 [get_ports {cam_data_0[6]}] set_property PACKAGE_PIN J19 [get_ports {cam_data_0[5]}] set_property PACKAGE_PIN L20 [get_ports {cam_data_0[4]}] set_property PACKAGE_PIN L19 [get_ports {cam_data_0[3]}] set_property PACKAGE_PIN L17 [get_ports {cam_data_0[2]}] set_property PACKAGE_PIN L16 [get_ports {cam_data_0[1]}] set_property PACKAGE_PIN M20 [get_ports {cam_data_0[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[7]}] set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[6]}] set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[5]}] set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[0]}] set_property PACKAGE_PIN H16 [get_ports UART_0_0_rxd] set_property PACKAGE_PIN H17 [get_ports UART_0_0_txd] set_property IOSTANDARD LVCMOS33 [get_ports UART_0_0_rxd] set_property IOSTANDARD LVCMOS33 [get_ports UART_0_0_txd] set_property PACKAGE_PIN B19 [get_ports {TMDS_0_tmds_data_p[2]}] set_property PACKAGE_PIN C20 [get_ports {TMDS_0_tmds_data_p[1]}] set_property PACKAGE_PIN D19 [get_ports {TMDS_0_tmds_data_p[0]}] set_property PACKAGE_PIN F19 [get_ports TMDS_0_tmds_clk_p] #cam_scl: set_property -dict {PACKAGE_PIN P18 IOSTANDARD LVCMOS33} [get_ports {emio_sccb_tri_io[0]}] #cam_sda: set_property -dict {PACKAGE_PIN M19 IOSTANDARD LVCMOS33} [get_ports {emio_sccb_tri_io[1]}] set_property PULLUP true [get_ports {emio_sccb_tri_io[1]}]
既然是学习,就不能浅尝辄止,下面是一些我学习时的笔记。
这个函数将根据ID配置VDMA的读写路径,ID就是直接上xparameters.h找到你在vivado中配置的VDMA ID即可。
#define XPAR_AXIVDMA_0_DEVICE_ID XPAR_AXI_VDMA_0_DEVICE_ID
位置 | 参数 | 含义 |
---|---|---|
1 | InstancePtr | 是XAxiVdma数据结构的句柄 |
2 | DeviceId | 当前VDMA的设备ID |
3 | hize | 帧的水平大小,以像素为单位 |
4 | vsize | 帧的垂直大小。 |
5 | buf_base_addr | VDMA写入和读取帧的缓冲区地址 |
6 | number_frame_count | 指定中断应该在多少帧之后到来 |
7 | enable_frm_cnt_intr | 置1时启用帧计数中断。 |
8 | select | 可设置读取通道、写入通道或读取和写入通道。 |
XST_SUCCESS 和 -XST_FAILURE
run_vdma_frame_buffer(&vdma, VDMA_ID, vd_mode.width, vd_mode.height,
frame_buffer_addr,0,0,BOTH);
其中,选择关闭帧计数中断,和中断计数,并将通道选择为both,即为读写通道
这个是重点
unsigned int const frame_buffer_addr = (XPAR_PS7_DDR_0_S_AXI_BASEADDR
+ 0x1000000);
其中XPAR_PS7_DDR_0_S_AXI_BASEADDR比较好理解,它就是我们在建立BD文件时,为这个VDMA分配的帧缓存空间的起始地址
/* Definitions for peripheral PS7_DDR_0 */
#define XPAR_PS7_DDR_0_S_AXI_BASEADDR 0x00100000
#define XPAR_PS7_DDR_0_S_AXI_HIGHADDR 0x0FFFFFFF
而加上0x1000000是为了给ps端运行留一些内存,让他使用的。
这个API函数能够用来配置我们放置在BD中的动态时钟的,并且它能够通过当前的video timing contraller 的ID获知,当前使用的是什么格式的视频流,进而查表后输出相应的时钟频率。
最终要的是,它能够返回一个dispCtrl结构句柄,我们可以使用这个句柄完成各种操作。
DisplayInitialize(&dispCtrl, DISP_VTC_ID, DYNCLK_BASEADDR);
第二个参数就是当前的video timing contraller 的ID,然后他会把得到的视频格式信息写入dispCtrl结构句柄中,给后续流程使用。
typedef struct {
u32 dynClkAddr;/*Physical Base address of the dynclk core*/
XVtc vtc; /*VTC driver struct*/
VideoMode vMode; /*Current Video mode*/
double pxlFreq; /* Frequency of clock currently being generated */
DisplayState state; /* Indicates if the Display is currently running */
} DisplayCtrl;
typedef struct { char label[64]; /* Label describing the resolution */ u32 width; /*Width of the active video frame*/ u32 height; /*Height of the active video frame*/ u32 hps; /*Start time of Horizontal sync pulse, in pixel clocks (active width + H. front porch)*/ u32 hpe; /*End time of Horizontal sync pulse, in pixel clocks (active width + H. front porch + H. sync width)*/ u32 hmax; /*Total number of pixel clocks per line (active width + H. front porch + H. sync width + H. back porch) */ u32 hpol; /*hsync pulse polarity*/ u32 vps; /*Start time of Vertical sync pulse, in lines (active height + V. front porch)*/ u32 vpe; /*End time of Vertical sync pulse, in lines (active height + V. front porch + V. sync width)*/ u32 vmax; /*Total number of lines per frame (active height + V. front porch + V. sync width + V. back porch) */ u32 vpol; /*vsync pulse polarity*/ double freq; /*Pixel Clock frequency*/ } VideoMode; static const VideoMode VMODE_480x272 = { .label = "480x272@60Hz", .width = 480, .height = 272, .hps = 482, .hpe = 523, .hmax = 525, .hpol = 0, .vps = 274, .vpe = 284, .vmax = 286, .vpol = 0, .freq = 9 }; static const VideoMode VMODE_640x480 = { .label = "640x480@60Hz", .width = 640, .height = 480, .hps = 656, .hpe = 752, .hmax = 799, .hpol = 0, .vps = 490, .vpe = 492, .vmax = 524, .vpol = 0, .freq = 25.12 };
这个句柄相当重要,它的成员变量有:动态CLK的地址dynClkAddr,当前视频流vtc结构体vtc,视频格式vMode,当前视频流的pclk,和用于控制这个结构句柄指向的视频流的工作状态state
typedef struct {
u32 dynClkAddr;/*Physical Base address of the dynclk core*/
XVtc vtc; /*VTC driver struct*/
VideoMode vMode; /*Current Video mode*/
double pxlFreq; /* Frequency of clock currently being generated */
DisplayState state; /* Indicates if the Display is currently running */
} DisplayCtrl;
通过调整state就能控制视频流是否工作。
typedef enum {
DISPLAY_STOPPED = 0,
DISPLAY_RUNNING = 1
} DisplayState;
dispPtr->state = DISPLAY_RUNNING
用于初始化dispCtrl结构句柄,注意它会缺省地将视频输出模式设置为800X480,所以需要用DisplaySetMode对其进行配置
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。