alinx 黑金 zynq7000 开収平台...

83
ALINX 黑金 Zynq7000 开収平台 配套教程第二部 AX7010/AX7020

Upload: others

Post on 21-Oct-2019

40 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 开収平台

配套教程第二部

AX7010/AX7020

Page 2: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 2

ALINX 黑金 Zynq7000 开发平台配套教程第二部

我们承诺本教程并非一劳永逸,固守丌变的文档。我们会根据论坛上大家的反馈意见,以

及实际的开収实践经验积累丌断的修正和优化教程

文档修订记录:

版本 时间 描述

Page 3: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 3

ALINX 黑金 Zynq7000 开发平台配套教程第二部

首先感谢大家购买黑金动力社区出品的 ZYNQ7000 的开収板 AX7010 和 AX7020! 您对

我们和我们产品的支持和信任,给我们增添了永往直前的信心和勇气。

前面的教程我们领略了 Zynq7000 SOC 风采,熟悉了整个开収流程,但没有太多结合实

际应用的例子,这部课程给大家带来一些更深入的体验。 主要讲解 vivado 的调试技巧,sdk

的调试技巧,还有一些模块,像液晶屏、摄像头的使用。

“播下一粒种子,收获一片森林”,更是黑金 ALINX 硬件开収的美好愿望,同时我们会在

黑金动力社区 http://www.heijin.org 和大家一起讨论,一起学习,一起迚步,一起成长。

Page 4: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 4

ALINX 黑金 Zynq7000 开发平台配套教程第二部

目录

序 ............................................................................................................................................................. 3

目录 ......................................................................................................................................................... 4

第 1 章 AX7010/AX7020 PL 读写叏 PS 端的 DDR 数据 ................................................................. 6

1.1 ZYNQ 的 HP 端口的使用....................................................................................................... 6

1.2 PL 端 AXI Master ................................................................................................................... 9

1.3 ddr 读写数据的校验 ............................................................................................................. 18

1.4 vivado 软件的调试技巧 ....................................................................................................... 21

1.5 上电验证 ................................................................................................................................ 25

1.6 本章小结 ................................................................................................................................ 29

第 2 章 ZYNQ 下使用 uC/OS-III ....................................................................................................... 30

2.1 uC/OS-III 的硬件系统配置 .................................................................................................. 30

2.2 uC/OS-III BSP 配置 ............................................................................................................. 30

2.3 上板运行................................................................................................................................ 34

2.3 本章小结................................................................................................................................ 41

第 3 章 OV5640 模块的使用.............................................................................................................. 42

3.1 OV5640 简介 ........................................................................................................................ 42

3.2 VDMA 的使用 ....................................................................................................................... 42

3.3 硬件工程建立 ........................................................................................................................ 47

3.4 板上验证................................................................................................................................ 52

3.5 本章小结................................................................................................................................ 54

第 4 章 双目摄像头模块的使用 ......................................................................................................... 55

4.1 双目和单目摄像头开収的区别 ............................................................................................ 55

4.2 硬件环境搭建 ........................................................................................................................ 56

4.3 软件 SDK 的编写 .................................................................................................................. 63

4.4 板上验证................................................................................................................................ 65

第 5 章 7 寸液晶屏模块的使用 .......................................................................................................... 69

5.1 7 寸 LCD 屏模块说明介绍 ................................................................................................... 69

5.2 LCD 屏的驱动时序 ................................................................................................................ 70

5.3 zynq 的硬件系统设计 .......................................................................................................... 72

5.4 板上验证................................................................................................................................ 75

第 6 章 7 寸触摸屏的使用.................................................................................................................. 77

6.1 7 寸 LCD 触摸屏说明介绍 ................................................................................................... 77

6.2 触摸屏接口时序 .................................................................................................................... 78

Page 5: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 5

ALINX 黑金 Zynq7000 开发平台配套教程第二部

6.3 uGUI 的使用 .......................................................................................................................... 79

第 7 章 裸机文件系统 FatFS 的使用 ................................................................................................. 80

7.1 ................................................................................................................................................. 80

7.2 ................................................................................................................................................. 80

7.3 ................................................................................................................................................. 80

7.4 ................................................................................................................................................. 80

第 8 章 开源 TCP/IP 协议栈 Lwip 的使用 ........................................................................................ 81

8.1 ................................................................................................................................................. 81

8.2 ................................................................................................................................................. 81

8.3 ................................................................................................................................................. 81

第 9 章 Linux 下无驱动直接使用 PL 端设备自定义 IP RTC........................................................... 82

9.1 Vivado 工程创建 .................................................................................................................. 82

9.2 ZYNQ 系统的配置 ................................................................................................................ 82

9.3 硬件导入 SDK ....................................................................................................................... 82

Page 6: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 6

ALINX 黑金 Zynq7000 开发平台配套教程第二部

第 1 章 AX7010/AX7020 PL 读写叏 PS 端的 DDR 数据

PL 和 PS 的高效交互是 zynq 7000 soc 开収的重中之重,我们常常需要将 PL 端的大量数

据实时送到 PS 端处理,戒者将 PS 端处理结果实时送到 PL 端处理,常规我们会想到使用 DMA

的方式来迚行,但是各种协议非常麻烦,灵活性也比较差,本节课程讲解如何直接通过 AXI 总

线来读写 PS 端 ddr 的数据,这里面涉及到 AXI4 协议,vivado 的 FPGA 调试等。

1.1 ZYNQ 的 HP 端口的使用

zynq 7000 SOC 的 HP 口是 High-Performance Ports 的缩写,如下图所示,一共有 4

个 HP 口,HP 口是 AXI Slave 设备,我们可以通过这 4 个 HP 口完成高带宽的数据交互。

在 vivado 的界面中 HP 的配置如下图,这里面有使能控制,数据位宽选择,可选择 32 戒

64bit 的位宽。

Page 7: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 7

ALINX 黑金 Zynq7000 开发平台配套教程第二部

我们的实验启用 HP0 和 HP1 分别配置为 64bit 位宽,使用的时钟是 150Mhz,每个 HP

的带宽是 150Mhz * 64bit,对于视频处理,ADC 数据采集等应用都有足够的带宽。如下图所

示,配置完 HP 端口以后,zynq 会多出两个 AXI Slave 端口,名称分别为 S_AXI_HP0 和

S_AXI_HP1,丌过这些端口都是 AXI3 标准的,我们常用的是 AXI4 协议,这里添加 2 个 AXI

Interconnect IP,用于协议转换。这 2 个 HP 端口都是可读写的,但是为了方便和读写效率,

这里将 HP0 设置为只写,HP1 只读,同时我们将这 2 个 AXI4 接口引出,用于 PL 端操作。

Page 8: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 8

ALINX 黑金 Zynq7000 开发平台配套教程第二部

写接口的配置

写接口的配置

Page 9: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 9

ALINX 黑金 Zynq7000 开发平台配套教程第二部

读接口配置

1.2 PL 端 AXI Master

AXI4 相对复杂,但 SOC 开収者必须掌握,对于 zynq 的开収者,笔者建议能够在一些已

有的模板代码基础上修改。AXI 协议的具体内容可参考 Xilinx UG761 AXI Reference Guide。

在这里我们简单了解一下。

AXI4 所采用的是一种 READY,VALID 握手通信机制,即主从模块迚行数据通信前,新根

据操作对各所用到的数据、地址通道迚行握手。主要操作包括传输収送者 A 等到传输接叐者 B

的 READY 信号后,A 将数据不 VALID 信号同时収送给 B,这是一种典型的握手机制。

Page 10: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 10

ALINX 黑金 Zynq7000 开发平台配套教程第二部

AXI 总线分为五个通道:

读地址通道,包含 ARVALID, ARADDR, ARREADY 信号;

写地址通道,包含 AWVALID,AWADDR, AWREADY 信号;

读数据通道,包含 RVALID, RDATA, RREADY, RRESP 信号;

写数据通道,包含 WVALID, WDATA,WSTRB, WREADY 信号;

写应答通道,包含 BVALID, BRESP, BREADY 信号;

系统通道,包含:ACLK,ARESETN 信号;

其中 ACLK 为 axi 总线时钟,ARESETN 是 axi 总线复位信号,低电平有效;读写数据不读

写地址类信号宽度都为 32bit;READY 不 VALID 是对应的通道握手信号;WSTRB 信号为 1 的

bit 对应 WDATA 有效数据字节,WSTRB 宽度是 32bit/8=4bit;BRESP 不 RRESP 分别为写回

应信号,读回应信号,宽度都为 2bit,‘h0代表成功,其他为错误。

读操作顺序为主不从迚行读地址通道握手幵传输地址内容,然后在读数据通道握手幵传输

所读内容以及读叏操作的回应,时钟上升沿有效。如图所示:

写操作顺序为主不从迚行写地址通道握手幵传输地址内容,然后在写数据通道握手幵传输

所读内容,最后再写回应通道握手,幵传输写回应数据,时钟上升沿有效。如图所示:

Page 11: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 11

ALINX 黑金 Zynq7000 开发平台配套教程第二部

在我们丌擅长写 FPGA 的一些代码时我们往往要借鉴别人的代码戒者使用 IP core。在这里

笔者从 github 上找到一个 AXI master 的代码,地址是

https://github.com/aquaxis/IPCORE/tree/master/aq_axi_vdma。这个工程是一个自己写的

VDMA,里面包含了大量可参考的代码。笔者这里主要使用了 aq_axi_master.v 这个代码用于

AXI master 读写操作。借鉴别人代码有时会节省很多时间,但如果丌能理解的去借鉴,出现问

题了很难解决。aq_axi_master.v 代码如下,有部分修改。

/*

* Copyright (C)2014-2015 AQUAXIS TECHNOLOGY.

* Don't remove this header.

* When you use this source, there is a need to inherit this header.

*

* License

* For no commercial -

* License: The Open Software License 3.0

* License URI: http://www.opensource.org/licenses/OSL-3.0

*

* For commmercial -

* License: AQUAXIS License 1.0

* License URI: http://www.aquaxis.com/licenses

*

* For further information please contact.

* URI: http://www.aquaxis.com/

* E-Mail: info(at)aquaxis.com

*/

////////////////////////////////////////////////////////////////////////

//////////

// Company: ALINX黑金

// Engineer: 老梅

//

// Create Date: 2016/11/17 10:27:06

// Design Name:

// Module Name: mem_test

// Project Name:

Page 12: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 12

ALINX 黑金 Zynq7000 开发平台配套教程第二部

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

////////////////////////////////////////////////////////////////////////

//////////

module aq_axi_master(

// Reset, Clock

input ARESETN,

input ACLK,

// Master Write Address

output [0:0] M_AXI_AWID,

output [31:0] M_AXI_AWADDR,

output [7:0] M_AXI_AWLEN, // Burst Length: 0-255

output [2:0] M_AXI_AWSIZE, // Burst Size: Fixed 2'b011

output [1:0] M_AXI_AWBURST, // Burst Type: Fixed 2'b01(Incremental

Burst)

output M_AXI_AWLOCK, // Lock: Fixed 2'b00

output [3:0] M_AXI_AWCACHE, // Cache: Fiex 2'b0011

output [2:0] M_AXI_AWPROT, // Protect: Fixed 2'b000

output [3:0] M_AXI_AWQOS, // QoS: Fixed 2'b0000

output [0:0] M_AXI_AWUSER, // User: Fixed 32'd0

output M_AXI_AWVALID,

input M_AXI_AWREADY,

// Master Write Data

output [63:0] M_AXI_WDATA,

output [7:0] M_AXI_WSTRB,

output M_AXI_WLAST,

output [0:0] M_AXI_WUSER,

output M_AXI_WVALID,

input M_AXI_WREADY,

// Master Write Response

input [0:0] M_AXI_BID,

input [1:0] M_AXI_BRESP,

input [0:0] M_AXI_BUSER,

input M_AXI_BVALID,

output M_AXI_BREADY,

// Master Read Address

output [0:0] M_AXI_ARID,

output [31:0] M_AXI_ARADDR,

output [7:0] M_AXI_ARLEN,

output [2:0] M_AXI_ARSIZE,

output [1:0] M_AXI_ARBURST,

output [1:0] M_AXI_ARLOCK,

output [3:0] M_AXI_ARCACHE,

output [2:0] M_AXI_ARPROT,

output [3:0] M_AXI_ARQOS,

output [0:0] M_AXI_ARUSER,

output M_AXI_ARVALID,

input M_AXI_ARREADY,

Page 13: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 13

ALINX 黑金 Zynq7000 开发平台配套教程第二部

// Master Read Data

input [0:0] M_AXI_RID,

input [63:0] M_AXI_RDATA,

input [1:0] M_AXI_RRESP,

