Zynqの基礎シリーズVTC + VDMA + Vid_Outは、単純な核パス表示を構築します

Zynqベースシリーズ(3)VTC + VDMA + Vid_Out核ビルド簡易表示対応の作業用パス

https://blog.csdn.net/long_fly/article/details/78968043

シンプルな表示部材通路を構築

のZynqベースシリーズ(ⅱ)IOポートシミュレーションHDMI、VGAのHDMI出力にIPコアの使用が記載されている、この記事では、重要なIPコアをご紹介しますVIVADO 3つのビデオ出力経路とビルドAが来ますまもなく通過基礎後のディスプレイにカメラのための比較的単純なビデオチャンネル:

1> Video Timing Controller
2> AXI4-Stream to Video Out
3> Video DMA
  
  

あなたは最初のIPコアの機能や構成を理解することは、奔放なアクセスを構築するために行うことができている必要があります

VTC核

実際には、このIPコア缶がちょうどタイミングジェネレータが必要なタイミング信号モニタ出力、この核の到着を生成して、面積をブランキング、それらの様々な表示が方法を検討する必要はありません見て、と心の平和をたくさんすること
1>ピン
次のように完全なピンは次のようになります。
書き込み絵は、ここで説明しました

任意AXI4-Liteの制御インタフェース:リアルタイムで置換動的パラメータAXIバスVTCコアを介し
:検出器インタフェース図形Video Timing (input) Interface、ビデオタイミング捕捉及び処理するためのプローブインタフェース
ジェネレータインタフェース:図形Video Timing (input) Interface、ビデオタイミング生成

ピン I / O 機能
CLK コアクロックワーク
CLKEN クロックイネーブル(アクティブ・ハイ)
gen_aclken モードの動作クロックイネーブル生成(アクティブハイ)
det_aclken 検出モードの動作クロックイネーブル(アクティブハイ)
RESETN リセット信号(アクティブロー)
IRQ ザ・ 割り込み信号出力(アクティブハイ)
[31:0] intc_if ザ・ INTCインタフェース:[31:8]およびステータスレジスタ(0x0004は)[31:8]と[5:0]、[21:16]としての例外レジスタ(0x0008で); [7:6]が0であります
fsync_in フレーム同期入力
fsync_out [(FS-1):0] ザ・ フレーム同期出力

あなたはAXIバスを介して、あなたのコアを構成する必要がある場合、また、各レジスタの機能を、一度だけGUIの設定によって動的に構成され、ここで、構成処理する必要をチェックする必要があります

設定するには、2> GUI
:最初のページ
書き込み絵は、ここで説明しました
オプション説明:

名前 機能
AXI4-Liteのインタフェースを含みます AXIコントロールを追加します
INTCインタフェースを含みます インタフェースintc_if追加
インターレースビデオのサポート 、選択したフィールドIDの出力ラインをフックを再生している、とにかく、それをビデオミキシングをサポートしているようです
検出器またはfsync_inに同期ジェネレータ 自動的にフレーム同期タイミング検出に同期したタイミングジェネレータ又は
フレーム当たりのクロックの最大数の各列内の行の最大数 可能な限り小さくなるように条件を満たす前提の下で、2ページ目のGUIデータの範囲を決定します
フレーム同期 フレーム同期の数、及びfsync_outの幅を決定します
そして、検出が可能に生成します 生成と検出が有効になっています

あるいは、最初のページ:
書き込み絵は、ここで説明しました

今、タイミング生成モードを見て:

名前 機能
フィールドIDの生成 出力は、フィールドIDを有効にします
垂直ブランク・ジェネレーション 垂直ブランク出力を可能にします
水平ブランク・ジェネレーション 空白の許容レベル出力
垂直同期ジェネレーション 垂直同期出力を許可します
水平同期ジェネレーション 許容レベルの同期出力
アクティブビデオジェネレーション アクティブビデオライン出力
アクティブクロマジェネレーション アクティブ出力クロミナンスライン
自動生成ファッション 生成的视频时序输出会随探测到的输入改变而改变;若不勾选,将仅基于第一个检测到的输入格式生成视频时序输出,即使探测块失锁,生成的同步信号仍继续输出

