显示recv调用次数_【正点原子FPGA连载】第十二章HDMI彩条显示实验--摘自达芬奇之Microblaze 开发指南...

1)实验平台:正点原子达芬奇FPGA开发板

2) 摘自【正点原子】达芬奇之Microblaze 开发指南

3)购买链接:https://detail.tmall.com/item.htm?id=624335496505

4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/fpga/zdyz_dafenqi.html

5) 正点原子官方B站:https://space.bilibili.com/394620890

6)对正点原子FPGA感兴趣的同学可以加群讨论:876744900

第十二章HDMI彩条显示实验


在上一章中我们介绍了使用MicroBlaze软核处理器在LCD液晶屏上显示彩条的方法,本章将介绍如何使用MicroBlaze处理器在HDMI显示屏上显示出彩条。本章包括以下几个部分:
1212.1 简介
12.2 实验任务
12.3 硬件设计
12.4 软件设计
12.5 下载验证
12.1简介
本章实验将在第十一章的基础上进行设计,由于使用HDMI屏幕而非LCD屏幕显示彩条,所以驱动模块要将LCD_RGB_TOP替换为HDMI_COLORBAR_TOP。本实验不涉及传输参数lcd_id进行突发次数的判断,所以AXI4_DDR_READ IP核要去除lcd_id信号和相关逻辑并重新封装。因为去除lcd_id而且没有其他参数传递,因此可以删除参数传递模块AXI4_Lite_COMM。
由于本次实验将使用第十章封装的HDMI_COLORBAR_TOP IP核来驱动HDMI屏显示彩条,所以会同时验证HDMI_COLORBAR_TOP IP核是否封装正确可用。
12.2实验任务
本章的实验任务是使用Microblaze处理器向DDR3中写彩条,然后通过自定义的具有AXI接口的IP核将彩条数据从DDR3中读出来,并在与开发板上两个HDMI接口相连的分辨率为640*480@60Hz的HDMI显示器上显示出彩条。
12.3硬件设计
根据实验任务我们可以画出本次实验的系统框图,如下图所示:

4151a8cd46f4bba66b9d5f6b386e0ca8.png

图 12.3.1 系统架构图


由上图可知,本章实验由MicroBlaze软核处理器将彩条数据写入外部DDR3中,然后数据被具有AXI4协议只读功能的模块读出并缓存在FIFO中,最后驱动模块驱动数据在HDMI显示屏显示彩条。与第十一章相比,系统没有从外部传入参数,因此没有调用参数传递模块AXI4_Lite_COMM。
自定义AXI4_DDR_READ IP核从DDR3中读取彩条显示数据并写入缓存FIFO。由于本实验分辨率指定为640*480,所以AXI4_DDR_READ IP核的图像的突发次数需要指定为640*480*16/32/256 = 600。
HDMI_COLORBAR_TOP IP核用于从缓存FIFO中获取16位的RGB565格式的彩条数据,并将其转化成24位的RGB888格式的数据后传递给HDMI显示屏。该IP核可依据实际需要灵活设置分辨率相关的参数,本实验指定分辨率为640*480@60Hz。
接下来在第十一章的基础上进行硬件设计。
由于本实验需要驱动HDMI显示屏,分辨率指定为640*480@60Hz,所以AXI4协议内的突发次数需要指定为固定值,因此在进行硬件系统设计之前,我们先对第十一章封装好的AXI4_DDR_READ IP核进行简单的修改并重新封装。首先打开“RGB LCD彩条显示实验”的Vivado工程,打开后依次点击菜单栏的“File->Project->Save As...”,将工程名改为“hdmi_colorbar_top”,如下图所示:

82532b6307bf96e9300cc6bb944a81cf.png

图 12.3.2 工程命名


新建工程后,依次点击“Tools->Setting…->IP->Repository”,由于此工程由其他工程通过“另存为”的方式创建的,该工程路径下并没有下图中的几个IP核,所以我们需要将它们的路径删除。选中IP核并点击红框内的“-”,如下图所示:

a35bf43d2c8d20b59cde0e1dc9418340.png

图 12.3.3 删除原先IP核路径


在工程路径下新建ip_repo文件夹,拷贝第十一章封装的axi4_ddr_read IP核到此文件夹下,拷贝后如下图所示:

94f20dbe49b6a841d901c1e7b0c9d6ec.png

