1)实验平台:正点原子开拓者FPGA 开发板
2)摘自《开拓者FPGA开发指南》关注官方微信号公众号,获取更多资料:正点原子
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/index.html
http://weixin.qq.com/r/hEhUTLbEdesKrfIv9x2W (二维码自动识别)
第四十一章 SD卡图片显示实验(LCD显示)我们在“SD卡图片显示实验(VGA显示)”中使用FPGA开发板实现从SD卡中读取两张图片,
并通过VGA接口在显示器上循环切换显示两张图片的功能。本章我们将学习如何将SD卡中存储
的图片循环切换显示在RGB TFT-LCD液晶屏上。
本章包括以下几个部分:
41.1 SD卡-LCD图片显示简介
41.2 实验任务
41.3 硬件设计
41.4 程序设计
41.5 下载验证
SD卡-LCD图片显示简介我们在“SD卡图片显示实验(VGA显示)”中对SD卡中的图片通过VGA显示的方法作了详细
的介绍,本次实验与之类似,只是显示设备不同,因此这部分内容大家可以参考“SD卡图片显
示实验(VGA显示)”。
实验任务本节实验任务是使用FPGA开发板循环读取SD卡中存储的两张图片(bin格式图片,分辨率
为800*480),然后将图片存储在SDRAM中并通过RGB TFTLCD接口在ATK-7’RGBLCD液晶屏上循
环切换显示。
硬件设计SD卡接口部分的硬件设计请参考“SD卡读写测试实验”中的硬件设计部分。
由于SDRAM、SD卡接口和LCD接口的引脚数目较多且在前面相应的章节中已经给出它们的管
脚列表,这里不再列出管脚分配。
程序设计图 41.4.1是根据本章实验任务画出的系统框图。PLL时钟模块为其它各模块提供驱动时
钟;SD卡读取图片控制模块控制SD卡控制器的读接口;SD卡控制器从SD卡中读出图像数据,并
将读出的数据写入SDRAM控制器;最后LCD驱动模块通过SDRAM控制器读取SDRAM中存储的图片数
据并通过RGB TFT-LCD接口显示在LCD液晶屏上。
图 41.4.1 SD卡图片显示实验(LCD显示)系统框图
顶层模块的原理图如下图所示:
图 41.4.2 顶层模块原理图
FPGA顶层模块(top_sd_photo_lcd)例化了以下五个模块:PLL时钟模块(pll_clk)、SD
卡读取图片控制模块(sd_read_photo)、SD卡控制器模块(sd_ctrl_top)、SDRAM控制器模
块(sdram_top)和LCD驱动模块(lcd_driver)。
顶层模块(top_sd_photo_vga):顶层模块主要完成对其余各模块的例化,实现各模块之
间的数据交互。需要注意的是,系统初始化完成是在SD卡以及SDRAM都初始化完成后才开始拉
高的,该信号控制着SD卡读取图片控制模块的复位信号,因此SD卡读取图片控制模块是在系统
初始化完成后才工作的,防止因SD卡或者SDRAM初始化未完成导致数据错误。
PLL时钟模块(pll_clk):PLL时钟模块通过调用锁相环(PLL)IP核实现,总共输出五个
时钟,频率分别为100Mhz、100Mhz(相位偏移-75度)、50Mhz、50Mhz(相位偏移180度)和33.3Mhz。
两个100Mhz的时钟用于为SDRAM控制器模块提供驱动时钟;两个50Mhz的时钟用于为SD卡控制器
模块提供驱动时钟,其中50mhz为SD卡读取图片控制模块提供驱动时钟;33.3Mhz用于为LCD驱
动模块提供驱动时钟。
SD卡读取图片控制模块(sd_read_photo):SD卡读取图片控制模块通过控制SD卡控制器
的读接口,从SD卡中读取图像数据,并在读完一张图片后延时一段时间,再去读取另一张图片
数据,实现两张图片的循环切换读取。
SD卡控制器模块(sd_ctrl_top):SD卡控制器模块负责驱动SD卡,该模块将SD卡的SPI读
写操作封装成方便用户使用的接口。有关该模块的详细介绍请大家参考“SD卡读写测试实验”
章节。
SDRAM读写控制模块(sdram_top):SDRAM读写控制器模块负责驱动SDRAM片外存储器,缓
存图像传感器输出的图像数据。该模块将SDRAM复杂的读写操作封装成类似FIFO的用户接口,
非常方便用户的使用。
LCD驱动模块(lcd_driver):LCD驱动模输出数据请求信号用于读取SDRAM中的图片数据,
并将图片通过RGB TFT-LCD接口显示在液晶屏上。有关该模块的详细介绍请大家参考“RGB TFT
LCD彩条显示实验”。
SD卡读取图片控制模块的代码如下:
1
modulesd_read_photo
(2
inputclk
,//时钟信号
3
inputrst_n
,//复位信号,低电平有效
4
5
inputrd_busy
,//SD卡读忙信号
6
output regrd_start_en
,//开始写SD卡数据信号
7
output reg [31
: ]rd_sec_addr //读数据扇区地址
8
);9
10 //parameter define
11
parameterPHOTO_SECTION_ADDR0
=32'd8256
;//第一张图片扇区起始地址
12
parameterPHOTO_SECTION_ADDR1
=32'd9792
;//第二张图片扇区起始地址
13 //800*480/256 = 1500
14
parameterRD_SECTION_NUM
=11'd1500
;//单张图片总共读出的次数
15
16 //reg define
17
reg [1
: ]rd_flow_cnt
;//读数据流程控制计数器
18
reg [10
: ]rd_sec_cnt
;//读扇区次数计数器
19
regrd_addr_sw
;//读两张图片切换
20
reg [25
: ]delay_cnt
;//延时切换图片计数器
21
22
regrd_busy_d0
;//读忙信号打拍,用来采下降沿
23
regrd_busy_d1
;24
25 //wire define
26
wireneg_rd_busy
;//SD卡读忙信号下降沿
27
28 //*****************************************************
29 //** main code
30 //*****************************************************
31
32
assignneg_rd_busy
=rd_busy_d1
& (~rd_busy_d0
);33
34 //对rd_busy信号进行延时打拍,用于采rd_busy信号的下降沿
35
always @(posedgeclk
or negedgerst_n
) begin36
if(rst_n
==1'b0
) begin37 rd_busy_d0
<=1'b0
;38 rd_busy_d1
<=1'b0
;39
end40
else begin41 rd_busy_d0
<=rd_busy
;42 rd_busy_d1
<=rd_busy_d0
;43
end44
end45
46 //循环读取SD卡中的两张图片(读完之后延时1s再读下一个)
47
always @(posedgeclk
or negedgerst_n
) begin48
if(!rst_n
) begin49 rd_flow_cnt
<=2'd0
;50 rd_addr_sw
<=1'b0
;51 rd_sec_cnt
<=11'd0
;52 rd_start_en
<=1'b0
;53 rd_sec_addr
<=32'd0
;54
end55
else begin56 rd_start_en
<=1'b0
;57
case(rd_flow_cnt
)58 2'd0
: begin59 //开始读取SD卡数据
60 rd_flow_cnt
<=rd_flow_cnt
+2'd1
;61 rd_start_en
<=1'b1
;62 rd_addr_sw
<= ~rd_addr_sw
;//读数据地址切换
63
if(rd_addr_sw
==1'b0
)64 rd_sec_addr
<=PHOTO_SECTION_ADDR0
;65
else66 rd_sec_addr
<=PHOTO_SECTION_ADDR1
;67
end68 2'd1
: begin69 //读忙信号的下降沿代表读完一个扇区,开始读取下一扇区地址数据
70
if(neg_rd_busy
) begin71 rd_sec_cnt
<=rd_sec_cnt
+11'd1
;72 rd_sec_addr
<=rd_sec_addr
+32'd1
;73 //单张图片读完
74
if(rd_sec_cnt
==RD_SECTION_NUM
-11'b1
) begin75 rd_sec_cnt
<=11'd0
;76 rd_flow_cnt
<=rd_flow_cnt
+2'd1
;77
end78
else79 rd_start_en
<=1'b1
;80
end81
end82 2'd2
: begin83 delay_cnt
<=delay_cnt
+26'd1
;//单张图片读完后延时1秒
84
if(delay_cnt
==26'd50_000_000
-26'd1
) begin//50_000_000*20ns = 1s
85 delay_cnt
<=26'd0
;86 rd_flow_cnt
<=2'd0
;87
end88
end89
default : ;90
endcase91
end92
end93
94
endmodule相比于SD卡的VGA图片显示的sd_read_photo模块,SD卡的LCD图片显示的sd_read_photo模
块仅仅是修改了第11行至第14行定义的三个参数值。三个参数分别为PHOTO_SECTION_ADDR0(第
一张图片扇区起始地址)、PHOTO_SECTION_ADDR1(第二张图片扇区起始地址)和RD_SECTION_NUM
(单张图片总共读出的次数)。其中PHOTO_SECTION_ADDR0和PHOTO_SECTION_ADDR1是由WinHex
软件查看得到的两张图片的扇区起始地址,具体查看的方法我们在下载验证部分再详细讲解。
RD_SECTION_NUM是读取单张图片总共需要读取的次数,即扇区数。单张图片的分辨率为800*480,
位宽为16位,读取一个扇区的字节数为512个字节,共256个16bit,所以单张图片需要读取的
扇区数为800*480/256=1500。
下载验证首先我们打开SD卡图片显示实验(LCD显示)工程,在工程所在的路径下打开
top_sd_photo_lcd/par文件夹,在里面找到“top_sd_photo_lcd.qpf”并双击打开。注意工程
所在的路径名只能由字母、数字以及下划线组成,不能出现中文、空格以及特殊字符等。工程
打开后如图 41.5.1所示:
图 41.5.1 SD卡图片显示实验(LCD显示)工程
在打开下载界面之前,我们还需要先做一些准备工作,也就是向SD卡中导入bin格式的图
片。首先来介绍一下如何利用工具“Img2Lcd”将图片转成bin文件,该工具位于开发板所随附
的资料“6_软件资料/1_软件/Img2Lcd”目录下找到“Img2Lcd.exe”并双击打开,软件打开后
界面如图 41.5.2所示。
在菜单栏中点击“打开”,然后在弹出的界面中选择一幅分辨率为800*480的jpg格式图片。
图片加载进来之后,在工具界面左侧设置输出数据类型为“二进制(*.bin)”,输出灰度为“16
位真彩色”,最大宽度和高度分别为“800”和“480”,选中高位在前(MSB First)。设置
完成后在菜单栏中点击“保存”,并在弹出的界面中选择bin文件的保存路径并输入文件名。
图 41.5.2 Img2Lcd工具界面
到这里我们已经成功地将第一张图片转成了bin文件,因为我们实现的功能是两张图片循
环切换显示,因此需要通过上面的方法再生成一个bin文件。此时,两张bin格式的图片文件制
作完成。
SD卡在经过多次存放数据与删除数据之后,存入的文件有可能不是按照连续的扇区地址存
储的,为了避免图片显示错误,我们将bin文件导入SD卡之前,先把SD卡格式化,格式化的设
置如图 41.5.3所示,然后点击开始按钮完成格式化。
图 41.5.3 SD卡格式化界面
接下来我们将生成的两个bin文件拷贝到SD卡中,拷贝完成后如下图所示:
图 41.5.4 SD卡bin文件拷贝完成
文件拷贝完成后,接下来我们使用WinHex工具软件查看这两个文件的扇区起始地址,该工
具位于开发板所随附的资料中“6_软件资料/1_软件/WinHex”目录下,双击“WinHex.exe”或
者“WinHex64.exe”打开软件。软件打开后,在菜单栏中点击“工具”,然后点击“打开磁盘”,
如下图所示。
图 41.5.5 WinHex打开界面
图 41.5.6 WinHex磁盘打开界面
在“物理驱动器”下,我们看到箭头2所指的地方有RM2、SD/MMC(7.5GB,USB)的字样,
可知该物理驱动器对应的是SD卡,标号为RM2,我们找到标号RM2在逻辑驱动器中的位置,即箭
头1所指的地方,选中后点击“确定”按钮即可查看文件的起始扇区地址,打开后的界面如下图所示:
图 41.5.7 WinHex查看扇区起始地址界面
由 上图可知,两张 bin 格式图片的起始扇区地址分别为 8256 和 9792 , 这和我们
sd_read_photo 模 块 定 义 的 PHOTO_SECTION_ADDR0 = 32'd8256 , PHOTO_SECTION_ADDR1 =
32'd9792是一致的。如果查看的值不是上图中的值,需要将代码中定义的这两个参数值改成
WinHex查看的扇区地址,然后重新编译工程。
接下来我们将SD卡适配器(用于插入MicroSD卡)或者SD卡插入开发板的SD卡插槽,注意
带有金属引脚的一面朝上;然后用FPC排线将ATK-7’RGBLCD模块与开发板连接;接下来将下载
器一端连接电脑,另一端与开发板上对应端口连接,最后连接电源线并打开电源开关。
接下来我们下载程序,验证SD卡的LCD图片显示功能。工程打开后通过点击工具栏中的
“Programmer” 图 标 打 开 下 载 界 面 , 通 过 “Add File” 按钮选择
top_sd_photo_lcd/par/output_files 目录下的“top_sd_photo_lcd.sof”文件。开发板电源
打开后,在程序下载界面点击“Hardware Setup”,在弹出的对话框中选择当前的硬件连接为
“USB-Blaster[USB-0]”。然后点击“Start”将工程编译完成后得到的sof文件下载到开发板
中,如图 41.5.所示:
图 41.5.8 程序下载完成界面
程序下载完成后,此时液晶屏上循环切换显示SD卡中的两张图片,说明SD卡图片显示实验
(LCD显示)下载验证成功。如图 41.5.和图 41.5.8所示:
图 41.5.9 LCD液晶屏显示第一张图片
图 41.5.8 LCD液晶屏显示第二张图片