第二页:
書き込み絵は、ここで説明しました
第二页的配置尤为简单,选择分辨率,大部分的显示器都可以找的到对应的分辨率,如果没有的话,也可以自定义参数
可以看到参数后面有个范围([0-4095]),那是因为我们第一页选了4096,实际上不需要这么大

第三页:
帧同步位置,暂时不管它


注意 :
不知道是不是VIVADO版本的问题(我的是2017.4),VIVADO有个BUG,就是IP核在原理图中显示的引脚与实际不符
書き込み絵は、ここで説明しました
比如,clken明明是高电平有效的,他在引脚上画了个圈表示低有效,这就很糟心了,所以以后需要在原理图连线的话,都不要被表象欺骗了,最好是点进GUI配置界面看一看IP核预览(上面有图,这个GUI预览的引脚显示却是正常的)
我不是针对这一个IP核,总之,连原理图的时候,各个IP核的使能信号需要特别注意一下


Vid_Out核

AXI4-Stream类型速度很快且容易处理,一般内部视频流都是这个格式,HLS做的图像处理核也是通过AXI4-Stream接口,这个HLS核一般也是放在VDMA的后面,但是AXI4-Stream终究是要转换为VIDEO接口来驱动外界的视频接收器(如显示屏),这个转换就由Vid_Out核来实现
这使得视频设计人员能够快速方便地将具有AXI4-Stream接口的视频处理模块连接到外部视频接收器,该核与VTC核协同工作,生成视频格式的时序信号(可以直接驱动VGA)
1>引脚
完整的引脚图如下:
書き込み絵は、ここで説明しました
AXI4-Stream接口 : AXI4-Stream格式视频的输入接口
Video Timing Inputs接口 : VTC生成的时序输出的接入口
Video Outputs : 转换后的视频格式,可以直接驱动VGA(硬件电路允许的话)

引脚 I/O 功能
aclk I AXI4-Stream流的时钟(官方图里这个引脚画错了)
aclken I AXI4-Stream流的时钟使能(高有效)
aresetn I AXI4-Stream流的复位(低有效)
vid_io_out_clk I 本地视频时钟(必须和VTC的工作时钟同步)
vid_io_out_ce I 本地视频时钟使能
vid_io_out_reset I 本地视频复位信号
fid I 针对混合视频的Field ID输入,0=偶数场,1=奇数场(同步到aclk)
vtg_ce O 用于暂停时序发生器达到同步的目的(接VTC时钟使能)
locked O 表明VTC是否锁定到输入时序(同步到vid_io_out_clk)
overflow O FIFO溢出(同步到vid_io_out_clk)
underflow O FIFO空(同步到vid_io_out_clk)
status[31:0] O 用于监视同步状态机的状态

2>GUI配置
書き込み絵は、ここで説明しました

选项 功能
Pixels Per Clock 指定要并行输出的像素数(影响输入和输出的数据位宽)
Video Format 选择相应的视频格式(决定输入输出线宽)
AXI4S视频输入分量线宽 改变输入位宽
本地视频输出分量线宽 改变输出位宽
FIFO Depth 指定FIFO深度
Clock Mode AXI4S和显示输出不在一个时钟域里的时候就需要独立时钟了
Timing Mode 时序模式,(官方建议选从模式,有能力动态调整AXI4S和vidout的相差)
Hysteresis Level 滞后等级,留FIFO的一部分作为缓冲

VDMA核