图 12.3.4 拷贝IP核


紧接着回到IP核加载界面,并添加该IP核至工程,如下图所示:

097e027f9b1992bde996f99658aa3609.png

图 12.3.5 添加IP核路径


接下来点击工程左侧的“Open Block Design”,在Diaream窗口中右键axi4_ddr_read_0模块,选择“Edit IP Package”,如下图所示:

4d4a086354c753f892039f7cd81f84cd.png

图 12.3.6 编辑IP核


在弹出的界面点击“OK”,工程名字和路径自动填充,继续点击“OK”,如下图所示:

628bc3784a412044a6d5f393990f8e4e.png

图 12.3.7 工程名和路径


稍等片刻,软件自动打开封装IP工程,点击下图红框关闭当前(代码修改前)封装界面,如下图所示:

d8ba2ae12e710de39ce1f5afeb2a9cc6.png

图 12.3.8 关闭封装界面


使用Notepad++打开上图中两个模块文件,路径如下图所示:

895e803032191b222cb7fac3413b164b.png

图 12.3.9 模块文件路径


由于本次实验指定HDMI分辨率为640*480@60Hz,所以无需由LCD屏幕的lcd_id来计算突发次数,将突发次数设为固定值即可。修改前计算突发次数的代码如下图所示:

ea0f2423f1f695b377e8c07f5210d0f0.png

图 12.3.10 突发次数修改前


修改后指定分辨率640*480的突发次数代码如下图所示:

e98936eb61034a3c3965271589f7a567.png

图 12.3.11 分辨率640*480的突发次数


修改固定分辨率的突发次数代码后,接着再删除两个模块的lcd_id相关的端口代码,然后保存。(注意,为避免大家在修改时遗漏或者错误导致后续封装的IP核不能正常使用,所以建议使用例程中的代码文件封装IP核或使用例程中封装好的IP核进行设计)
回到IP封装工程,选中顶层模块,然后右键,点击“Refresh Hierarchy”进行刷新,接着点击左侧“Edit IP Package”重新打开封装界面(代码修改后的封装界面),如下图所示:

8a9f9d9dc45c8b0db47a7d0d6154aa92.png

图 12.3.12 刷新并重新打开封装界面


重新打开封装IP核后界面如下图所示:

53174622d525c42466d1e3dd8b6aacf0.png

图 12.3.13 封装IP新界面


由于是在原先IP核上进行修改,故可以跳至“Customization Parameters”界面刷新变量,如下图所示:

304a48d889a6de6a5bfddb9957748ba0.png

图 12.3.14 刷新变量


接下来在“Ports and interface”界面中可以发现lcd_id端口被移除,如下图所示:

1927a151de64659aa78352617ae09f72.png

图 12.3.15 IP核端口与接口


最后,在“Review and Package”界面点击“Package IP”重新封装IP,如下图所示:

735bcb52769d7b50a3ce09c972f743e7.png

图 12.3.16 重新封装IP核


接着刷新IP核路径,在IP核加载界面依次点击“Refresh All->Apply->OK”,如下图所示:

ffe42a102702870c1dce60f54a0dd39a.png

图 12.3.17 刷新IP核路径


刷新路径之后,点击“Report IP Status”,如下图所示:

19d36f943de5854a25cbb592855b7cbf.png

图 12.3.18 Report IP Status


接着在下方IP Status下可以看到系统内被修改的IP核axi_ddr_read_0,两个找不到定义的IP核axi_lite_comm_0和lcd_rgb_top_0(因为前面将路径删除了),如下图所示:

6df484c5cdd2be6f4752131bc71fdb5f.png

图 12.3.19 IP Status


在此,我们对修改的IP核进行升级,其他两个IP核在后面会进行处理。取消勾选“Others(2)”,保留选中“Revision Change”,点击“Upgrade Seleted”对修改的IP核进行升级,如下图所示:

f5517bd1ea4cc8a6e4b2178f69ee6389.png

图 12.3.20 IP升级


弹出“IP Upgrade Compeleted”即表明IP核升级完成,点击“OK”,如下图所示:

b1326effe6312dd9a326a36ad86bdcef.png

图 12.3.21 升级完成提示


继续点击“Skip”,暂时跳过IP核编译步骤。因为升级IP核之后,还要继续进行硬件设计,所以暂时可以不用对升级的IP核进行编译,等到设计完成后再进行编译也不迟。如下图所示:

cb863627c48c731df2ce0e28bb69772b.png

图 12.3.22 跳过IP编译


回到Diagram窗口,观察IP核axi_ddr_read_0可以发现,红标处原先存在的lcd_id信号接口已经消失了,说明升级后的新IP核已经生效。保持当前连线不做修改即可,如下图所示:

5a2318fd14a124be0a0abc5cfb771ac3.png

图 12.3.23 新IP核生效


双击axi4_ddr_read_0,参数C_M_AXI_TARGET_SLAVE_BASE_ADDR为DDR3读彩条起始地址,我们在此将值设置为0x85000000(在后续软的件设计中,MicroBlaze写彩条数据的起始地址需要设置同样值),点击“OK”,如下图所示:

3c178beeeefabec9bf32359fbecf5155.png

图 12.3.24 写数据地址


由于本实验指定HDMI分辨率为640*480@60Hz,所以需要修改FIFO读时钟和像素时钟。在该分辨率下需要设置的时钟值参考下图中的第一行:

449dad033c14271713e095c0efa87658.png

图 12.3.25 各分辨率下时钟和参数


双击clk_wize_1,勾选clk_out4(5倍像素时钟),并将clk_out3、clk_out4分别设置为25.175MHz和125.875MHz,然后点击“OK”,如下图所示:

19c51bff619d05cf51ebf6aed60b6ee9.png

图 12.3.26 时钟设置


接着点击选中FIFO的读时钟“rd_clk”,并右键选择“Disconnect Pin”断开FIFO读时钟连线,然后将其连接至clk_out3。连接后如下图所示:

9d3279a4580303eaaa2b882799be4525.png

图 12.3.27 FIFO读时钟


由于本实验通过HDMI显示彩条,所以无需传递参数lcd_id,选中axi4_lite_comm_0,右键并选择“Delete”删除该IP核,如下图所示:

efc611e02bac8d6fd8eb611248d93404.png

图 12.3.28 删除axi4_lite_comm IP核


接下来,使用第十章封装完成的用于驱动HDMI屏幕显示彩条的HDMI_COLORBAR_TOP IP核来代替lcd_rgb_top模块。从第十章拷贝该IP核至本实验ip_repo文件夹下,拷贝后IP核位置如下图所示:

6514046f8784a8423cafc88512ef25c2.png

图 12.3.29 拷贝IP核


将其添加至工程中,如下图所示:

a24c7915bc57bb6434fa490fc532d580.png

图 12.3.30 添加IP核至工程


选中系统中的lcd_rgb_top模块和它引出的管脚,右键并选择“Delete”,如下图所示:

b741f1a6ca48a4dc9f03f4b049cce1f5.png

图 12.3.31 删除原模块


在弹出的提示界面中,删除项目中包含了该模块和它的接口与端口,点“OK”,如下图所示:

bc60cabd5ead771ba2a4937933ded5cd.png

图 12.3.32 删除提示


在Diagram窗口搜索HDMI_COLORBAR_TOP IP核,然后并双击添加至硬件系统,如下图所示:

09d0f64dc4c12664a2a0a05f7685c122.png

图 12.3.33 添加HDMI_COLORBAR_TOP IP核


接着添加连线和引出信号:复位信号sys_rst_n连接时钟模块的locked信号,DDR3初始化完成信号ddr_init_done接MIG核的init_calib_complete信号,时钟pixel_clk、pixel_clk_5x分别连接时钟模块的clk_out3和clk_out4,data_req和data_in与FIFO读接口连接,分别引出TMDS、TMDS1、tmds_oen、tmds_oen1并改名为hdmi_out0、hdmi_out1、tmds_oen0、tmds_oen1。连线和引出信号后如下图所示:

11d9e00d1c762af78a3931044b108057.png

图 12.3.34 HDMI_COLORBAR_TOP连接图


验证无误后,保存设计。最后搭建的硬件系统如下图所示:

cdc2a7fac0c3ee3e06ab50537abf0bca.png

图 12.3.35 最终布局图


