Smart ZYNQ(SP&SL 版) 工程二十四 用VDMA模块来缓存图像并在HDMI上显示(二)用always分频来适配更多分辨率

本节作为上一章节的补充,用always方式来实现分频,来解决PLL在某些分辨率下无法同时提供两路1倍和5倍像素时钟的情况,以适配更多的分辨率(本文以720P来展开介绍)

(备注 此章节内容适用于 Smart ZYNQ SP和SL 版的板子,如果是Smart ZYNQ 标准版请看对应板子目录)

答疑解惑,为什么已经有PLL 可以生成多个时钟了还需要用always模块来替代?看了下面内容你就知道了

当分辨率是800X600的时候 基准像素时钟40M,5X的时钟就是200M,我们PLL里设置是可以实现的

但是如果我们分辨率需要改成 720P分辨率,那像素时钟就是74.25M, 5倍像素时钟就是371.25M, 但是我们这样设置后,实际值出来是74.219M 和371.094M ,不能满足完完全全的5倍关系,这就会造成数据的不同步,导致图像输出不稳定,这也就是我们要用always 模块去解决的原因。

为了实现不同分辨率,用PLL 来输出两个5倍关系的时钟并不一定高度同步,这边可以换个思路,用PLL 生成5倍频时钟,然后用always块来分频生成像素时钟

整体工程将在上一节的内容上进行修改 ,所以 具体操作请看上一节, 这里仅仅介绍修改的地方

修改过程如下:

1) 打开上一节 VDMA_HDMI的工程(800X600)

2)点选Add Sources –>Add or create design sources 点Next

3)点Create File ,名称写 Pixclock_divider(名称可以自己修改)点OK,然后点Finish,后面弹出的界面也点选OK 然后完成

4)双击打开我们刚才创建的 Pixclock_divider,复制以下代码到里面

`timescale 1ns / 1ps

module Pixclock_divider(
    output reg PIX_CLK_1X,
    input PIX_CLK_5X
);
    
    reg [2:0]count;
    always@(posedge PIX_CLK_5X)begin
       if(count>=3'd4)begin PIX_CLK_1X<=1'b1;count<=3'd0;end
       else begin  PIX_CLK_1X<=1'b0; count<=count+1'b1;end
    end
endmodule

程序非常好理解,相当于5倍的像素时钟 PIX_CLK_5X的时钟经过always块的5拍分频,生成了个单倍的时钟PIX_CLK_1X

之后先预编译一下看看有没有问题(一定要做,不然可能无法导入到block design)

之后点击 Open Block Design ,打开我们上一节设计的block design

PS,如果变更过项目文件夹地址,那DVI模块也可能需要重新添加一遍(具体方法如下,上一节已经提过)

如果是红色的就需要重新导入,导入方法如下

先下载模块 DVI_Transmitter下载

选择目录点select

之后点ok确认 apply 应用,然后OK推出就好

5)添加好模块后,回到刚才的界面, 将我们设计的分频模块导入到BlockDesign 里如下图所示,右键我们设计的Pixclock_divider ,然后点选Add Module to Block Design

之后系统就Block Design 的设计界面里看到我们刚刚设计的分频模块了

双击打开clock wizard模块, 关闭其中的clk_out2, 然后将clk_out1修改成 371.25M 点选ok(为什么是371.25m ,因为我们这里测试把分辨率修改成720p分辨率对应的像素时钟74.25M的5倍)

之后先删除clock模块上一个工程遗留下来连接clk_out1的信号线,如下图所示,点选红圈处删除就好

增加clk_out1信号线的连接(这个信号线即是5倍像素时钟,所以连接 DVI的 PCLK_x5 和我们刚才设计的pixclock_divider分频模块就好)

分频模块输出的就是原先单倍的像素时钟(替换原先设计里的像素时钟连接方法就好)如下图所示方式去连接

为了把hdmi显示的分辨率修改成720P,我们这里还需要修改Video Timing Controller 的参数,如下图所示,双击模块,然后将Video Mode 修改成720p即可

不知为何我这边的 HDMI OUTPUT映射显示不全(不确定大家是否会遇到这个问题,我这里删除后重新 EXTERNAL一下)

之后就显示正常了

以下是完整blockdesign的设计视图(网站上看不清楚的话,可以在工程里直接查看)

之后正常编译综合并 输出Export Hardware 即可(需要勾选include bitstream)(详细过程可以参看上一章节)

SDK软件打开后,会根据新修改的硬件进行更新, 更新后可能会报错,如果有报错的情况就右键BSP 然后Refresh(硬件修改后造成的报错,一般这样都能解决)

之后打开main.c 将上一个工程的800X600分辨率修改成1280X720

至此所有的地方都修改完成 ,正常debug 看结果就好,没问题的话,hdmi屏幕会显示和上一节一样的彩色条纹,只是分辨率变成了1280X720

以下是完整工程,大家自行下载研究

备注用相同的方法 应该也可以尝试1080p分辨率,下面是修改成720P修改成1080P的地方

1)CLK WIZARD模块的 输出时钟修改成 148.5M的5倍,也就是742.5Mhz

2)SDK 主程序中 修改分辨率的部分

修改完以上两处 就可以下载到板子上进行演示了 (我自己测试的几台显示器都是可以工作的,但是因为742.5m已经超过了clkwizard 的推荐范围, 所以不确定所有的显示器都支持板子输出的1080P,仅供大家自行测试)

以下是1080P的程序,仅供参考

另外这里仅使用了库函数的方式来初始化VDMA, 其实还可以通过Xil_Out32的方式直接通过寄存器来配置VDMA, 将在VDMA 第三节 TF卡显示的工程上进行演示

备注 :如遇到自己的工程显示不稳定的情况(1080P情况下),可尝试在时序约束向导Timing Constraints Wizard 里对单倍图像时钟进行约束(在Generated Clocks页面下),设置成5分频即可(1/5),之后再重新生成bit并且EXPORT

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注