FrameBuffer帧缓存 : 每一存储单元对应屏幕上的一个像素,整个帧缓存对应一帧图像,相当于一块画布,画好之后直接通知显示设备显示
VDMA 核 : 可以方便的实现多帧缓存,也就是拥有多个画布,其最多可以控制32个画布,并可自由地进行画布切换;用户可以通过VDMA的写通道将 AXI-S类型的数据流转为Memory Map类型写入DDR,也可以通过读通道从DDR读取Memory Map类型数据以 AXI-S类型输出。VDMA本质上是一个数据搬运的核,为数据进出DDR提供了一种便捷的方案。
1>引脚
書き込み絵は、ここで説明しました
虽然上面不是全部的引脚,但是几个重要的引脚和接口都已经展示出来了,下面再配一张VDMA核的框图,一起说明
書き込み絵は、ここで説明しました
从框图中可以看出,VDMA核主要由控制和状态寄存器、数据搬运模块、行缓冲构成,数据通过行缓冲缓存和数据搬运模块进出 DDR,实现读写数据,几个和外界通信的重要接口:
AXI4-Lite 接口(S_AXI_LITE) : PS通过该接口对VDMA实现配置
AXI4 Memory Map 读接口(M_AXI_MM2S) : 存储器的读接口(映射到存储器读)
AXI4 Memory Map 写接口(M_AXI_S2MM) : 存储器的写接口(映射到存储器写)
AXI4-S 主接口(M_AXIS_MM2S) : 存储器读出图像到AXI-S视频流
AXI4-S 从接口(S_AXIS_S2MM) : AXI-S视频流写入图像到存储器

主要引脚:

引脚信号 功能
s_axi_lite_aclk s_axi_lite接口的时钟
m_axi_mm2s_aclk m_axi_mm2s接口的时钟
m_axi_s2mm_aclk m_axi_s2mm的时钟
m_axis_mm2s_aclk m_axis_mm2s的时钟
s_axis_s2mm_aclk s_axis_s2mm的时钟
axi_resetn 核的复位信号(至少16个s_axi_lite_aclk,低有效)
mm2s_introut mm2s通道的中断输出
s2mm_introut s2mm通道的中断输出

视频同步接口信号:

信号 功能
mm2s_fsync帧同步信号 使能该信号后,VDMA操作始于 mm2s_fsync每个下降沿(该信号至少持续一个 m_axis_mm2s_aclk 时钟周期)
s2mm_fsync帧同步信号 使能该信号后,VDMA操作始于 s2mm_fsync每个下降沿(该信号至少持续一个 s_axis_s2mm_aclk时钟周期)

GenLock相关信号:

信号 功能
mm2s_frame_ptr_in mm2s帧编号的输入
mm2s_frame_ptr_out 当前mm2s的帧编号输出
s2mm_frame_ptr_in s2mm帧编号的输入
s2mm_frame_ptr_out 当前s2mm的帧编号输出

2>常用寄存器
寄存器都是小端格式:
書き込み絵は、ここで説明しました
MM2S,也就是从DDR中读数据:

寄存器名称 偏移地址 功能
MM2S_VDMACR 00h MM2S VDMA控制寄存器
MM2S_VDMASR 04h MM2S VDMA状态寄存器
MM2S_START_ADDRESS 5C~98h MM2S帧存起始地址(1~16)
MM2S_FRMDLY_STRIDE 58h MM2S帧延迟和跨度寄存器
MM2S_HSIZE 54h MM2S 水平方向显示大小寄存器
MM2S_VSIZE 50h MM2S 垂直方向显示大小寄存器

类似的S2MM(往DDR写数据):

寄存器名称 偏移地址 功能
S2MM_VDMACR 30h S2MM VDMA控制寄存器
S2MM_VDMASR 34h S2MM VDMA状态寄存器
S2MM_START_ADDRESS AC~E8h S2MM帧存起始地址(1~16)
S2MM_FRMDLY_STRIDE A8h S2MM 帧延迟和跨度寄存器
S2MM_HSIZE A4h S2MM 水平方向显示大小寄存器
S2MM_VSIZE A0h S2MM 垂直方向显示大小寄存器
PARK_PRT_REG 28h MM2S 和 S2MM Park 指针寄存器