在Source窗口中右键点击Block Design设计文件“system.bd”,然后执行“Generate Output Products”,编译IP时选择“Global”,编译完成后执行“Create HDL Wrapper”。
紧接着添加约束文件:打开system_wrapper.xdc文件删除之前的约束文件,添加如下管脚约束:

  1. create_clock -period 20.000 -name sys_clk [get_ports sys_clk]
  2. set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS33} [get_ports sys_clk]
  3. set_property -dict {PACKAGE_PIN U2 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]
  4. #UART
  5. set_property -dict {PACKAGE_PIN U5 IOSTANDARD LVCMOS33} [get_ports UART_rxd]
  6. set_property -dict {PACKAGE_PIN T6 IOSTANDARD LVCMOS33} [get_ports UART_txd]
  7. #--------------------------------HDMI_A-----------------------------------------
  8. set_property PACKAGE_PIN B20 [get_ports {hdmi_out0_tmds_data_p[2]}]
  9. set_property PACKAGE_PIN B21 [get_ports {hdmi_out0_tmds_data_p[1]}]
  10. set_property PACKAGE_PIN C22 [get_ports {hdmi_out0_tmds_data_p[0]}]
  11. set_property IOSTANDARD TMDS_33 [get_ports {hdmi_out0_tmds_data_p[2]}]
  12. set_property IOSTANDARD TMDS_33 [get_ports {hdmi_out0_tmds_data_p[1]}]
  13. set_property IOSTANDARD TMDS_33 [get_ports {hdmi_out0_tmds_data_p[0]}]
  14. set_property PACKAGE_PIN C18 [get_ports hdmi_out0_tmds_clk_p]
  15. set_property IOSTANDARD TMDS_33 [get_ports hdmi_out0_tmds_clk_p]
  16. set_property -dict {PACKAGE_PIN E21 IOSTANDARD LVCMOS33} [get_ports tmds_oen0]
  17. set_property IOSTANDARD LVCMOS33 [get_ports tmds_oen0]
  18. #--------------------------------HDMI_B----------------------------------------
  19. set_property PACKAGE_PIN A13 [get_ports {hdmi_out1_tmds_data_p[2]}]
  20. set_property PACKAGE_PIN A15 [get_ports {hdmi_out1_tmds_data_p[1]}]
  21. set_property PACKAGE_PIN A18 [get_ports {hdmi_out1_tmds_data_p[0]}]
  22. set_property IOSTANDARD TMDS_33 [get_ports {hdmi_out1_tmds_data_p[2]}]
  23. set_property IOSTANDARD TMDS_33 [get_ports {hdmi_out1_tmds_data_p[1]}]
  24. set_property IOSTANDARD TMDS_33 [get_ports {hdmi_out1_tmds_data_p[0]}]
  25. set_property PACKAGE_PIN B17 [get_ports hdmi_out1_tmds_clk_p]
  26. set_property IOSTANDARD TMDS_33 [get_ports hdmi_out1_tmds_clk_p]
  27. set_property -dict {PACKAGE_PIN C20 IOSTANDARD LVCMOS33} [get_ports tmds_oen1]
  28. set_property IOSTANDARD LVCMOS33 [get_ports tmds_oen1]
  29. #SPI
  30. set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
  31. set_property CONFIG_MODE SPIx4 [current_design]
  32. set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
  33. set_property CFGBVS VCCO [current_design]
  34. set_property CONFIG_VOLTAGE 3.3 [current_design]
  35. set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design]