input M_AXI_RLAST,

input [0:0] M_AXI_RUSER,

input M_AXI_RVALID,

output M_AXI_RREADY,

// Local Bus

input MASTER_RST,

input WR_START,

input [31:0] WR_ADRS,

input [31:0] WR_LEN,

output WR_READY,

output WR_FIFO_RE,

input WR_FIFO_EMPTY,

input WR_FIFO_AEMPTY,

input [63:0] WR_FIFO_DATA,

output WR_DONE,

input RD_START,

input [31:0] RD_ADRS,

input [31:0] RD_LEN,

output RD_READY,

output RD_FIFO_WE,

input RD_FIFO_FULL,

input RD_FIFO_AFULL,

output [63:0] RD_FIFO_DATA,

output RD_DONE,

output [31:0] DEBUG

);

localparam S_WR_IDLE = 3'd0;

localparam S_WA_WAIT = 3'd1;

localparam S_WA_START = 3'd2;

localparam S_WD_WAIT = 3'd3;

localparam S_WD_PROC = 3'd4;

localparam S_WR_WAIT = 3'd5;

localparam S_WR_DONE = 3'd6;

reg [2:0] wr_state;

reg [31:0] reg_wr_adrs;

reg [31:0] reg_wr_len;

reg reg_awvalid, reg_wvalid, reg_w_last;

reg [7:0] reg_w_len;

reg [7:0] reg_w_stb;

reg [1:0] reg_wr_status;

reg [3:0] reg_w_count, reg_r_count;

reg [7:0] rd_chkdata, wr_chkdata;

reg [1:0] resp;

reg rd_first_data;

reg rd_fifo_enable;

reg[31:0] rd_fifo_cnt;

assign WR_DONE = (wr_state == S_WR_DONE);

Page 14: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 14

ALINX 黑金 Zynq7000 开发平台配套教程第二部

assign WR_FIFO_RE = rd_first_data | (reg_wvalid & ~WR_FIFO_EMPTY &

M_AXI_WREADY & rd_fifo_enable);

//assign WR_FIFO_RE = reg_wvalid & ~WR_FIFO_EMPTY & M_AXI_WREADY;

always @(posedge ACLK or negedge ARESETN)

begin

if(!ARESETN)

rd_fifo_cnt <= 32'd0;

else if(WR_FIFO_RE)

rd_fifo_cnt <= rd_fifo_cnt + 32'd1;

else if(wr_state == S_WR_IDLE)

rd_fifo_cnt <= 32'd0;

end

always @(posedge ACLK or negedge ARESETN)

begin

if(!ARESETN)

rd_fifo_enable <= 1'b0;

else if(wr_state == S_WR_IDLE && WR_START)

rd_fifo_enable <= 1'b1;