以MM2S为例大致说明重要寄存器的配置:
1>MM2S_VDMACR(00h)
MM2S的控制寄存器,重要的在后四位
書き込み絵は、ここで説明しました

bit位 名称 功能
3 GenlockEn 1=使能Genlock或动态Genlock同步(仅当GUI配置Genlock Mode为Slave、Dynamic-Master或Dynamic-Slave,此位才起作用)
2 Reset 1=复位MM2S通道
1 Circular_Park 0=park模式:缓存页停留在PARK_PTR_REG.RdFrmPntrRef 指定的位置;1=Circular模式:循环切换缓存页
0 RS 1=运行;0=停止

注:具体可以查看手册PARK_PTR_REG(28h)寄存器,使用park模式,可以通过操作RdFrmPtrRef和WrFrmPtrRef,实现帧缓存任意切换

2>MM2S_VDMASR(04h)
書き込み絵は、ここで説明しました
重要的是bit0:Halted位,指示VDMA是否停止运行(1=停止),只读

3> MM2S_START_ADDRESS (5C~98h)

    Xil_Out32((VDMA_BASEADDR + 0x5c), VIDEO_BASEADDR0);
    Xil_Out32((VDMA_BASEADDR + 0x60), VIDEO_BASEADDR1); 
    Xil_Out32((VDMA_BASEADDR + 0x64), VIDEO_BASEADDR2);
  
  

用于存放帧存的起始地址,上述代码为只有3个帧存时的配置
帧存最多可以达到32个,但是5C~98h只够写16个,于是就需要配合MM2S_REG_INDEX(14h)寄存器,MM2S_REG_INDEX=1时:5Ch就是第17个帧存的起始地址

4> MM2S_FRMDLY_STRIDE(58h)
MM2S帧延迟(24-28bit)和跨度(0-15bit)寄存器
書き込み絵は、ここで説明しました
帧延迟:( Genlock Mode为Slave时有效),指定从接口比主接口至少要延迟多少个帧
跨度:相邻两行的第一个像素间的距离

5> MM2S_HSIZE(54h)和MM2S_VSIZE(50h)
假如是RGB 800*600(每个像素点3个字节)
MM2S_HSIZE用于指定一行有多少字节:800*3
MM2S_VSIZE用于指定有多少行:600(配置完就开始工作,所以对这个寄存器的配置,必须放在最后)

往DDR写数据的S2MM的相关寄存器与这些类似,具体的查看手册
3>SDK配置
初始化配置的关键代码:

/*  帧存地址参数  */
#define DDR_BASEADDR    0x00000000
#define VIDEO_BASEADDR0 0x01000000
#define VIDEO_BASEADDR1 DDR_BASEADDR + 0x3000000
#define VIDEO_BASEADDR2 DDR_BASEADDR + 0x4000000
/*  分辨率参数800*600分辨率  */
#define H_STRIDE            800
#define H_ACTIVE            800
#define V_ACTIVE            600
/*****************往DDR写数据设置**********************/
Xil_Out32((VDMA_BASEADDR + 0x030), 0x00000003);//使能循环模式
Xil_Out32((VDMA_BASEADDR + 0x0AC), VIDEO_BASEADDR0);//帧存0地址
Xil_Out32((VDMA_BASEADDR + 0x0B0), VIDEO_BASEADDR1);//帧存1地址
Xil_Out32((VDMA_BASEADDR + 0x0B4), VIDEO_BASEADDR2);//帧存2地址
Xil_Out32((VDMA_BASEADDR + 0x0A8), (H_STRIDE*4));   //跨度设置(800 * 4) bytes
Xil_Out32((VDMA_BASEADDR + 0x0A4), (H_ACTIVE*4));   //行宽设置(800* 4) bytes
Xil_Out32((VDMA_BASEADDR + 0x0A0), V_ACTIVE);       //行数设置(600)
/*****************从DDR读数据设置**********************/
Xil_Out32((VDMA_BASEADDR + 0x000), 0x3);//使能循环模式
Xil_Out32((VDMA_BASEADDR + 0x05c), VIDEO_BASEADDR0);//帧存0地址
Xil_Out32((VDMA_BASEADDR + 0x060), VIDEO_BASEADDR1);//帧存1地址
Xil_Out32((VDMA_BASEADDR + 0x064), VIDEO_BASEADDR2);//帧存2地址
Xil_Out32((VDMA_BASEADDR + 0x058), (H_STRIDE*4));   //跨度设置(800 * 4) bytes
Xil_Out32((VDMA_BASEADDR + 0x054), (H_ACTIVE*4));   //行宽设置(800* 4) bytes
Xil_Out32((VDMA_BASEADDR + 0x050), V_ACTIVE);       //行数设置(600)
  
  