管脚分配完成后按快捷键“Ctrl+S”保存管脚约束。点击“Generate Bitstream”,对设计进行综合、实现、并生成Bit文件。
至此,本实验的硬件设计已经全部完成。Bit文件生成后导出至工程的vitis文件夹,并启动Vitis。
12.4软件设计
打开Vitis开发环境后,创建应用工程的步骤都是一样的,这里不再赘述,新创建的空白应用工程命名为“hdmi_colorbar”。然后为应用工程新建一个源文件“main.c”,我们在新建的main.c文件中输入本次实验的代码,代码如下所示:

  1. 48 #include <stdio.h>
  2. 49 #include "platform.h"
  3. 50 #include "xil_printf.h"
  4. 51 #include "xparameters.h"
  5. 52 #include "xil_cache.h"
  6. 53
  7. 54 //宏定义
  8. 55 #define BYTES_PIXEL 2
  9. 56
  10. 57 //函数声明
  11. 58 void colorbar(u8 *frame, u32 width, u32 height, u32 stride);
  12. 59
  13. 60 unsigned int const frame_buffer_addr = (XPAR_MIG_7SERIES_0_BASEADDR);
  14. 61
  15. 62 int main()
  16. 63 {
  17. 64 //分辨率640*480的width height参数设置
  18. 65 u16 hor_res = 0x280,ver_res = 0x1E0;
  19. 66
  20. 67 init_platform();
  21. 68
  22. 69 //写彩条
  23. 70 colorbar((u8*)frame_buffer_addr, hor_res, ver_res, hor_res*BYTES_PIXEL);
  24. 71
  25. 72 cleanup_platform();
  26. 73 return 0;
  27. 74 }
  28. 75
  29. 76 //写彩条函数
  30. 77void colorbar(u8 *frame, u32 width, u32 height, u32 stride)
  31. 78{
  32. 79 u32 color_edge, colorbar_2, colorbar_3, colorbar_4, colorbar_5;
  33. 80 u32 x_pos, y_pos;
  34. 81 u32 y_stride = 0;
  35. 82 u16 rgb = 0;
  36. 83
  37. 84 color_edge = width * BYTES_PIXEL / 5;
  38. 85 colorbar_2 = color_edge * 2;
  39. 86 colorbar_3 = color_edge * 3;
  40. 87 colorbar_4 = color_edge * 4;
  41. 88 colorbar_5 = color_edge * 5;
  42. 89
  43. 90 //开始写彩条
  44. 91 xil_printf("write color star rn");
  45. 92 for (y_pos = 0; y_pos < height; y_pos++) {
  46. 93 for (x_pos = 0; x_pos < width * BYTES_PIXEL; x_pos += BYTES_PIXEL) {
  47. 94 if (x_pos < color_edge) { //白色
  48. 95 rgb = 0xffff;
  49. 96 } else if ((x_pos >= color_edge) && (x_pos < colorbar_2)) { //黑色
  50. 97 rgb = 0x0;
  51. 98 } else if ((x_pos >= colorbar_2) && (x_pos < colorbar_3)) { //红色
  52. 99 rgb = 0xf800;
  53. 100 } else if ((x_pos >= colorbar_3) && (x_pos < colorbar_4)) { //绿色
  54. 101 rgb = 0x07e0;
  55. 102 } else if ((x_pos >= colorbar_4) && (x_pos < colorbar_5)) { //蓝色
  56. 103 rgb = 0x001f;
  57. 104 }
  58. 105 frame[x_pos + y_stride + 0] = rgb;
  59. 106 frame[x_pos + y_stride + 1] = rgb>>8;
  60. 107 }
  61. 108 y_stride += stride;
  62. 109 }
  63. 110 Xil_DCacheFlush(); //刷新Cache,数据更新至DDR3中
  64. 111 xil_printf("show color barrn");
  65. 112}


与第十一章代码不同的是,本试验代码不需要获取lcd_id以及计算参数width、height,直接将width、height设为固定值即可,其余代码与第十一章的基本一致。
第60行获取写彩条的基地址,按“Ctrl”键点击宏“XPAR_MIG_7SERIES_0_BASEADDR”进入该值设置文件xparameters.h,我们将其设置为0x85000000(必须与硬件系统中axi4_ddr_read_1设置的读数据起始地址相同),点击“保存”。地址设置如下图所示:

7b69288c51c0a5862d41e94f0449cc1f.png

图 12.4.1 写彩条基地址设置


主函数中,代码第65行对分辨率640*480的width height参数进行了设置。
其余代码不再赘述,请参考第十一章代码的解释。
保存,编译整个工程,生成ELF文件。
12.5下载验证
首先我们将下载器与达芬奇开发板上的JTAG接口连接,下载器另外一端与电脑连接。然后使用USB连接线将USB_UART接口与电脑连接,用于串口通信。将HDMI线一端连接在开发板上两个HDMI接口中的任意一个,另一端连接至HDMI屏幕。最后连接开发板的电源,并打开电源开关。
打开Vitis的Terminal并连接,开始下载程序。随着程序的执行,当串口打印出“show color bar”时,证明程序执行完毕,如下图所示:

c748e1f77f4c0fa9370522c516189d01.png

图 12.5.1 程序执行完毕


在HDMI屏幕上即可看到彩条图像,如下图所示:

ad3a5fe06563f721c1f6a96a58458be1.png

图 12.5.2 HDMI屏幕彩条显示


至此,HDMI彩条显示实验完成,同时验证了第十章封装的HDMI_COLORBAR_TOP IP核正确可用。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值