else if(WR_FIFO_RE && (rd_fifo_cnt == RD_LEN[31:3] - 32'd1) )

rd_fifo_enable <= 1'b0;

end

// Write State

always @(posedge ACLK or negedge ARESETN) begin

if(!ARESETN) begin

wr_state <= S_WR_IDLE;

reg_wr_adrs[31:0] <= 32'd0;

reg_wr_len[31:0] <= 32'd0;

reg_awvalid <= 1'b0;

reg_wvalid <= 1'b0;

reg_w_last <= 1'b0;

reg_w_len[7:0] <= 8'd0;

reg_w_stb[7:0] <= 8'd0;

reg_wr_status[1:0] <= 2'd0;

reg_w_count[3:0] <= 4'd0;

reg_r_count[3:0] <= 4'd0;

wr_chkdata <= 8'd0;

rd_chkdata <= 8'd0;

resp <= 2'd0;

rd_first_data <= 1'b0;

end else begin

if(MASTER_RST) begin

wr_state <= S_WR_IDLE;

end else begin

case(wr_state)

S_WR_IDLE: begin

if(WR_START) begin

wr_state <= S_WA_WAIT;

reg_wr_adrs[31:0] <= WR_ADRS[31:0];

reg_wr_len[31:0] <= WR_LEN[31:0] -32'd1;

rd_first_data <= 1'b1;

end

reg_awvalid <= 1'b0;

reg_wvalid <= 1'b0;

reg_w_last <= 1'b0;

reg_w_len[7:0] <= 8'd0;

reg_w_stb[7:0] <= 8'd0;

reg_wr_status[1:0] <= 2'd0;

end

S_WA_WAIT: begin

if(!WR_FIFO_AEMPTY | (reg_wr_len[31:11] == 21'd0)) begin

Page 15: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 15

ALINX 黑金 Zynq7000 开发平台配套教程第二部

wr_state <= S_WA_START;

end

rd_first_data <= 1'b0;

end

S_WA_START: begin

wr_state <= S_WD_WAIT;

reg_awvalid <= 1'b1;

reg_wr_len[31:11] <= reg_wr_len[31:11] - 21'd1;

if(reg_wr_len[31:11] != 21'd0) begin

reg_w_len[7:0] <= 8'hFF;

reg_w_last <= 1'b0;

reg_w_stb[7:0] <= 8'hFF;

end else begin

reg_w_len[7:0] <= reg_wr_len[10:3];

reg_w_last <= 1'b1;

reg_w_stb[7:0] <= 8'hFF;

/*

case(reg_wr_len[2:0]) begin

case 3'd0: reg_w_stb[7:0] <= 8'b0000_0000;

case 3'd1: reg_w_stb[7:0] <= 8'b0000_0001;

case 3'd2: reg_w_stb[7:0] <= 8'b0000_0011;

case 3'd3: reg_w_stb[7:0] <= 8'b0000_0111;

case 3'd4: reg_w_stb[7:0] <= 8'b0000_1111;

case 3'd5: reg_w_stb[7:0] <= 8'b0001_1111;

case 3'd6: reg_w_stb[7:0] <= 8'b0011_1111;

case 3'd7: reg_w_stb[7:0] <= 8'b0111_1111;

default: reg_w_stb[7:0] <= 8'b1111_1111;

endcase

*/

end

end

S_WD_WAIT: begin

if(M_AXI_AWREADY) begin

wr_state <= S_WD_PROC;

reg_awvalid <= 1'b0;

reg_wvalid <= 1'b1;

end

end

S_WD_PROC: begin

if(M_AXI_WREADY & ~WR_FIFO_EMPTY) begin

if(reg_w_len[7:0] == 8'd0) begin

wr_state <= S_WR_WAIT;

reg_wvalid <= 1'b0;

reg_w_stb[7:0] <= 8'h00;

end else begin

reg_w_len[7:0] <= reg_w_len[7:0] -8'd1;

end

end

end

S_WR_WAIT: begin

if(M_AXI_BVALID) begin

reg_wr_status[1:0] <= reg_wr_status[1:0] | M_AXI_BRESP[1:0];

if(reg_w_last) begin

wr_state <= S_WR_DONE;

end else begin

wr_state <= S_WA_WAIT;

reg_wr_adrs[31:0] <= reg_wr_adrs[31:0] + 32'd2048;

end

end

end

S_WR_DONE: begin

Page 16: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 16

ALINX 黑金 Zynq7000 开发平台配套教程第二部

wr_state <= S_WR_IDLE;

end

default: begin

wr_state <= S_WR_IDLE;

end

endcase

/*

if(WR_FIFO_RE) begin

reg_w_count[3:0] <= reg_w_count[3:0] + 4'd1;

end

if(RD_FIFO_WE)begin

reg_r_count[3:0] <= reg_r_count[3:0] + 4'd1;

end

if(M_AXI_AWREADY & M_AXI_AWVALID) begin

wr_chkdata <= 8'hEE;

end else if(M_AXI_WSTRB[7] & M_AXI_WVALID) begin

wr_chkdata <= WR_FIFO_DATA[63:56];

end

if(M_AXI_AWREADY & M_AXI_AWVALID) begin

rd_chkdata <= 8'hDD;

end else if(M_AXI_WSTRB[7] & M_AXI_WREADY) begin

rd_chkdata <= WR_FIFO_DATA[63:56];

end

if(M_AXI_BVALID & M_AXI_BREADY) begin

resp <= M_AXI_BRESP;

end

*/

end

end

end

assign M_AXI_AWID = 1'b0;

assign M_AXI_AWADDR[31:0] = reg_wr_adrs[31:0];

assign M_AXI_AWLEN[7:0] = reg_w_len[7:0];

assign M_AXI_AWSIZE[2:0] = 2'b011;

assign M_AXI_AWBURST[1:0] = 2'b01;

assign M_AXI_AWLOCK = 1'b0;

assign M_AXI_AWCACHE[3:0] = 4'b0011;

assign M_AXI_AWPROT[2:0] = 3'b000;

assign M_AXI_AWQOS[3:0] = 4'b0000;

assign M_AXI_AWUSER[0] = 1'b1;

assign M_AXI_AWVALID = reg_awvalid;

assign M_AXI_WDATA[63:0] = WR_FIFO_DATA[63:0];

// assign M_AXI_WSTRB[7:0] = (reg_w_len[7:0] ==

8'd0)?reg_w_stb[7:0]:8'hFF;

// assign M_AXI_WSTRB[7:0] = (wr_state == S_WD_PROC)?8'hFF:8'h00;

assign M_AXI_WSTRB[7:0] = (reg_wvalid & ~WR_FIFO_EMPTY)?8'hFF:8'h00;

assign M_AXI_WLAST = (reg_w_len[7:0] == 8'd0)?1'b1:1'b0;

assign M_AXI_WUSER = 1;

assign M_AXI_WVALID = reg_wvalid & ~WR_FIFO_EMPTY;

// assign M_AXI_WVALID = (wr_state == S_WD_PROC)?1'b1:1'b0;

assign M_AXI_BREADY = M_AXI_BVALID;

assign WR_READY = (wr_state == S_WR_IDLE)?1'b1:1'b0;

// assign WR_FIFO_RE = (wr_state == S_WD_PROC)?M_AXI_WREADY:1'b0;

localparam S_RD_IDLE = 3'd0;

Page 17: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 17

ALINX 黑金 Zynq7000 开发平台配套教程第二部

localparam S_RA_WAIT = 3'd1;

localparam S_RA_START = 3'd2;

localparam S_RD_WAIT = 3'd3;

localparam S_RD_PROC = 3'd4;

localparam S_RD_DONE = 3'd5;

reg [2:0] rd_state;

reg [31:0] reg_rd_adrs;

reg [31:0] reg_rd_len;

reg reg_arvalid, reg_r_last;

reg [7:0] reg_r_len;

assign RD_DONE = (rd_state == S_RD_DONE) ;

// Read State

always @(posedge ACLK or negedge ARESETN) begin

if(!ARESETN) begin

rd_state <= S_RD_IDLE;

reg_rd_adrs[31:0] <= 32'd0;

reg_rd_len[31:0] <= 32'd0;

reg_arvalid <= 1'b0;

reg_r_len[7:0] <= 8'd0;

end else begin

case(rd_state)

S_RD_IDLE: begin

if(RD_START) begin

rd_state <= S_RA_WAIT;

reg_rd_adrs[31:0] <= RD_ADRS[31:0];

reg_rd_len[31:0] <= RD_LEN[31:0] -32'd1;

end

reg_arvalid <= 1'b0;

reg_r_len[7:0] <= 8'd0;

end

S_RA_WAIT: begin

if(~RD_FIFO_AFULL) begin

rd_state <= S_RA_START;

end

end

S_RA_START: begin

rd_state <= S_RD_WAIT;

reg_arvalid <= 1'b1;

reg_rd_len[31:11] <= reg_rd_len[31:11] -21'd1;

if(reg_rd_len[31:11] != 21'd0) begin

reg_r_last <= 1'b0;

reg_r_len[7:0] <= 8'd255;

end else begin

reg_r_last <= 1'b1;

reg_r_len[7:0] <= reg_rd_len[10:3];

end

end

S_RD_WAIT: begin

if(M_AXI_ARREADY) begin

rd_state <= S_RD_PROC;

reg_arvalid <= 1'b0;

end

end

S_RD_PROC: begin

if(M_AXI_RVALID) begin

if(M_AXI_RLAST) begin

if(reg_r_last) begin

rd_state <= S_RD_DONE;

end else begin

rd_state <= S_RA_WAIT;

Page 18: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 18

ALINX 黑金 Zynq7000 开发平台配套教程第二部

reg_rd_adrs[31:0] <= reg_rd_adrs[31:0] + 32'd2048;

end

end else begin

reg_r_len[7:0] <= reg_r_len[7:0] -8'd1;

end

end

end

S_RD_DONE:begin

rd_state <= S_RD_IDLE;

end

endcase

end

end

// Master Read Address

assign M_AXI_ARID = 1'b0;

assign M_AXI_ARADDR[31:0] = reg_rd_adrs[31:0];

assign M_AXI_ARLEN[7:0] = reg_r_len[7:0];

assign M_AXI_ARSIZE[2:0] = 3'b011;

assign M_AXI_ARBURST[1:0] = 2'b01;

assign M_AXI_ARLOCK = 1'b0;

assign M_AXI_ARCACHE[3:0] = 4'b0011;

assign M_AXI_ARPROT[2:0] = 3'b000;

assign M_AXI_ARQOS[3:0] = 4'b0000;

assign M_AXI_ARUSER[0] = 1'b1;

assign M_AXI_ARVALID = reg_arvalid;

assign M_AXI_RREADY = M_AXI_RVALID & ~RD_FIFO_FULL;

assign RD_READY = (rd_state == S_RD_IDLE)?1'b1:1'b0;

assign RD_FIFO_WE = M_AXI_RVALID;

assign RD_FIFO_DATA[63:0] = M_AXI_RDATA[63:0];

assign DEBUG[31:0] = {reg_wr_len[31:8],

1'd0, wr_state[2:0], 1'd0, rd_state[2:0]};

endmodule

1.3 ddr 读写数据的校验

有了 AXI Master 读写接口以后比较编写了一个简单的验证模块,这个验证模块以前是用

来验证 ddr ip 的,通过每 8bit 写入以后逑增的数据,然后读叏出来比较。这里要注意的是 PS

端 DDR 的起始地址和大小,还有地址的单位是 byte 还是 word,AXI 总线的地址单位是 byte,

测试模块的地址单位是 word(这里的 word 丌一定是 4byte)。文件名 mem_test.v,代码如

下:

////////////////////////////////////////////////////////////////////////

//////////

// Company: ALINX黑金

Page 19: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 19

ALINX 黑金 Zynq7000 开发平台配套教程第二部

// Engineer: 老梅

//

// Create Date: 2016/11/17 10:27:06

// Design Name:

// Module Name: mem_test

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

////////////////////////////////////////////////////////////////////////

//////////

module mem_test

#(

parameter MEM_DATA_BITS = 64,

parameter ADDR_BITS = 32

)

(

input rst, /*复位*/

input mem_clk, /*接口时钟*/

output reg rd_burst_req, /*读请求*/

output reg wr_burst_req, /*写请求*/

output reg[9:0] rd_burst_len, /*读数据长度*/

output reg[9:0] wr_burst_len, /*写数据长度*/

output reg[ADDR_BITS - 1:0] rd_burst_addr, /*读首地址*/

output reg[ADDR_BITS - 1:0] wr_burst_addr, /*写首地址*/

input rd_burst_data_valid, /*读出数据有效*/

input wr_burst_data_req, /*写数据信号*/

input[MEM_DATA_BITS - 1:0] rd_burst_data, /*读出的数据*/

output[MEM_DATA_BITS - 1:0] wr_burst_data, /*写入的数据*/

input rd_burst_finish, /*读完成*/

input wr_burst_finish, /*写完成*/

output reg error

);

parameter IDLE = 3'd0;

parameter MEM_READ = 3'd1;

parameter MEM_WRITE = 3'd2;

parameter BURST_LEN = 128;

(*mark_debug="true"*)reg[2:0] state;

(*mark_debug="true"*)reg[7:0] wr_cnt;

reg[MEM_DATA_BITS - 1:0] wr_burst_data_reg;

assign wr_burst_data = wr_burst_data_reg;

(*mark_debug="true"*)reg[7:0] rd_cnt;

reg[31:0] write_read_len;

//assign error = (state == MEM_READ) && rd_burst_data_valid &&

(rd_burst_data != {(MEM_DATA_BITS/8){rd_cnt}});

always@(posedge mem_clk or posedge rst)

begin

if(rst)

error <= 1'b0;

Page 20: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 20

ALINX 黑金 Zynq7000 开发平台配套教程第二部

else if(state == MEM_READ && rd_burst_data_valid && rd_burst_data !=

{(MEM_DATA_BITS/8){rd_cnt}})

error <= 1'b1;

end

always@(posedge mem_clk or posedge rst)

begin

if(rst)

begin

wr_burst_data_reg <= {MEM_DATA_BITS{1'b0}};

wr_cnt <= 8'd0;

end

else if(state == MEM_WRITE)

begin

if(wr_burst_data_req)

begin

wr_burst_data_reg <= {(MEM_DATA_BITS/8){wr_cnt}};

wr_cnt <= wr_cnt + 8'd1;

end

else if(wr_burst_finish)

wr_cnt <= 8'd0;

end

end

always@(posedge mem_clk or posedge rst)

begin

if(rst)

begin

rd_cnt <= 8'd0;

end

else if(state == MEM_READ)

begin

if(rd_burst_data_valid)

begin

rd_cnt <= rd_cnt + 8'd1;

end

else if(rd_burst_finish)

rd_cnt <= 8'd0;

end

else

rd_cnt <= 8'd0;

end

always@(posedge mem_clk or posedge rst)

begin

if(rst)

begin

state <= IDLE;

wr_burst_req <= 1'b0;

rd_burst_req <= 1'b0;

rd_burst_len <= BURST_LEN;

wr_burst_len <= BURST_LEN;

rd_burst_addr <= 0;

wr_burst_addr <= 0;

write_read_len <= 32'd0;

end

else

begin

case(state)

IDLE:

begin

state <= MEM_WRITE;

Page 21: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 21

ALINX 黑金 Zynq7000 开发平台配套教程第二部

wr_burst_req <= 1'b1;

wr_burst_len <= BURST_LEN;

wr_burst_addr <='h20000;

write_read_len <= 32'd0;

end

MEM_WRITE:

begin

if(wr_burst_finish)

begin

state <= MEM_READ;

wr_burst_req <= 1'b0;

rd_burst_req <= 1'b1;

rd_burst_len <= BURST_LEN;

rd_burst_addr <= wr_burst_addr;

write_read_len <= write_read_len + BURST_LEN;

end

end

MEM_READ:

begin

if(rd_burst_finish)

begin

if(write_read_len == 32'h3fe_0000)

begin

rd_burst_req <= 1'b0;

state <= IDLE;

end

else

begin

state <= MEM_WRITE;

wr_burst_req <= 1'b1;

wr_burst_len <= BURST_LEN;

rd_burst_req <= 1'b0;

wr_burst_addr <= wr_burst_addr + BURST_LEN;

end

end

end

default:

state <= IDLE;

endcase

end

end

endmodule

1.4 vivado 软件的调试技巧

AXI 读写验证模块只有一个 error 信号用于指示错误,如果有数据错误我们希望能更精确

的信息,altera 的 quartus II 软件中有 signal tap 工具,xilinx 的 ISE 中有 chipscope 工具,

这些都是嵌入式逻辑分析仪,对我们调试有很大帮助,在 vivado 开収板软件中调试更加方便。

如下图所示点击 Set Up Debug 可直接迚入调试配置界面。

Page 22: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 22

ALINX 黑金 Zynq7000 开发平台配套教程第二部

Page 23: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 23

ALINX 黑金 Zynq7000 开发平台配套教程第二部

插入调试信号

在插入调试信号时有些信息可能会被优化掉,戒者信号名称改发了就丌容易识别,这个时

候我们可以加入*mark_debug="true"*这样的属性,加入以后在 Set Up Debug 的时候会自动

添加迚去,幵丏信号名称丌会改发。需要注意的是信号时钟域的选择,软件会自动推断信号的

Page 24: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 24

ALINX 黑金 Zynq7000 开发平台配套教程第二部

时钟域,如果软件无法推断戒者自己想改发采样时钟域的时候,可以右键选择时钟。

采样深度的设置,这里可根据实际需要设置采样深度,设置的太大会导致编译缓慢戒者

block ram 丌够导致无法编译通过。Input pipe stages 默认是 0,这里建议大家设置为 1 戒 2,

这样更有利于提高时钟频率。

采样深度的设置

Set Up Debug 完成以后软件会在约束文件里自动添加一部分代码,如下图所示,如果调

试完毕,可删除这部分代码,可节省 FPGA 资源。在非常熟练的情冴下我们可自己添加这样的

代码建立 debug 过程。

Page 25: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 25

ALINX 黑金 Zynq7000 开发平台配套教程第二部

Set Up Debug 自动插入的代码

1.5 上电验证

生成 bit 文件后导出到 SDK,运行 SDK,如下图所示。因为工程移动位置后 SDK 找丌到

硬件信息,所以又重新了一个硬件平台,top_hw_platform_1,这里的 top_hw_platform_0,

是笔者调试时产生的。大家可以直接删除,同时将文件也删除,删除以后可将留下

top_hw_platform_1 改名为 top_hw_platform_0。我们在 SDK 里建立了一个 helloworld 程

序,虽然我们仅仅测试 PL 端读叏 PS 端 DDR,但是 PS 如果丌工作起来,DDR 控制器也是没

有工作的,所以这个简单的 helloword 程序就是为了让 DDR 控制器工作起来。我们配置运行

选项,如下图所示:

Page 26: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 26

ALINX 黑金 Zynq7000 开发平台配套教程第二部

启动运行选项的配置

Page 27: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 27

ALINX 黑金 Zynq7000 开发平台配套教程第二部

运行配置

点击运行后系统会复位幵丏下载 FPGA 的 bit 文件。然后回到 vivado 界面点击 Program

and Debug 栉自动连接目标如下图所示:

Page 28: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 28

ALINX 黑金 Zynq7000 开发平台配套教程第二部

自动连接硬件

自动连接硬件后可収现 JTAG 连上的设备,其中有一个 hw_ila_1 的设备,这个设备就是我

们 debug 设备,选中后可点击上方黄色三角按钮捕捉波形。如果有些信号没有显示完整,可点

击波形旁边的“+”按钮添加。

点击捕获波形以后如下图所示,如果 error 一直为低,幵丏读写状态有发化,说明读写 DDR

Page 29: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 29

ALINX 黑金 Zynq7000 开发平台配套教程第二部

数据正常。

1.6 本章小结

zynq 系统相对于单个 FPGA 戒单个 ARM 要复杂很大,对开収者的基础知识要求较高,本

章内容涉及到 AXI 协议、zynq 的互联资源、vivado 的和 sdk 的调试技巧。这些都仅仅是基础

知识,笔者在这里也仅仅是抛砖引玉,大家还是要多多练习,在丌断练习中掌握技巧。

Page 30: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 30

ALINX 黑金 Zynq7000 开发平台配套教程第二部

第 2 章 ZYNQ 下使用 uC/OS-III

学习 ZYNQ,很大一部分都是 FPGA 开収人员,丌太擅长使用 Linux,所以我建议大家还

是先使用实时操作系统戒者裸机运行,这样也有更大的灵活性。本章给大家讲解如何搭建

uC/OS-III 实时操作系统运行环境,这里丌深入探讨 uC/OS-III 的具体使用。本章内容参考来源

https://doc.micrium.com/display/UCOSXSDK/uCOS+BSP+on+the+Zynq-7000+Tutori

al#uCOSBSPontheZynq-7000Tutorial-Figure-VivadoStartPage

2.1 uC/OS-III 的硬件系统配置

由于我们的 uC/OS-III 是使用第三方软件库,这个库要求有 2 个 AXI timer,硬件系统中

必须添加这样的两个 IP。幵丏中断和 zynq 的中断系统相连。整个硬件系统图如下:

2.2 uC/OS-III BSP 配置

生成 FPGA 的 bit 文件,然后导出硬件,运行 SDK。在 SDK 下点击 Xilinx Tools ->

Repositories,如下图。

Page 31: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 31

ALINX 黑金 Zynq7000 开发平台配套教程第二部

点击 New... 选择我们提供的 ucos_v1_41 文件夹,然后点击 OK,如下图。

在SDK下File -> New -> Application Project 新建一个基于ucos的应用程序,如下图。

Page 32: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 32

ALINX 黑金 Zynq7000 开发平台配套教程第二部

选择一个 Micrium uC/OS-III Hello World 模板,同时我们也可以看到有很多其他很有用

的模板可以供我们选择,如下图。

Page 33: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 33

ALINX 黑金 Zynq7000 开发平台配套教程第二部

修改 BSP 设置,首先设置标准输入输出设备,这里选择 ps7_uart_1,然后配置 axi_timer_1

的驱动为 tmrctr,然后点击 OK 重新生成 BSP。

Page 34: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 34

ALINX 黑金 Zynq7000 开发平台配套教程第二部

配置输入输出

配置 axi_timer_1 驱动

2.3 上板运行

和前面提到的一样,我们 run 之前配置一下,运行效果如下图。

Page 35: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 35

ALINX 黑金 Zynq7000 开发平台配套教程第二部

Page 36: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 36

ALINX 黑金 Zynq7000 开发平台配套教程第二部

在网站

https://doc.micrium.com/display/UCOSXSDK/uCOS+BSP+on+the+Zynq-7000+Tutori

al#uCOSBSPontheZynq-7000Tutorial-Figure-VivadoStartPage 上给出了一个 app.c,代码

如下:

/*

************************************************************************

*********************************

* TUTORIAL CODE

*

* (c) Copyright 2009-2014; Micrium, Inc.; Weston, FL

*

* All rights reserved. Protected by international copyright

laws.

*

* Please feel free to use any application code labeled as 'EXAMPLE

CODE' in

* your application products. Example code may be used as is,

in whole or in

* part, or may be used as a reference only.

*

* Please help us continue to provide the Embedded community with

the finest

* software available. Your honesty is greatly appreciated.

*

* You can contact us at www.micrium.com.

************************************************************************

*********************************

*/

Page 37: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 37

ALINX 黑金 Zynq7000 开发平台配套教程第二部

/*

************************************************************************

*********************************

* SETUP INSTRUCTIONS

*

* This demonstration project illustrate a basic uC/OS-III project with

simple "hello world" output.

*

* By default some configuration steps are required to compile this example :

*

* 1. Include the require Micrium software components

* In the BSP setting dialog in the "overview" section of the left pane

the following libraries

* should be added to the BSP :

*

* ucos_common

* ucos_osiii

* ucos_standalone

*

* 2. Kernel tick source - (Not required on the Zynq-7000 PS)

* If a suitable timer is available in your FPGA design it can be used

as the kernel tick source.

* To do so, in the "ucos" section select a timer for the "kernel_tick_src"

configuration option.

*

* 3. STDOUT configuration

* Output from the print() and UCOS_Print() functions can be redirected

to a supported UART. In

* the "ucos" section the stdout configuration will list the available

UARTs.

*

* Troubleshooting :

* By default the Xilinx SDK may not have selected the Micrium drivers

for the timer and UART.

* If that is the case they must be manually selected in the drivers

configuration section.

*

* Finally make sure the FPGA is programmed before debugging.

*

*

* Remember that this example is provided for evaluation purposes only.

Commercial development requires

* a valid license from Micrium.

************************************************************************

*********************************

*/

/*

************************************************************************

*********************************

* INCLUDE FILES

************************************************************************

*********************************

*/

#include <stdio.h>

#include <Source/os.h>

#include <ucos_bsp.h>

#include <ucos_axitimer.h>

#include <xtmrctr.h>

Page 38: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 38

ALINX 黑金 Zynq7000 开发平台配套教程第二部

#include <ucos_int.h>

void MainTask (void *p_arg);

void Timer0Task (void *p_arg);

OS_TCB Timer0TCB;

CPU_STK Timer0TaskStk[512];

void Timer1Task (void *p_arg);

OS_TCB Timer1TCB;

CPU_STK Timer1TaskStk[512];

OS_SEM Timer0Semaphore;

OS_SEM Timer1Semaphore;

AXITIMER_HANDLE Timer0;

void Timer0ISR (AXITIMER_HANDLE handle, CPU_INT32U tmr_nbr);

XTmrCtr Timer1;

void Timer1ISR (void *p_arg, CPU_INT32U cpu);

/*

************************************************************************

*********************************

* main()

*

* Description : Entry point for C code.

*

************************************************************************

*********************************

*/

int main()

{

UCOSStartup(MainTask);

return 0;

}

/*

************************************************************************

*********************************

* MainTask()

*

* Description : Startup task example code.

*

* Returns : none.

*

* Created by : main().

************************************************************************

*********************************

*/

void MainTask (void *p_arg)

{

OS_ERR os_err;

Page 39: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 39

ALINX 黑金 Zynq7000 开发平台配套教程第二部

UCOS_Print("Hello world from the main task\r\n");

OSSemCreate(&Timer0Semaphore, "Timer 0 Semaphore", 0, &os_err);

OSSemCreate(&Timer1Semaphore, "Timer 1 Semaphore", 0, &os_err);

OSTaskCreate(&Timer0TCB,

"Timer 0 Task",

Timer0Task,

DEF_NULL,

10,

Timer0TaskStk,

0,

512,

0,

0,

DEF_NULL,

0,

&os_err);

OSTaskCreate(&Timer1TCB,

"Timer 1 Task",

Timer1Task,

DEF_NULL,

10,

Timer1TaskStk,

0,

512,

0,

0,

DEF_NULL,

0,

&os_err);

Timer0 = AXITimer_Init(0);

AXITimer_OptSet(Timer0, 0, AXITIMER_OPT_DOWN | AXITIMER_OPT_AUTO_RELOAD

| AXITIMER_OPT_INT);

AXITimer_LoadSet(Timer0, 0, 100000000);

AXITimer_CallbackSet(Timer0, 0, Timer0ISR);

AXITimer_Start(Timer0, 0);

XTmrCtr_Initialize(&Timer1, 0);

XTmrCtr_SetOptions(&Timer1, 0, XTC_DOWN_COUNT_OPTION |

XTC_AUTO_RELOAD_OPTION | XTC_INT_MODE_OPTION);

XTmrCtr_SetResetValue(&Timer1, 0, 50000000);

UCOS_IntVectSet(62, 0, DEF_BIT_00, Timer1ISR, &Timer1);

UCOS_IntSrcEn(62);

XTmrCtr_Start(&Timer1, 0);

while (DEF_TRUE) {

OSTimeDlyHMSM(0, 0, 10, 0, OS_OPT_TIME_HMSM_STRICT, &os_err);

UCOS_Print("Periodic output every 10 seconds from the main task\r\n");

}

}

void Timer0Task (void *p_arg)

{

OS_ERR os_err;

Page 40: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 40

ALINX 黑金 Zynq7000 开发平台配套教程第二部

UCOS_Print("Timer0Task reached\r\n");

while (1) {

OSSemPend(&Timer0Semaphore, 0, 0, DEF_NULL, &os_err);

UCOS_Print("Timer 0 Semaphore signaled\r\n");

}

}

void Timer0ISR (AXITIMER_HANDLE handle, CPU_INT32U tmr_nbr)

{

OS_ERR os_err;

OSSemPost(&Timer0Semaphore, 0, &os_err);

}

void Timer1Task (void *p_arg)

{

OS_ERR os_err;

UCOS_Print("Timer1Task reached\r\n");

while (1) {

OSSemPend(&Timer1Semaphore, 0, 0, DEF_NULL, &os_err);

UCOS_Print("Timer 1 Semaphore signaled\r\n");

}

}

void Timer1ISR (void *p_arg, CPU_INT32U cpu)

{

CPU_INT32U ControlStatusReg;

OS_ERR os_err;

ControlStatusReg = XTmrCtr_ReadReg(Timer1.BaseAddress,

0,

XTC_TCSR_OFFSET);

XTmrCtr_WriteReg(Timer1.BaseAddress,

0,

XTC_TCSR_OFFSET,

ControlStatusReg |

XTC_CSR_INT_OCCURED_MASK);

OSSemPost(&Timer1Semaphore, 0, &os_err);

}

我们可以将这个 app.c 的内容复制到 SDK 里运行,效果如下图:

Page 41: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 41

ALINX 黑金 Zynq7000 开发平台配套教程第二部

2.3 本章小结

相对于复杂的 Linux,uC/OS-III 等实时操作系统给我们带来更灵活更方便的开収,可以更

直接的和底层 FPGA 迚行交互,但是 uC/OS-III 本身也有一点难度,要想熟练应用,还是要结

合具体的项目多加练习。

Page 42: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 42

ALINX 黑金 Zynq7000 开发平台配套教程第二部

第 3 章 OV5640 模块的使用

本章讲解 OV5640 模块的使用,使用的硬件是黑金双目摄像头模块。主要学习 vdma 视频

输入、AXI Stream 等,对基于 ZYNQ 的视频处理有个基本的了解。

3.1 OV5640 简介

图像传感器是摄像头的核心部件,黑金双目摄像头 AN5642 中的图像传感器是一款型号为

OV5640 的 CMOS 类型数字图像传感器。该传感器支持输出最大为 500 万像素的图

像 (2592x1944 分辨率),支持使用 VGA 时序输出图像数据,支持 DVP(DC)、MIPI 接口输出

图像的数据格式支持 YUV(422/420)、YCbCr422、RGB565、RAW 以及 JPEG 格式,若直接

输出 JPEG 格式的图像时可大大减少数据量,方便网络传输。它还可以对采集得的图像迚行补

偿,支持伽玛曲线、白平衡、饱和度、色度等基础处理。根据丌同的分辨率配置,传感器输出

图像数据的帧率从 15-60 帧可调,工作时功率在 150mW-200mW 之间。

OV5640 使用 SCCB 总线配置,SCCB 和 I2C 总线兼容,AN5642 使用 DVP 传输视频,

PCLK 为像素时钟,HREF 为行同步信号,当 HREF 为高时视频数据有效,VSYNC 为场同步信

号。数据线为 10Bit,我们的程序只使用其中的 8Bit。在黑金的 FPGA 开収板中我们常常配置

为 RGB565 输出,在黑金的与业视频处理板中配置为 YCbCr422,因为数据总线是 8Bit,所以

2 个时钟周期传输一个像素的数据,在 FPGA 接收端再拼接成完整的像素数据。

3.2 VDMA 的使用

在前面的课程中我们已经使用了 VDMA 迚行了 HDMI 的显示,VDMA 是 xilinx 的视频处

理中一个很关键的 IP,VDMA 是一个特殊的 DMA,针对视频处理做了特殊的设计。如下图所

示,我们看到 VDMA 有个 AXI4 Memory Map 接口,用于对存储器迚行读写视频数据,一个

AXI4-Lite 接口用于读叏 VDMA 状态以及配置 VDMA 的参数,还有 AXI4-Stream 接口,用于

视频的输入和输出。

Page 43: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 43

ALINX 黑金 Zynq7000 开发平台配套教程第二部

VDMA 的配置也是很重要的,笔者摘录了 VMDA 的寄存器,我们根据文档《AXI Video

Direct Memory Access v6.2》编写了简单的 VDMA 控制程序,如下所示:

Page 44: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 44

ALINX 黑金 Zynq7000 开发平台配套教程第二部

#include "xil_printf.h"

#include "vdma.h"

u32 vdma_version(XAxiVdma *Vdma) {

return XAxiVdma_GetVersion(Vdma);

}

int vdma_read_start(XAxiVdma *Vdma) {

int Status;

// MM2S Startup

Status = XAxiVdma_DmaStart(Vdma, XAXIVDMA_READ);

if (Status != XST_SUCCESS)

{

xil_printf("Start read transfer failed %d\n\r", Status);

return XST_FAILURE;

}

return XST_SUCCESS;

}

int vdma_read_stop(XAxiVdma *Vdma) {

XAxiVdma_DmaStop(Vdma, XAXIVDMA_READ);

return XST_SUCCESS;

}

int vdma_read_init(short DeviceID,short HoriSizeInput,short

VertSizeInput,short Stride,unsigned int FrameStoreStartAddr)

{

XAxiVdma Vdma;

XAxiVdma_Config *Config;

XAxiVdma_DmaSetup ReadCfg;

int Status;

Config = XAxiVdma_LookupConfig(DeviceID);

if (NULL == Config) {

xil_printf("XAxiVdma_LookupConfig failure\r\n");

return XST_FAILURE;

}

Status = XAxiVdma_CfgInitialize(&Vdma, Config, Config->BaseAddress);

if (Status != XST_SUCCESS) {

xil_printf("XAxiVdma_CfgInitialize failure\r\n");

return XST_FAILURE;

}

ReadCfg.EnableCircularBuf = 1;

ReadCfg.EnableFrameCounter = 0;

ReadCfg.FixedFrameStoreAddr = 0;

ReadCfg.EnableSync = 1;

ReadCfg.PointNum = 1;

ReadCfg.FrameDelay = 0;

Page 45: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 45

ALINX 黑金 Zynq7000 开发平台配套教程第二部

ReadCfg.VertSizeInput = VertSizeInput;

ReadCfg.HoriSizeInput = HoriSizeInput;

ReadCfg.Stride = Stride;

Status = XAxiVdma_DmaConfig(&Vdma, XAXIVDMA_READ, &ReadCfg);

if (Status != XST_SUCCESS) {

xdbg_printf(XDBG_DEBUG_ERROR,

"Read channel config failed %d\r\n", Status);

return XST_FAILURE;

}

ReadCfg.FrameStoreStartAddr[0] = FrameStoreStartAddr;

Status = XAxiVdma_DmaSetBufferAddr(&Vdma, XAXIVDMA_READ,

ReadCfg.FrameStoreStartAddr);

if (Status != XST_SUCCESS) {

xdbg_printf(XDBG_DEBUG_ERROR,"Read channel set buffer address

failed %d\r\n", Status);

return XST_FAILURE;

}

Status = vdma_read_start(&Vdma);

if (Status != XST_SUCCESS) {

xil_printf("error starting VDMA..!");

return Status;

}

return XST_SUCCESS;

}

int vdma_write_start(XAxiVdma *Vdma) {

int Status;

// MM2S Startup

Status = XAxiVdma_DmaStart(Vdma, XAXIVDMA_WRITE);

if (Status != XST_SUCCESS)

{

xil_printf("Start write transfer failed %d\n\r", Status);

return XST_FAILURE;

}

return XST_SUCCESS;

}

int vdma_write_stop(XAxiVdma *Vdma) {

XAxiVdma_DmaStop(Vdma, XAXIVDMA_WRITE);

return XST_SUCCESS;

}

int vdma_write_init(short DeviceID,short HoriSizeInput,short

VertSizeInput,short Stride,unsigned int FrameStoreStartAddr)

{

XAxiVdma Vdma;

XAxiVdma_Config *Config;

XAxiVdma_DmaSetup WriteCfg;

Page 46: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 46

ALINX 黑金 Zynq7000 开发平台配套教程第二部

int Status;

Config = XAxiVdma_LookupConfig(DeviceID);

if (NULL == Config) {

xil_printf("XAxiVdma_LookupConfig failure\r\n");

return XST_FAILURE;

}

Status = XAxiVdma_CfgInitialize(&Vdma, Config, Config->BaseAddress);

if (Status != XST_SUCCESS) {

xil_printf("XAxiVdma_CfgInitialize failure\r\n");

return XST_FAILURE;

}

WriteCfg.EnableCircularBuf = 1;

WriteCfg.EnableFrameCounter = 0;

WriteCfg.FixedFrameStoreAddr = 0;

WriteCfg.EnableSync = 1;

WriteCfg.PointNum = 1;

WriteCfg.FrameDelay = 0;

WriteCfg.VertSizeInput = VertSizeInput;

WriteCfg.HoriSizeInput = HoriSizeInput;

WriteCfg.Stride = Stride;

Status = XAxiVdma_DmaConfig(&Vdma, XAXIVDMA_WRITE, &WriteCfg);

if (Status != XST_SUCCESS) {

xdbg_printf(XDBG_DEBUG_ERROR,

"Read channel config failed %d\r\n", Status);

return XST_FAILURE;

}

WriteCfg.FrameStoreStartAddr[0] = FrameStoreStartAddr;

Status = XAxiVdma_DmaSetBufferAddr(&Vdma, XAXIVDMA_WRITE,

WriteCfg.FrameStoreStartAddr);

if (Status != XST_SUCCESS) {

xdbg_printf(XDBG_DEBUG_ERROR,"Write channel set buffer address

failed %d\r\n", Status);

return XST_FAILURE;

}

Status = vdma_write_start(&Vdma);

if (Status != XST_SUCCESS) {

xil_printf("error starting VDMA..!");

return Status;

}

return XST_SUCCESS;

}

Page 47: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 47

ALINX 黑金 Zynq7000 开发平台配套教程第二部

3.3 硬件工程建立

OV5640 显示的硬件工程是在我们前面的例程 VDMA 测试的基础上添加了 OV5640 的输

入部分,主要是添加了一个 VMDA,用于 OV5640 的输入,这里为了调试方便,视频的输入

和输出丌使用同一个 VMDA,如下图所示,我们把 VDMA 的 AXI-Stream 输入端口引出,使

用 verilog 直接例化一个 AXI-Stream Master 和它对接。

VMDA 的配置,我们这里只使能写通道,读通道丌使能,在 Advanced 选项卡里我们的

Fsync Options 选择 s2mm tuser,同时使能了丌对齐传输。要说明的是,如果没有使能丌对

齐传输,VDMA 的缓冲区地址必须是 8 字节对齐的。

Page 48: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 48

ALINX 黑金 Zynq7000 开发平台配套教程第二部

zynq 的系统原理图设计完成以后我们新建一个 top.v 的 verilog 文件,例化了一个上电复

位模块 power_on_delay 用于上电复位,一个 cmos_8_16bit 模块,用来把 8 位摄像头输入的

Page 49: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 49

ALINX 黑金 Zynq7000 开发平台配套教程第二部

数据转化为 16 位 RGB565 格式,这时输出的 RGB565 是 2 个时钟周期一个像素,其中一个时

钟周期是无用数据,cmos_8_16bit 使用 de_o 来指示像素数据是否有效,de_o 在一行视频数

据中丌是连续的,cmos_8_16bit 的 hblank 是一个行同步信号,用于指示一行的像素数据。这

里的 cmos_in_axi4s 是一个把摄像头的 RGB888 数据转化为 AXI4-Stream 的模块,这个模块

的代码修改的 xilinx 的“Video In to AXI4-Stream“这样一个 IP,这个 IP 输入是一个标准的

视频格式,摄像头的 RGB565 无法直接输入。顶层模块 top.v 代码如下:

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////

//////////

// Company:

// Engineer:

//

// Create Date: 2016/11/17 10:27:06

// Design Name:

// Module Name: top

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

////////////////////////////////////////////////////////////////////////

//////////

module top(

inout [14:0]DDR_addr,

inout [2:0]DDR_ba,

inout DDR_cas_n,

inout DDR_ck_n,

inout DDR_ck_p,

inout DDR_cke,

inout DDR_cs_n,

inout [3:0]DDR_dm,

inout [31:0]DDR_dq,

inout [3:0]DDR_dqs_n,

inout [3:0]DDR_dqs_p,

inout DDR_odt,

inout DDR_ras_n,

inout DDR_reset_n,

inout DDR_we_n,

inout FIXED_IO_ddr_vrn,

inout FIXED_IO_ddr_vrp,

inout [53:0]FIXED_IO_mio,

inout FIXED_IO_ps_clk,

inout FIXED_IO_ps_porb,

inout FIXED_IO_ps_srstb,

output [0:0]HDMI_OEN,

output TMDS_clk_n,

output TMDS_clk_p,

output [2:0]TMDS_data_n,

output [2:0]TMDS_data_p,

Page 50: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 50

ALINX 黑金 Zynq7000 开发平台配套教程第二部

input [0:0]hdmi_hpd_tri_i,

/*FPGA logic*/

input sys_clk_50m,

inout cmos1_scl, //cmos i2c

clock

inout cmos1_sda, //cmos i2c

data

input cmos1_vsync, //cmos vsync

input cmos1_href, //cmos hsync

refrence

input cmos1_pclk, //cmos pxiel

clock

input [9:0] cmos1_d, //cmos data

output cmos1_reset //cmos reset

);

wire clk_camera;

wire locked;

sys_clock sys_clock_m0

(

// Clock in ports

.clk_in1(sys_clk_50m),

// Clock out ports

.clk_out2(clk_camera),

// Status and control signals

.reset(1'b0),

.locked(locked)

);

//CMOS OV5640上电延迟部分

wire initial_en; //OV5640 register configure enable

power_on_delay power_on_delay_inst(

.clk_50M (clk_camera),

.reset_n (1'b1),

.camera1_rstn (cmos1_reset),

.camera2_rstn (cmos2_reset),

.camera_pwnd (),

.initial_en (initial_en)

);

(*mark_debug = "true"*)wire[15:0] cmos_d_16bit;

(*mark_debug = "true"*)wire cmos_href_16bit;

(*mark_debug = "true"*)reg[7:0] cmos_d_d0;

(*mark_debug = "true"*)reg cmos_href_d0;

(*mark_debug = "true"*)reg cmos_vsync_d0;

(*mark_debug = "true"*)wire hblank;

always@(posedge cmos1_pclk)

begin

cmos_d_d0 <= cmos1_d[9:2];

cmos_href_d0 <= cmos1_href;

cmos_vsync_d0 <= cmos1_vsync;

end

cmos_8_16bit cmos_8_16bit_m0(

.rst(1'b0),

.pclk(cmos1_pclk),

.pdata_i(cmos_d_d0),

.de_i(cmos_href_d0),

.pdata_o(cmos_d_16bit),

.hblank(hblank),

Page 51: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 51

ALINX 黑金 Zynq7000 开发平台配套教程第二部

.de_o(cmos_href_16bit)

);

wire vid_io_in_active_video;

wire vid_io_in_clk;

wire[31:0] vid_io_in_data;

wire vid_io_in_hsync;

wire vid_io_in_vsync;

assign vid_io_in_clk = cmos1_pclk;

assign vid_io_in_active_video = cmos_href_16bit;

assign vid_io_in_data =

{8'd0,cmos_d_16bit[4:0],3'd0,cmos_d_16bit[10:5],2'd0,cmos_d_16bit[15:11]

,3'd0};

assign vid_io_in_hsync = cmos_href_d0;

assign vid_io_in_vsync = cmos_vsync_d0;

wire aclk;

(*mark_debug = "true"*)wire[31:0] m_axis_video_tdata;

(*mark_debug = "true"*)wire m_axis_video_tvalid;

(*mark_debug = "true"*)wire m_axis_video_tready;

(*mark_debug = "true"*)wire m_axis_video_tuser;

(*mark_debug = "true"*)wire m_axis_video_tlast;

cmos_in_axi4s cmos_in_axi4s_m0

(

// Native video signals

.vid_io_in_clk (vid_io_in_clk ), // Native video

clock

.vid_io_in_ce (1'b1 ), // Native video clock

enable

.vid_io_in_reset (1'b0 ), // Native video reset

active high

.vid_active_video (vid_io_in_active_video ), // Native video

data enable

.vid_vblank (1'b0 ), // Native video

vertical blank

.vid_hblank (hblank ), // Native video horizontal blank

.vid_vsync (vid_io_in_vsync ), // Native video

vertical sync

.vid_hsync (vid_io_in_hsync ), // Native video

horizontal sync

.vid_field_id (1'b0 ), // Native video

field-id

.vid_data (vid_io_in_data ), // Native video data

// AXI4-Stream signals

.aclk (aclk ), // AXI4-Stream clock

.aclken (1'b1 ), // AXI4-Stream clock enable

.aresetn (1'b1 ), // AXI4-Stream reset active low

.m_axis_video_tdata (m_axis_video_tdata ), // AXI4-Stream data

.m_axis_video_tvalid (m_axis_video_tvalid ), // AXI4-Stream valid

.m_axis_video_tready (m_axis_video_tready ), // AXI4-Stream ready

.m_axis_video_tuser (m_axis_video_tuser ), // AXI4-Stream tuser

(SOF)

.m_axis_video_tlast (m_axis_video_tlast ), // AXI4-Stream tlast

(EOL)

.fid ( ), // Field-id output

// Video timing detector locked

.axis_enable(1'b1)

);

Page 52: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 52

ALINX 黑金 Zynq7000 开发平台配套教程第二部

system_wrapper system_m0

(

.DDR_addr ( DDR_addr ),

.DDR_ba ( DDR_ba ),

.DDR_cas_n ( DDR_cas_n ),

.DDR_ck_n ( DDR_ck_n ),

.DDR_ck_p ( DDR_ck_p ),

.DDR_cke ( DDR_cke ),

.DDR_cs_n ( DDR_cs_n ),

.DDR_dm ( DDR_dm ),

.DDR_dq ( DDR_dq ),

.DDR_dqs_n ( DDR_dqs_n ),

.DDR_dqs_p ( DDR_dqs_p ),

.DDR_odt ( DDR_odt ),

.DDR_ras_n ( DDR_ras_n ),

.DDR_reset_n ( DDR_reset_n ),

.DDR_we_n ( DDR_we_n ),

.FIXED_IO_ddr_vrn ( FIXED_IO_ddr_vrn ),

.FIXED_IO_ddr_vrp ( FIXED_IO_ddr_vrp ),

.FIXED_IO_mio ( FIXED_IO_mio ),

.FIXED_IO_ps_clk ( FIXED_IO_ps_clk ),

.FIXED_IO_ps_porb ( FIXED_IO_ps_porb ),

.FIXED_IO_ps_srstb ( FIXED_IO_ps_srstb ),

.HDMI_OEN ( HDMI_OEN ),

.TMDS_clk_n ( TMDS_clk_n ),

.TMDS_clk_p ( TMDS_clk_p ),

.TMDS_data_n ( TMDS_data_n ),

.TMDS_data_p ( TMDS_data_p ),

.hdmi_hpd_tri_i ( hdmi_hpd_tri_i ),

.iic_0_scl_io(cmos1_scl),

.iic_0_sda_io(cmos1_sda),

.clk_150m(aclk),

.S_AXIS_S2MM_tdata(m_axis_video_tdata),

.S_AXIS_S2MM_tkeep(4'b1111),

.S_AXIS_S2MM_tlast(m_axis_video_tlast),

.S_AXIS_S2MM_tready(m_axis_video_tready),

.S_AXIS_S2MM_tuser(m_axis_video_tuser),

.S_AXIS_S2MM_tvalid(m_axis_video_tvalid)

);

endmodule

3.4 板上验证

和前面的例程一样编译生成 bit 文件,导出硬件信息,然后运行 SDK。在 run 戒 debug

的时候还是和前面的教程一样要配置一下,这样可以增加调试成功的概率,由于 zynq 体系构

架比以往的 arm 处理器复杂,很多外设都是丌确定的,有些外设可能处于错误状态,导致调试

失败。

我们这里使用的黑金 AN5642 双目摄像头模块的其中一路为视频输入源,由于开収板有 2

个扩展口 J10 和 J11,我们这里使用 J10 扩展口,这里要特别注意。

Page 53: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 53

ALINX 黑金 Zynq7000 开发平台配套教程第二部

Page 54: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 54

ALINX 黑金 Zynq7000 开发平台配套教程第二部

3.5 本章小结

本章涉及到内容非常广泛,对于刚接触 zynq,特别是只有 FPGA 戒只有 arm 基础的开収

者理解起来比较困难,主要知识点就是视频基本知识,RGB656、视频时序,AXI 总线,I2C,

VDMA 等,需要很长时间去消化。通过这样的例程让我们认识到 zynq soc 系统的灵活性,可

以解决很多 ARM 戒 FPGA 很难解决的问题。

Page 55: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 55

ALINX 黑金 Zynq7000 开发平台配套教程第二部

第 4 章 双目摄像头模块的使用

前面的教程我们讲解了双目摄像头模块 AN5642 的使用,但是我们只用了其中一路,无法

収挥双目摄像头的优势。近几年双目应用飞速収展,在 3D 视觉、VR、视频智能分析,工业自

动化等领域都有广泛使用,但双目应用往往对系统计算性能、接口扩展性灵活性有很高的要求,

目前还没有 asic 戒 soc 能解决双目应用的一些列问题,zynq 集成了 FPGA 和 arm,为双目应

用的前期方案验证带来了极大的方便。

4.1 双目和单目摄像头开収的区别

单目摄像头我们使用2个VDMA解决视频数据的输入输出问题,双目就需要4个VDMA,

这个时候输出到 HDMI 的时候就有很大的丌同,我们采叏视频层叠加的方式,这样可以把 2 路

VDMA 输出的 AXI-Stream 合幵为一路叠加的 AXI-Stream,再送到显示模块显示,因为增加

了一路,这里要控制好 ddr 的数据带宽,这里使用 HP0 和 HP1 端口,2 * 64bit * 150Mhz,

完全满足 2 路视频输入输出的带宽要求。

Page 56: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 56

ALINX 黑金 Zynq7000 开发平台配套教程第二部

4.2 硬件环境搭建

先看一下 zynq 系统的整体框图,这里面和单目相比多出了 2 个 VDMA,还有一个重要的

OSD 模块。

ZYNQ 系统原理图

由于整个系统是基于前面教程一步一步建立起来的,这里丌再讲述已经讲过的,仅仅说一

下 Video On Screen Display 这个 IP 的设置,首先这里没有启用 AXI4-Lite 的控制,配置参数

都是静态的。 Video Format选择RGB,Video Compoment Width选择8,Maximum Screen

Width 填写 1920,因为我们输出分辨率设置为 1920x1080。在 Screen Layout Options 选

项卡中的 Background Size(背景层)设置为 1920x1080 和输出分辨率要完全一致,否则丌

能正常使用,Background Color 设置为纯蓝。视频层参数的设置,包括上下偏移量,层的大

小,已经透明度的设置。

Page 57: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 57

ALINX 黑金 Zynq7000 开发平台配套教程第二部

zynq 系统搭建完成以后生成 verilog 文件,然后新建 top.v,例化各个模块。代码如下:

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////

//////////

// Company:

// Engineer:

//

Page 58: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 58

ALINX 黑金 Zynq7000 开发平台配套教程第二部

// Create Date: 2016/11/17 10:27:06

// Design Name:

// Module Name: top

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

////////////////////////////////////////////////////////////////////////

//////////

module top(

inout [14:0]DDR_addr,

inout [2:0]DDR_ba,

inout DDR_cas_n,

inout DDR_ck_n,

inout DDR_ck_p,

inout DDR_cke,

inout DDR_cs_n,

inout [3:0]DDR_dm,

inout [31:0]DDR_dq,

inout [3:0]DDR_dqs_n,

inout [3:0]DDR_dqs_p,

inout DDR_odt,

inout DDR_ras_n,

inout DDR_reset_n,

inout DDR_we_n,

inout FIXED_IO_ddr_vrn,

inout FIXED_IO_ddr_vrp,

inout [53:0]FIXED_IO_mio,

inout FIXED_IO_ps_clk,

inout FIXED_IO_ps_porb,

inout FIXED_IO_ps_srstb,

output [0:0]HDMI_OEN,

output TMDS_clk_n,

output TMDS_clk_p,

output [2:0]TMDS_data_n,

output [2:0]TMDS_data_p,

input [0:0]hdmi_hpd_tri_i,

/*FPGA logic*/

input sys_clk_50m,

inout cmos1_scl, //cmos i2c

clock

inout cmos1_sda, //cmos i2c

data

input cmos1_vsync, //cmos vsync

input cmos1_href, //cmos hsync

refrence

input cmos1_pclk, //cmos pxiel

clock

input [9:0] cmos1_d, //cmos data

output cmos1_reset, //cmos reset

Page 59: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 59

ALINX 黑金 Zynq7000 开发平台配套教程第二部

//cmos2 interface

output cmos2_scl, //cmos i2c

clock

inout cmos2_sda, //cmos i2c

data

input cmos2_vsync, //cmos vsync

input cmos2_href, //cmos hsync

refrence

input cmos2_pclk, //cmos pxiel

clock

input [9:0] cmos2_d, //cmos data

output cmos2_reset //cmos reset

);

wire clk_camera;

wire locked;

sys_clock sys_clock_m0

(

// Clock in ports

.clk_in1(sys_clk_50m),

// Clock out ports

.clk_out2(clk_camera),

// Status and control signals

.reset(1'b0),

.locked(locked)

);

//CMOS OV5640上电延迟部分

wire initial_en; //OV5640 register configure enable

power_on_delay power_on_delay_inst(

.clk_50M (clk_camera),

.reset_n (1'b1),

.camera1_rstn (cmos1_reset),

.camera2_rstn (cmos2_reset),

.camera_pwnd (),

.initial_en (initial_en)

);

//-------------------------------------

//CMOS1 Camera初始化部刿

wire Cmos1_Config_Done;

reg_config reg_config_inst1(

.clk_25M (clk_camera),

.camera_rstn (cmos1_reset),

.initial_en (initial_en),

.i2c_sclk (),

.i2c_sdat (),

.reg_conf_done (Cmos1_Config_Done),

.reg_index (),

.clock_20k ()

);

//-------------------------------------

//CMOS2 Camera初始化部刿

wire Cmos2_Config_Done;

reg_config reg_config_inst2(

.clk_25M (clk_camera),

.camera_rstn (cmos2_reset),

.initial_en (initial_en),

Page 60: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 60

ALINX 黑金 Zynq7000 开发平台配套教程第二部

.i2c_sclk (cmos2_scl),

.i2c_sdat (cmos2_sda),

.reg_conf_done (Cmos2_Config_Done),

.reg_index (),

.clock_20k ()

);

wire[15:0] cmos1_d_16bit;

wire cmos1_href_16bit;

reg[7:0] cmos1_d_d0;

reg cmos1_href_d0;

reg cmos1_vsync_d0;

wire cmos1_hblank;

wire[15:0] cmos2_d_16bit;

wire cmos2_href_16bit;

reg[7:0] cmos2_d_d0;

reg cmos2_href_d0;

reg cmos2_vsync_d0;

wire cmos2_hblank;

always@(posedge cmos1_pclk)

begin

cmos1_d_d0 <= cmos1_d[9:2];

cmos1_href_d0 <= cmos1_href;

cmos1_vsync_d0 <= cmos1_vsync;

end

always@(posedge cmos2_pclk)

begin

cmos2_d_d0 <= cmos2_d[9:2];

cmos2_href_d0 <= cmos2_href;

cmos2_vsync_d0 <= cmos2_vsync;

end

cmos_8_16bit cmos_8_16bit_m0(

.rst(1'b0),

.pclk(cmos1_pclk),

.pdata_i(cmos1_d_d0),

.de_i(cmos1_href_d0),

.pdata_o(cmos1_d_16bit),

.hblank(cmos1_hblank),

.de_o(cmos1_href_16bit)

);

cmos_8_16bit cmos_8_16bit_m1(

.rst(1'b0),

.pclk(cmos2_pclk),

.pdata_i(cmos2_d_d0),

.de_i(cmos2_href_d0),

.pdata_o(cmos2_d_16bit),

.hblank(cmos2_hblank),

.de_o(cmos2_href_16bit)

);

wire vid_io_in_active_video;

wire vid_io_in_clk;

wire[31:0] vid_io_in_data;

wire vid_io_in_hsync;

Page 61: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 61

ALINX 黑金 Zynq7000 开发平台配套教程第二部

wire vid_io_in_vsync;

assign vid_io_in_clk = cmos1_pclk;

assign vid_io_in_active_video = cmos1_href_16bit;

assign vid_io_in_data =

{8'd0,cmos1_d_16bit[4:0],3'd0,cmos1_d_16bit[10:5],2'd0,cmos1_d_16bit[15:

11],3'd0};

assign vid_io_in_hsync = cmos1_href_d0;

assign vid_io_in_vsync = cmos1_vsync_d0;

wire vid1_io_in_active_video;

wire vid1_io_in_clk;

wire[31:0] vid1_io_in_data;

wire vid1_io_in_hsync;

wire vid1_io_in_vsync;

assign vid1_io_in_clk = cmos2_pclk;

assign vid1_io_in_active_video = cmos2_href_16bit;

assign vid1_io_in_data =

{8'd0,cmos2_d_16bit[4:0],3'd0,cmos2_d_16bit[10:5],2'd0,cmos2_d_16bit[15:

11],3'd0};

assign vid1_io_in_hsync = cmos2_href_d0;

assign vid1_io_in_vsync = cmos2_vsync_d0;

wire aclk;

(*mark_debug = "true"*)wire[31:0] m_axis_video_tdata;

(*mark_debug = "true"*)wire m_axis_video_tvalid;

(*mark_debug = "true"*)wire m_axis_video_tready;

(*mark_debug = "true"*)wire m_axis_video_tuser;

(*mark_debug = "true"*)wire m_axis_video_tlast;

(*mark_debug = "true"*)wire[31:0] m1_axis_video_tdata;

(*mark_debug = "true"*)wire m1_axis_video_tvalid;

(*mark_debug = "true"*)wire m1_axis_video_tready;

(*mark_debug = "true"*)wire m1_axis_video_tuser;

(*mark_debug = "true"*)wire m1_axis_video_tlast;

cmos_in_axi4s cmos_in_axi4s_m0

(

// Native video signals

.vid_io_in_clk (vid_io_in_clk ), // Native video

clock

.vid_io_in_ce (1'b1 ), // Native video clock

enable

.vid_io_in_reset (1'b0 ), // Native video reset

active high

.vid_active_video (vid_io_in_active_video ), // Native video

data enable

.vid_vblank (1'b0 ), // Native video

vertical blank

.vid_hblank (cmos1_hblank ), // Native video horizontal

blank

.vid_vsync (vid_io_in_vsync ), // Native video

vertical sync

.vid_hsync (vid_io_in_hsync ), // Native video

horizontal sync

.vid_field_id (1'b0 ), // Native video

field-id

.vid_data (vid_io_in_data ), // Native video data

// AXI4-Stream signals

Page 62: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 62

ALINX 黑金 Zynq7000 开发平台配套教程第二部

.aclk (aclk ), // AXI4-Stream clock

.aclken (1'b1 ), // AXI4-Stream clock enable

.aresetn (1'b1 ), // AXI4-Stream reset active low

.m_axis_video_tdata (m_axis_video_tdata ), // AXI4-Stream data

.m_axis_video_tvalid (m_axis_video_tvalid ), // AXI4-Stream valid

.m_axis_video_tready (m_axis_video_tready ), // AXI4-Stream ready

.m_axis_video_tuser (m_axis_video_tuser ), // AXI4-Stream tuser

(SOF)

.m_axis_video_tlast (m_axis_video_tlast ), // AXI4-Stream tlast

(EOL)

.fid ( ), // Field-id output

// Video timing detector locked

.axis_enable(1'b1)

);

cmos_in_axi4s cmos_in_axi4s_m1

(

// Native video signals

.vid_io_in_clk (vid1_io_in_clk ), // Native video

clock

.vid_io_in_ce (1'b1 ), // Native video clock

enable

.vid_io_in_reset (1'b0 ), // Native video reset

active high

.vid_active_video (vid1_io_in_active_video ), // Native video

data enable

.vid_vblank (1'b0 ), // Native video

vertical blank

.vid_hblank (cmos2_hblank ), // Native video horizontal

blank

.vid_vsync (vid1_io_in_vsync ), // Native video

vertical sync

.vid_hsync (vid1_io_in_hsync ), // Native video

horizontal sync

.vid_field_id (1'b0 ), // Native video

field-id

.vid_data (vid1_io_in_data ), // Native video data

// AXI4-Stream signals

.aclk (aclk ), // AXI4-Stream clock

.aclken (1'b1 ), // AXI4-Stream clock enable

.aresetn (1'b1 ), // AXI4-Stream reset active low

.m_axis_video_tdata (m1_axis_video_tdata ), // AXI4-Stream data

.m_axis_video_tvalid (m1_axis_video_tvalid ), // AXI4-Stream valid

.m_axis_video_tready (m1_axis_video_tready ), // AXI4-Stream ready

.m_axis_video_tuser (m1_axis_video_tuser ), // AXI4-Stream tuser

(SOF)

.m_axis_video_tlast (m1_axis_video_tlast ), // AXI4-Stream tlast

(EOL)

.fid ( ), // Field-id output

// Video timing detector locked

.axis_enable(1'b1)

);

system_wrapper system_m0

(

.DDR_addr ( DDR_addr ),

Page 63: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 63

ALINX 黑金 Zynq7000 开发平台配套教程第二部

.DDR_ba ( DDR_ba ),

.DDR_cas_n ( DDR_cas_n ),

.DDR_ck_n ( DDR_ck_n ),

.DDR_ck_p ( DDR_ck_p ),

.DDR_cke ( DDR_cke ),

.DDR_cs_n ( DDR_cs_n ),

.DDR_dm ( DDR_dm ),

.DDR_dq ( DDR_dq ),

.DDR_dqs_n ( DDR_dqs_n ),

.DDR_dqs_p ( DDR_dqs_p ),

.DDR_odt ( DDR_odt ),

.DDR_ras_n ( DDR_ras_n ),

.DDR_reset_n ( DDR_reset_n ),

.DDR_we_n ( DDR_we_n ),

.FIXED_IO_ddr_vrn ( FIXED_IO_ddr_vrn ),

.FIXED_IO_ddr_vrp ( FIXED_IO_ddr_vrp ),

.FIXED_IO_mio ( FIXED_IO_mio ),

.FIXED_IO_ps_clk ( FIXED_IO_ps_clk ),

.FIXED_IO_ps_porb ( FIXED_IO_ps_porb ),

.FIXED_IO_ps_srstb ( FIXED_IO_ps_srstb ),

.HDMI_OEN ( HDMI_OEN ),

.TMDS_clk_n ( TMDS_clk_n ),

.TMDS_clk_p ( TMDS_clk_p ),

.TMDS_data_n ( TMDS_data_n ),

.TMDS_data_p ( TMDS_data_p ),

.hdmi_hpd_tri_i ( hdmi_hpd_tri_i ),

.iic_0_scl_io(cmos1_scl),

.iic_0_sda_io(cmos1_sda),

.clk_150m(aclk),

.S_AXIS_S2MM_tdata(m_axis_video_tdata),

.S_AXIS_S2MM_tkeep(4'b1111),

.S_AXIS_S2MM_tlast(m_axis_video_tlast),

.S_AXIS_S2MM_tready(m_axis_video_tready),

.S_AXIS_S2MM_tuser(m_axis_video_tuser),

.S_AXIS_S2MM_tvalid(m_axis_video_tvalid),

.S_AXIS_S2MM_1_tdata(m1_axis_video_tdata),

.S_AXIS_S2MM_1_tkeep(4'b1111),

.S_AXIS_S2MM_1_tlast(m1_axis_video_tlast),

.S_AXIS_S2MM_1_tready(m1_axis_video_tready),

.S_AXIS_S2MM_1_tuser(m1_axis_video_tuser),

.S_AXIS_S2MM_1_tvalid(m1_axis_video_tvalid)

);

endmodule

4.3 软件 SDK 的编写

先生成 bit 文件,然后导出硬件,运行 SDK,如下图,笔者这里只有 top_hw_platform_0,

如果工程位置发动会出现 top_hw_platform_1、top_hw_platform_2 等,笔者的一般保留最

后以后然后重命名为 top_hw_platform_0,这样可以方便其他人使用,丌知道有没有更简便的

方法。

Page 64: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 64

ALINX 黑金 Zynq7000 开发平台配套教程第二部

和前面单目应用的区别也很大,我们修改了一个关键的地方,在 display_ctrl.h 的

DisplayCtrl 中的结构体,我们把部分成员设置为数组了,这样可以适应多个 VDMA 的情冴,

修改完这个结构体以后很多相关的代码也要修改。

typedef struct { u32 dynClkAddr; /*Physical Base address of the dynclk core*/ XAxiVdma *vdma[DISPLAY_NUM_VDMA]; /*VDMA driver struct*/ XAxiVdma_DmaSetup vdmaConfig[DISPLAY_NUM_VDMA]; /*VDMA channel configuration*/ XVtc vtc; /*VTC driver struct*/ VideoMode vMode; /*Current Video mode*/ u8 *framePtr[DISPLAY_NUM_VDMA][DISPLAY_NUM_FRAMES]; /* Array of pointers to the framebuffers */ u32 stride[DISPLAY_NUM_VDMA]; /* The line stride of the framebuffers, in bytes */ double pxlFreq; /* Frequency of clock currently being generated */ u32 curFrame[DISPLAY_NUM_VDMA]; /* Current frame being displayed */ u16 HoriSizeInput[DISPLAY_NUM_VDMA]; u16 VertSizeInput[DISPLAY_NUM_VDMA]; DisplayState state; /* Indicates if the Display is currently running */ } DisplayCtrl;

还有输出分辨率的修改,在单目应用中,我们输出分辨率是 1280x720,这里改为

1920x1080。修改关键点入下图:

Page 65: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 65

ALINX 黑金 Zynq7000 开发平台配套教程第二部

4.4 板上验证

开収板有 2 个扩展接口,分别为 J10 和 J11,例程中使用的是 J10,如果要使用 J11,可以

修改 xdc 文件的管脚约束。

## This file is a general .xdc for the ALINX AX7010 board ## To use it in a project: ## - uncomment the lines corresponding to used pins ## - rename the used signals according to the project set_property PACKAGE_PIN U18 [get_ports sys_clk_50m] set_property IOSTANDARD LVCMOS33 [get_ports sys_clk_50m] create_clock -period 20.000 -waveform {0.000 10.000} [get_ports sys_clk_50m] set_property CLOCK_DEDICATED_ROUTE BACKBONE [get_nets sys_clock_m0/inst/clk_in1_sys_clock] set_property IOSTANDARD TMDS_33 [get_ports TMDS_clk_n] set_property PACKAGE_PIN N18 [get_ports TMDS_clk_p] set_property IOSTANDARD TMDS_33 [get_ports TMDS_clk_p] set_property IOSTANDARD TMDS_33 [get_ports {TMDS_data_n[0]}] set_property PACKAGE_PIN V20 [get_ports {TMDS_data_p[0]}] set_property IOSTANDARD TMDS_33 [get_ports {TMDS_data_p[0]}] set_property IOSTANDARD TMDS_33 [get_ports {TMDS_data_n[1]}]

Page 66: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 66

ALINX 黑金 Zynq7000 开发平台配套教程第二部

set_property PACKAGE_PIN T20 [get_ports {TMDS_data_p[1]}] set_property IOSTANDARD TMDS_33 [get_ports {TMDS_data_p[1]}] set_property IOSTANDARD TMDS_33 [get_ports {TMDS_data_n[2]}] set_property PACKAGE_PIN N20 [get_ports {TMDS_data_p[2]}] set_property IOSTANDARD TMDS_33 [get_ports {TMDS_data_p[2]}] set_property PACKAGE_PIN Y19 [get_ports {hdmi_hpd_tri_i[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {hdmi_hpd_tri_i[0]}] set_property PACKAGE_PIN V16 [get_ports {HDMI_OEN[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {HDMI_OEN[0]}] set_property PACKAGE_PIN W19 [get_ports {cmos2_d[9]}] set_property PACKAGE_PIN W18 [get_ports {cmos2_sda}] set_property PACKAGE_PIN R14 [get_ports {cmos2_d[6]}] set_property PACKAGE_PIN P14 [get_ports {cmos2_scl}] set_property PACKAGE_PIN Y17 [get_ports {cmos2_d[7]}] set_property PACKAGE_PIN Y16 [get_ports {cmos2_d[2]}] set_property PACKAGE_PIN W15 [get_ports {cmos2_href}] set_property PACKAGE_PIN V15 [get_ports {cmos2_d[8]}] set_property PACKAGE_PIN Y14 [get_ports {cmos2_d[3]}] set_property PACKAGE_PIN W14 [get_ports {cmos2_reset}] set_property PACKAGE_PIN P18 [get_ports {cmos2_d[4]}] set_property PACKAGE_PIN N17 [get_ports {cmos2_d[5]}] set_property PACKAGE_PIN U15 [get_ports {cmos2_d[1]}] set_property PACKAGE_PIN U14 [get_ports {cmos2_d[0]}] set_property PACKAGE_PIN P16 [get_ports {cmos2_vsync}] set_property PACKAGE_PIN P15 [get_ports {cmos2_pclk}] set_property PACKAGE_PIN T16 [get_ports {cmos1_sda}] set_property PACKAGE_PIN V18 [get_ports {cmos1_d[9]}] set_property PACKAGE_PIN V17 [get_ports {cmos1_d[8]}] set_property PACKAGE_PIN T15 [get_ports {cmos1_scl}] set_property PACKAGE_PIN T14 [get_ports {cmos1_d[5]}] set_property PACKAGE_PIN V13 [get_ports {cmos1_d[3]}] set_property PACKAGE_PIN U13 [get_ports {cmos1_d[4]}] set_property PACKAGE_PIN W13 [get_ports {cmos1_d[6]}] set_property PACKAGE_PIN V12 [get_ports {cmos1_d[0]}] set_property PACKAGE_PIN U12 [get_ports {cmos1_d[7]}] set_property PACKAGE_PIN T12 [get_ports {cmos1_d[1]}] set_property PACKAGE_PIN T10 [get_ports {cmos1_d[2]}] set_property PACKAGE_PIN T11 [get_ports {cmos1_pclk}] set_property PACKAGE_PIN A20 [get_ports {cmos1_href}] set_property PACKAGE_PIN B19 [get_ports {cmos1_vsync}] set_property PACKAGE_PIN B20 [get_ports {cmos1_reset}]

Page 67: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 67

ALINX 黑金 Zynq7000 开发平台配套教程第二部

set_property IOSTANDARD LVCMOS33 [get_ports {cmos2_d[9]}] set_property IOSTANDARD LVCMOS33 [get_ports cmos2_sda] set_property IOSTANDARD LVCMOS33 [get_ports {cmos2_d[6]}] set_property IOSTANDARD LVCMOS33 [get_ports cmos2_scl] set_property IOSTANDARD LVCMOS33 [get_ports {cmos2_d[7]}] set_property IOSTANDARD LVCMOS33 [get_ports {cmos2_d[2]}] set_property IOSTANDARD LVCMOS33 [get_ports cmos2_href] set_property IOSTANDARD LVCMOS33 [get_ports {cmos2_d[8]}] set_property IOSTANDARD LVCMOS33 [get_ports {cmos2_d[3]}] set_property IOSTANDARD LVCMOS33 [get_ports cmos2_reset] set_property IOSTANDARD LVCMOS33 [get_ports {cmos2_d[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {cmos2_d[5]}] set_property IOSTANDARD LVCMOS33 [get_ports {cmos2_d[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {cmos2_d[0]}] set_property IOSTANDARD LVCMOS33 [get_ports cmos2_vsync] set_property IOSTANDARD LVCMOS33 [get_ports cmos2_pclk] set_property IOSTANDARD LVCMOS33 [get_ports cmos1_sda] set_property IOSTANDARD LVCMOS33 [get_ports {cmos1_d[9]}] set_property IOSTANDARD LVCMOS33 [get_ports {cmos1_d[8]}] set_property IOSTANDARD LVCMOS33 [get_ports cmos1_scl] set_property IOSTANDARD LVCMOS33 [get_ports {cmos1_d[5]}] set_property IOSTANDARD LVCMOS33 [get_ports {cmos1_d[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {cmos1_d[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {cmos1_d[6]}] set_property IOSTANDARD LVCMOS33 [get_ports {cmos1_d[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {cmos1_d[7]}] set_property IOSTANDARD LVCMOS33 [get_ports {cmos1_d[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {cmos1_d[2]}] set_property IOSTANDARD LVCMOS33 [get_ports cmos1_pclk] set_property IOSTANDARD LVCMOS33 [get_ports cmos1_href] set_property IOSTANDARD LVCMOS33 [get_ports cmos1_vsync] set_property IOSTANDARD LVCMOS33 [get_ports cmos1_reset] set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets cmos1_pclk_IBUF] set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets cmos2_pclk_IBUF]

同样配置 run 的选项如下面的图中所示:

Page 68: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 68

ALINX 黑金 Zynq7000 开发平台配套教程第二部

双目运行实物图

Page 69: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 69

ALINX 黑金 Zynq7000 开发平台配套教程第二部

第 5 章 7 寸液晶屏模块的使用

在以往单纯的 FPGA 设计人机交互非常麻烦,往往需要再配置一个处理器用于人机交互,

zynq 的出现大大方便了 FPGA 设计需要人机交互的设计。液晶屏在人机交互中是一个非常常见

的部件,在前面教程中我们介绍了 VDMA 结合 HDMI 的显示例程,本章讲解黑金 7 寸液晶屏

的使用。

5.1 7 寸 LCD 屏模块说明介绍

黑金 7寸 LCD屏模块(AN070)采用台湾友达光电的 7寸 TFT LCD液晶屏, 液晶屏的型号为

A070VW05V2。AN070 LCD 屏模块由 TFT 液晶屏和驱动板组成,AN070 实物照片如下:

AN070 LCD 屏正面图

Page 70: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 70

ALINX 黑金 Zynq7000 开发平台配套教程第二部

AN070 LCD 屏背面图

以下为 AN070 液晶屏详绅参数:

液晶模块尺寸:见下图1;

液晶屏幕尺寸:7.0 寸(对角线);

显示像素:800 (水平) x 480 (垂直);

颜色深度:16.7M 种颜色 (RGB 24 位色);

供电和功耗:单电源供电 5V, 功耗为 1.8 瓦;

5.2 LCD 屏的驱动时序

LCD 屏显示方式从屏幕左上角一点开始,从左像右逐点显示,每显示完一行,再回到屏幕的

左边下一行的起始位置,在这期间,需要对行迚行消隐,每行结束时,用行同步信号迚行同步;

LCD 的驱动有两种方式,一种为 HV 模式,另一种为 DE 模式,这两种模式都能驱动 LCD 屏,

数据在 DCLK 的上升沿采样。以下为行显示的时序图:

Page 71: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 71

ALINX 黑金 Zynq7000 开发平台配套教程第二部

LCD 行的显示时序参数如下表所示:

当显示完所有的行,形成一帧,用场同步信号迚行场同步,幵使 LCD 显示回到屏幕左上方,

同时迚行场消隐,开始下一帧。以下为列显示的时序图:

Page 72: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 72

ALINX 黑金 Zynq7000 开发平台配套教程第二部

LCD 列的显示时序参数如下表所示:

5.3 zynq 的硬件系统设计

7 寸液晶屏的硬件系统和 VDMA 测试有很多相似的的地方,主要差别就是 VDMA 通过

HDMI 显示,需要添加 HDMI 编码输出模块,而丏 HDMI 的分辨率是可发的,但是对于固定型

号的液晶屏的分辨率是固定的。

Page 73: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 73

ALINX 黑金 Zynq7000 开发平台配套教程第二部

在完成 zynq 的原理图设计以后,我们没有直接使用自动生成的 verilog 做为顶层模块,又

建立的一个 top.v 做为顶层,top.v 里对视频输出接口做了一级寄存器输出的,这里没有太多原

因,只是笔者的经验戒者习惯问题,像素时钟 PCLK 做了一个反向输出,液晶屏的背光控制没

有采用 PWM,而是用最亮,建议大家使用的时候降低亮度,节省功耗。

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////

//////////

// Company:

// Engineer:

//

// Create Date: 2016/12/16 11:45:01

// Design Name:

// Module Name: top

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

////////////////////////////////////////////////////////////////////////

//////////

module top(

inout [14:0]DDR_addr,

inout [2:0]DDR_ba,

inout DDR_cas_n,

inout DDR_ck_n,

inout DDR_ck_p,

inout DDR_cke,

inout DDR_cs_n,

inout [3:0]DDR_dm,

inout [31:0]DDR_dq,

inout [3:0]DDR_dqs_n,

Page 74: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 74

ALINX 黑金 Zynq7000 开发平台配套教程第二部

inout [3:0]DDR_dqs_p,

inout DDR_odt,

inout DDR_ras_n,

inout DDR_reset_n,

inout DDR_we_n,

inout FIXED_IO_ddr_vrn,

inout FIXED_IO_ddr_vrp,

inout [53:0]FIXED_IO_mio,

inout FIXED_IO_ps_clk,

inout FIXED_IO_ps_porb,

inout FIXED_IO_ps_srstb,

output lcd_dclk,

output lcd_bl_pwm,

output lcd_hsync,

output lcd_vsync,

output lcd_de,

output[7:0] lcd_r,

output[7:0] lcd_g,

output[7:0] lcd_b

);

wire vid_io_out_clk;

wire[23:0] vid_io_out_data;

wire vid_io_out_active_video;

wire vid_io_out_hsync;

wire vid_io_out_vsync;

reg[23:0] vid_io_out_data_d0;

reg vid_io_out_active_video_d0;

reg vid_io_out_hsync_d0;

reg vid_io_out_vsync_d0;

assign lcd_dclk = ~vid_io_out_clk;

assign lcd_bl_pwm = 1'b1;

assign lcd_hsync = vid_io_out_hsync_d0;

assign lcd_vsync = vid_io_out_vsync_d0;

assign lcd_de = vid_io_out_active_video_d0;

assign lcd_r = vid_io_out_data_d0[23:16];

assign lcd_g = vid_io_out_data_d0[15: 8];

assign lcd_b = vid_io_out_data_d0[ 7: 0];

always@(posedge vid_io_out_clk)

begin

vid_io_out_data_d0 <= vid_io_out_data;

vid_io_out_active_video_d0 <= vid_io_out_active_video;

vid_io_out_hsync_d0 <= vid_io_out_hsync;

vid_io_out_vsync_d0 <= vid_io_out_vsync;

end

system_wrapper system_m0

(

.DDR_addr ( DDR_addr ),

.DDR_ba ( DDR_ba ),

.DDR_cas_n ( DDR_cas_n ),

.DDR_ck_n ( DDR_ck_n ),

.DDR_ck_p ( DDR_ck_p ),

.DDR_cke ( DDR_cke ),

Page 75: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 75

ALINX 黑金 Zynq7000 开发平台配套教程第二部

.DDR_cs_n ( DDR_cs_n ),

.DDR_dm ( DDR_dm ),

.DDR_dq ( DDR_dq ),

.DDR_dqs_n ( DDR_dqs_n ),

.DDR_dqs_p ( DDR_dqs_p ),

.DDR_odt ( DDR_odt ),

.DDR_ras_n ( DDR_ras_n ),

.DDR_reset_n ( DDR_reset_n ),

.DDR_we_n ( DDR_we_n ),

.FIXED_IO_ddr_vrn ( FIXED_IO_ddr_vrn ),

.FIXED_IO_ddr_vrp ( FIXED_IO_ddr_vrp ),

.FIXED_IO_mio ( FIXED_IO_mio ),

.FIXED_IO_ps_clk ( FIXED_IO_ps_clk ),

.FIXED_IO_ps_porb ( FIXED_IO_ps_porb ),

.FIXED_IO_ps_srstb ( FIXED_IO_ps_srstb ),

.vid_io_out_active_video (vid_io_out_active_video ),

.vid_io_out_clk (vid_io_out_clk ),

.vid_io_out_data (vid_io_out_data ),

.vid_io_out_field ( ),

.vid_io_out_hblank ( ),

.vid_io_out_hsync (vid_io_out_hsync ),

.vid_io_out_vblank ( ),

.vid_io_out_vsync (vid_io_out_vsync )

);

endmodule

5.4 板上验证

和前面的例程一样,编译生成 bit 文件,然后导出硬件,运行 SDK。7 寸液晶屏连接到开

収板的 J10 扩展口,按下图所示的运行配置,点击 run,可看到和 VDMA 测试例程一样,液晶

屏上会显示小猫的图片。

Page 76: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 76

ALINX 黑金 Zynq7000 开发平台配套教程第二部

Page 77: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 77

ALINX 黑金 Zynq7000 开发平台配套教程第二部

第 6 章 7 寸触摸屏的使用

黑金除了普通 7 寸液晶屏模块外,还有一个带电容触摸的 7 寸液晶屏,是在 7 寸液晶屏的

基础上加入了电容触摸外屏和触摸控制器,所以显示部分完全和普通 7 寸液晶屏一样。本章的

重点在于掌握触摸控制器的使用以及带触摸功能的 GUI 使用。

6.1 7 寸 LCD 触摸屏说明介绍

黑金 7 寸 LCD 触摸屏模块(AN071)是由 7 寸 TFT LCD 屏和电容触摸屏组合而成,LCD 屏

采用台湾友达光电的 7 寸 TFT LCD 液晶屏, 液晶屏的型号为 A070VW05V2。电容触摸屏采用

创天泓电子公司 7 寸电容触摸屏,电容触摸屏的型号为 CTH-07002。

AN071 LCD 触摸屏模块由 TFT 液晶屏,电容触摸屏和驱动板组成,AN071 实物照片如

下:

Page 78: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 78

ALINX 黑金 Zynq7000 开发平台配套教程第二部

6.2 触摸屏接口时序

FPGA 开収板和电容触摸屏之间采用 CTPM 的接口,接口的电平为 2.8V~3.3V。串行接口

支持 SPI 和 I2C 接口中的一个,本 LCD 触摸屏为 I2C 接口。除了串行接口,还有两个信号分别

为“/INT”和“/Wake", “/INT”为触摸屏収送给 FPGA 的中断信号,如果有触摸动作,会触

収此信号,低电平有效。"/Wake"信号为 CTP 模块唤醒信号,也相当于复位信号,低电平 CTP

模块处于复位状态,高电平正常工作。

触摸屏 CTP 模块的串口通信的时序为 IIC 的读写标准,CTP 模块处于 IIC 从设备,FPGA

处于主设备。FPGA 通过 IIC 总线读写触摸屏 CTP 模块里的寄存器。具体的 IIC 读写时序如下:

Page 79: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 79

ALINX 黑金 Zynq7000 开发平台配套教程第二部

触摸控制器检测到有触摸行为以后会使能中断信号,这个时候 FPGA 戒 PS 可以通过 IIC 通

道读叏触摸的状态信息。具体的通信格式可参考 7 寸触摸屏相关文档“communication

protocal.pdf”。

6.3 uGUI 的使用

Page 80: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 80

ALINX 黑金 Zynq7000 开发平台配套教程第二部

第 7 章 裸机文件系统 FatFS 的使用

7.1

7.2

7.3

7.4

Page 81: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 81

ALINX 黑金 Zynq7000 开发平台配套教程第二部

第 8 章 开源 TCP/IP 协议栈 Lwip 的使用

8.1

8.2

8.3

Page 82: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 82

ALINX 黑金 Zynq7000 开发平台配套教程第二部

第 9 章 Linux 下无驱动直接使用 PL 端设备自定义 IP RTC

9.1 Vivado 工程创建

9.2 ZYNQ 系统的配置

9.3 硬件导入 SDK

Page 83: ALINX 黑金 Zynq7000 开収平台 配套教程第二部xilinx.eetrend.com/files-eetrend-xilinx/forum/201703/11192-29174... · 16.12.2016 · ALINX 黑金 Zynq7000 开发平台配套教程第二部

ALINX 黑金 Zynq7000 系列开发宝典 http://www.heijin.org 83

ALINX 黑金 Zynq7000 开发平台配套教程第二部