4>GUI配置
第一页:
書き込み絵は、ここで説明しました

选项 功能
Address Width DDR地址线宽度
Frame Buffers 帧缓存的数量
Memory Map Data Width VDMA与DDR控制器的AXI总线宽度
Write Burst Size 写猝发大小(在一次写猝发中,每一时钟节拍内传输数据字节的最大字节数),详见AXI4具体协议
Stream Data Width AXI4-S流的数据宽度
Line Buffer Depth Line Buffer的深度
读通道的各选项 与写通道类似

第二页:
書き込み絵は、ここで説明しました

选项 功能
Enable Asynchronous Mode 开启异步模式(各工作时钟异步),同步模式下时钟必须同源
Enable Vertical Flip S2MM有效时,垂直翻转图像
Fsync Options 帧同步设置
None:自由运行模式下,视频数据尽可能快地被转移,不用等待外部触发。
s2mm fsync:VDMA在s2mm_fsync输入信号的下降沿,开始一帧的工作
s2mm tuser:写通道的s_axis_s2mm_tuser(0)信号作为帧起始信号
Genlock Mode 同步锁相模式【注】
Allow Unaligned Transfers 是否允许非对齐传输(选中,允许数据重新对齐;否则,起始地址宽度必须与写存储器映射数据宽度字节的倍数对齐)
读通道的各选项 与写通道类似

【注】同步锁相模式:
四种方式,以S2MM(写通道为例),读通道可以类比出来
1>Master模式
该通道不会跳过或重复任一帧数据,并把当前帧的编号输出到s2mm_frame_ptr_out 端口。
通道不会检测 s2mm_frame_ptr_in端口提供的帧编号。
Slave通道应跟随Master通道变化,但有一定的延迟。延迟大小预定义在寄存器s2mm_frmdly_stride[28:24]

2>Slave模式
该通道会通过跳过或重复一些帧的方式,尝试与Master同步,会对s2mm_frame_ptr_in 端口进行采样,获取Master的帧编号,为了实现状态反馈,通道会把当前帧的编号输出到s2mm_frame_ptr_out 端口
指定通道工作在Slave模式,必须进行如下操作:

  • 将 GenlockEn置位(S2MM_VDMACR[3]=1),使能主从通道间的 Genlock 同步
  • 将 GenlockSrc置位(S2MM_VDMACR[7]=1),使能内部 Genlock 模式
    如果在GUI配置中同时使能读写通道,该位默认置位
    当 GenlockSRC置位时,VDMA 默认支持内部同步锁相总线(就没有必要在外部对帧指针端口 *_frame_ptr_out 和 *_frame_ptr_in进行连接了)
  • 根据主从通道的帧率,使用 s2mm_frmdly_stride[28:24]设定合适的延迟时间。

3>动态Master模式
动态 MasterMaster的区别在于,主通道会跳过从通道正在操作的帧。动态 Master检测到Slave正在操作某帧的话,就会跳过该帧,在其他帧缓存中循环操作

4>动态Slave模式
Dynamic Slave通道会操作Dynamic Master通道上一周期操作的帧,当动态 Slave比Master慢的时候,Slave会适当跳过一些帧

将在下一篇ZYNQ基础系列(四)中完成一个简单视频通路的搭建

ZYNQ基础系列(四)VTC+VDMA+Vid_Out核 开始构建一个简单的显示通路

https://blog.csdn.net/long_fly/article/details/79066302

ZYNQ7010把SD卡的图片显示到HDMI

ZYNQ基础系列(三)中有相关IP核的初步介绍,在已有的基础上可以搭建一个基础的显示通路了
实验目的:在Mi701N开发板的基础上,驱动800*600的显示屏输出图片(图片文件[.bin文件]存放SD卡中)

一、PL部分实现

大体框图:
書き込み絵は、ここで説明しました

  • AXI接口连接模块和复位模块是通过自动生成的
  • rgb2dvi模块:用于IO口输出HDMI信号 [在ZYNQ基础系列(二)],也可以不加该模块直接以VGA形式输出,或者加一个驱动HDMI芯片的IP核输出
  • PS模块:注意根据板子具体情况设置PS时钟和PL时钟以及DDR型号
  • CLOCK模块:PS倍频到100M的时钟输出(图中红色线)作为CLOCK模块的输入,由于分辨率是800*600的,所以时钟clock1输出40M,clock2是clock1的5倍,200M,(两个输出时钟,图中青色线),该模块的lock信号作为显示通路的复位信号
  • VTC、VDMA和Vid_Out核的配置,和上一文中的一样

二、制作图片文件

Image2Lcd工具
書き込み絵は、ここで説明しました
按照如上设置,将.bin图片文件,导出

三、SDK部分实现

初始化:首先PS通过AXI总线配置PL的工作模式
工作:从SD卡中读取图片文件,然后PS将图片数据写入DDR,PL不断从DDR中读取数据,然后通过视频通路,显示在屏幕上

设置开启xilinx自带的文件系统的库:
書き込み絵は、ここで説明しました
如图将xilffs勾选(否则提示找不到 ff.h 文件):
書き込み絵は、ここで説明しました
勾选此库之后,就可以使用文件系统相关的函数了
等下的代码中,SD_InitSD_Transfer_read分别是初始化SD卡和读取SD卡中的文件内容(.bin文件)

将读取的.bin数据存到DDR中:
等下的代码中,show_img函数,将完成数据存到DDR相应地址的操作

对PL中的VDMA的配置:
通过PS完成对VDMA的初始化,详先上一文

PS完整代码:

#include "xaxivdma.h"
#include "xaxivdma_i.h"
#include "sleep.h"

#include <string.h>
#include "xparameters.h"
#include "xil_printf.h"
#include "ff.h"
#include "xdevcfg.h"

#define DDR_BASEADDR        0x00000000
#define VDMA_BASEADDR       XPAR_AXI_VDMA_0_BASEADDR
#define H_STRIDE            800
#define H_ACTIVE            800
#define V_ACTIVE            600

#define VIDEO_BASEADDR0 DDR_BASEADDR + 0x1000000
#define VIDEO_BASEADDR1 DDR_BASEADDR + 0x2000000
#define VIDEO_BASEADDR2 DDR_BASEADDR + 0x3000000

void Xil_DCacheFlush(void);

unsigned char picture1[800*600*3]={0};
static FATFS fatfs;

void show_img(u32 x, u32 y, u32 disp_base_addr, unsigned char * addr, u32 size_x, u32 size_y)
{
    u32 i=0;
    u32 j=0;
    u32 r,g,b;
    u32 start_addr=disp_base_addr;
    start_addr = disp_base_addr + 4*x + y*4*H_STRIDE;
    for(j=0;j<size_y;j++)
    {
        for(i=0;i<size_x;i++)
        {
            b = *(addr+(i+j*size_x)*3+0);
            g = *(addr+(i+j*size_x)*3+1);
            r = *(addr+(i+j*size_x)*3+2);
            Xil_Out32((start_addr+(i+j*H_STRIDE)*4),((r<<16)|(g<<8)|(b<<0)|0x0));
        }
    }
    Xil_DCacheFlush();
}

int SD_Init()
{
    FRESULT rc;
    rc = f_mount(&fatfs,"",0);
    if(rc)
    {
        xil_printf("ERROR : f_mount returned %d\r\n",rc);
        return XST_FAILURE;
    }
    return XST_SUCCESS;
}
int SD_Transfer_read(char *FileName,u32 DestinationAddress,u32 ByteLength)
{
    FIL fil;
    FRESULT rc;
    UINT br;
    rc = f_open(&fil,FileName,FA_READ);
    if(rc)
    {
        xil_printf("ERROR : f_open returned %d\r\n",rc);
        return XST_FAILURE;
    }
    rc = f_lseek(&fil, 0);
    if(rc)
    {
        xil_printf("ERROR : f_lseek returned %d\r\n",rc);
        return XST_FAILURE;
    }
    rc = f_read(&fil, (void*)DestinationAddress,ByteLength,&br);
    if(rc)
    {
        xil_printf("ERROR : f_read returned %d\r\n",rc);
        return XST_FAILURE;
    }
    rc = f_close(&fil);
    if(rc)
    {
        xil_printf(" ERROR : f_close returned %d\r\n", rc);
        return XST_FAILURE;
    }
    return XST_SUCCESS;
}

int main(void)
{
    u32 i;
    xil_printf("Starting the first VDMA \n\r");

    //VDMA configurateAXI VDMA0
    /*****************往DDR写数据设置**********************/
    //Xil_Out32((VDMA_BASEADDR + 0x030), 0x3);// enable circular mode
    //Xil_Out32((VDMA_BASEADDR + 0x0AC), VIDEO_BASEADDR0);  // start address
    //Xil_Out32((VDMA_BASEADDR + 0x0B0), VIDEO_BASEADDR1);  // start address
    //Xil_Out32((VDMA_BASEADDR + 0x0B4), VIDEO_BASEADDR2);  // start address
    //Xil_Out32((VDMA_BASEADDR + 0x0A8), (H_STRIDE*4));     // h offset (800 * 4) bytes
    //Xil_Out32((VDMA_BASEADDR + 0x0A4), (H_ACTIVE*4));     // h size (600 * 4) bytes
    //Xil_Out32((VDMA_BASEADDR + 0x0A0), V_ACTIVE);         // v size (600)
    /*****************从DDR读数据设置**********************/
    Xil_Out32((VDMA_BASEADDR + 0x000), 0x3);        // enable circular mode
    Xil_Out32((VDMA_BASEADDR + 0x05c), VIDEO_BASEADDR0);    // start address
    Xil_Out32((VDMA_BASEADDR + 0x060), VIDEO_BASEADDR1);    // start address
    Xil_Out32((VDMA_BASEADDR + 0x064), VIDEO_BASEADDR2);    // start address
    Xil_Out32((VDMA_BASEADDR + 0x058), (H_STRIDE*4));       // h offset (800 * 4) bytes
    Xil_Out32((VDMA_BASEADDR + 0x054), (H_ACTIVE*4));       // h size (800 * 4) bytes
    Xil_Out32((VDMA_BASEADDR + 0x050), V_ACTIVE);           // v size (600)

    for(i=0;i<H_STRIDE*H_ACTIVE;i++)
    {
        Xil_Out32(VIDEO_BASEADDR0+i,0);
    }

    SD_Init();
    SD_Transfer_read("test.bin",(u32)picture1,800*600*3+1);

    while(1)
    {
        show_img(0,0,VIDEO_BASEADDR0,&picture1[0],800,600);
        show_img(0,0,VIDEO_BASEADDR1,&picture1[0],800,600);
        show_img(0,0,VIDEO_BASEADDR2,&picture1[0],800,600);
        sleep(5);
    }
    return 0;
}
  
  

四、实验现象

書き込み絵は、ここで説明しました

公開された42元の記事 ウォンの賞賛148 ビュー410 000 +

おすすめ

転載: blog.csdn.net/baidu_37503452/article/details/104999352