正点原子开拓者FPGA开发板资料连载第四十章 SD卡图片显示实验
cac55 2025-06-28 12:27 21 浏览 0 评论
1)实验平台:正点原子开拓者FPGA 开发板
2)摘自《开拓者FPGA开发指南》关注官方微信号公众号,获取更多资料:正点原子
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-13912-1-1.html
第四十章 SD卡图片显示实验(VGA显示)
在“SD卡读写测试实验”中,我们成功地在开发板上实现了对SD卡的读写测试。本章我们
将使用FPGA开发板实现从SD卡中读取两张图片,并通过VGA接口在显示器上循环切换显示两张
图片的功能。
本章包括以下几个部分:
40.1 SD卡-VGA图片显示简介
40.2 实验任务
40.3 硬件设计
40.4 程序设计
40.5 下载验证
SD卡-VGA图片显示简介
我们在“SD卡读写测试实验”中介绍过,SD卡在SD2.0版本协议下,SPI模式的理论最大传
输速率为50Mbps,在SDIO模式下理论传输速率为200Mbps,加上命令号以及等待SD卡返回响应
信号的时间,实际上的传输速率会比理论传输速率下降不少。对于采用分辨率为640*480@60Hz
的显示器来说,一幅图像的数据量达到640*480*16bit=4915200bit=4800Kbit(1Kbit=1024bit),
每秒钟刷新60次,那么每秒钟需要传输的数据量达到4800Kbit*60=288000Kbit=281.25Mbit
(1Mbit=1024Kbit)。由此可以看出,SD卡的读写速度完全跟不上VGA的数据发送速度,因此
必须先缓存一幅图像,再通过VGA接口显示。我们在前面多次提到过,FPGA的片内存储资源较
少,对于缓存如此大量的数据,只能使用开发板上的SDRAM存储器缓存数据。
本次实验使用SDRAM存储器来缓存图片数据,图片数据来自于SD卡,那么我们就需要事先
向SD卡中导入两张图片,也就是从电脑中拷贝两张图片放入SD卡。如果是Micro SD卡(TF卡),
需要将先将Micro SD卡插入读卡器中,再将读卡器插入电脑的USB接口。如果是SD卡,可以直
接将SD卡插入电脑的SD卡插槽内(有些电脑可能没有此接口),也可以插入支持SD卡的读卡器
中。
VGA的显示格式为16位RGB565格式,为了使SD卡读出的数据可以直接在VGA上显示,我们需
要将图片通过“IMG2LCD”上位机软件转成16位的RGB565格式的bin文件,再将bin文件导入SD
卡中。然后使用WinHex软件查看两个bin文件的扇区地址,此时查询到的扇区地址就是bin文件
存放的起始扇区地址,我们只需要按照这个起始扇区地址,按顺序读出SD卡中的数据即可,直
到读完一张图片中的所有数据。SD卡中一个扇区存放512个字节,也就是256个16位数据,对于
分辨率为640*480的图片来说,共需要读出1200(640*480/256)个扇区数据。
我们在“SD卡读写测试实验”中对SD卡的协议规范作了详细的介绍,包括SD卡的接口说明、
初始化以及读写操作等。如果大家对这部分内容不是很熟悉的话,请参考“SD卡读写测试实验”
中的SD卡简介部分。
实验任务
本节实验任务是使用FPGA开发板循环读取SD卡中存储的两张图片(bin格式图片,分辨率
为640*480),然后将图片存储在SDRAM中并通过VGA接口在显示器上循环切换显示。
硬件设计
SD卡接口部分的硬件设计请参考“SD卡读写测试实验”中的硬件设计部分。
由于SDRAM、SD卡接口和VGA接口的引脚数目较多且在前面相应的章节中已经给出它们的管
脚列表,这里不再列出管脚分配。
程序设计
图 40.4.1是根据本章实验任务画出的系统框图。PLL时钟模块为其它各模块提供驱动时
钟;SD卡读取图片控制模块控制SD卡控制器的读接口;SD卡控制器从SD卡中读出图像数据,并
将读出的数据写入SDRAM控制器;最后VGA驱动模块通过SDRAM控制器读取SDRAM中存储的图片数
据并通过VGA接口显示在显示器上。
图 40.4.1 SD卡图片显示实验(VGA显示)系统框图
顶层模块的原理图如下图所示:
图 40.4.2 顶层模块原理图
FPGA顶层模块(top_sd_photo_vga)例化了以下五个模块:PLL时钟模块(pll_clk)、SD
卡读取图片控制模块(sd_read_photo)、SD卡控制器模块(sd_ctrl_top)、SDRAM控制器模
块(sdram_top)和VGA驱动模块(vga_driver)。
顶层模块(top_sd_photo_vga):顶层模块主要完成对其余各模块的例化,实现各模块之
间的数据交互。需要注意的是,系统初始化完成是在SD卡以及SDRAM都初始化完成后才开始拉
高的,该信号控制着SD卡读取图片控制模块的复位信号,因此SD卡读取图片控制模块是在系统
初始化完成后才工作的,防止因SD卡或者SDRAM初始化未完成导致数据错误。
PLL时钟模块(pll_clk):PLL时钟模块通过调用锁相环(PLL)IP核实现,总共输出五个
时钟,频率分别为100Mhz、100Mhz(相位偏移-75度)、50Mhz、50Mhz(相位偏移180度)和25Mhz。
两个100Mhz的时钟用于为SDRAM控制器模块提供驱动时钟;两个50Mhz的时钟用于为SD卡控制器
模块提供驱动时钟,其中50mhz为SD卡读取图片控制模块提供驱动时钟;25Mhz用于为VGA驱动
模块提供驱动时钟。
SD卡读取图片控制模块(sd_read_photo):SD卡读取图片控制模块通过控制SD卡控制器
的读接口,从SD卡中读取图像数据,并在读完一张图片后延时一段时间,再去读取另一张图片
数据,实现两张图片的循环切换读取。
SD卡控制器模块(sd_ctrl_top):SD卡控制器模块负责驱动SD卡,该模块将SD卡的SPI读
写操作封装成方便用户使用的接口。有关该模块的详细介绍请大家参考“SD卡读写测试实验”
章节。
SDRAM读写控制模块(sdram_top):SDRAM读写控制器模块负责驱动SDRAM片外存储器,缓
存图像传感器输出的图像数据。该模块将SDRAM复杂的读写操作封装成类似FIFO的用户接口,
非常方便用户的使用。
VGA驱动模块(vga_driver):VGA驱动模块根据VGA时序参数输出行、场同步信号;同时
它还要输出数据请求信号用于读取SDRAM中的图片数据,并将图片通过VGA接口显示。
SD卡读取图片控制模块的代码如下:
1 module sd_read_photo(
2 input clk , //时钟信号
3 input rst_n , //复位信号,低电平有效
4
5 input rd_busy , //SD卡读忙信号
6 output reg rd_start_en , //开始写SD卡数据信号
7 output reg [31:0] rd_sec_addr //读数据扇区地址
8 );
9
10 //parameter define
11 parameter PHOTO_SECCTION_ADDR0 = 32'd8256; //第一张图片扇区起始地址
12 parameter PHOTO_SECTION_ADDR1 = 32'd9472 ; //第二张图片扇区起始地址
13 //640*480/256 = 1200
14 parameter RD_SECTION_NUM = 11'd1200 ; //单张图片总共读出的次数
15
16 //reg define
17 reg [1:0] rd_flow_cnt ; //读数据流程控制计数器
18 reg [10:0] rd_sec_cnt ; //读扇区次数计数器
19 reg rd_addr_sw ; //读两张图片切换
20 reg [25:0] delay_cnt ; //延时切换图片计数器
21
22 reg rd_busy_d0 ; //读忙信号打拍,用来采下降沿
23 reg rd_busy_d1 ;
24
25 //wire define
26 wire neg_rd_busy ; //SD卡读忙信号下降沿
27
28 //*****************************************************
29 //** main code
30 //*****************************************************
31
32 assign neg_rd_busy = rd_busy_d1 & (~rd_busy_d0);
33
34 //对rd_busy信号进行延时打拍,用于采rd_busy信号的下降沿
35 always @(posedge clk or negedge rst_n) begin
36 if(rst_n == 1'b0) begin
37 rd_busy_d0 <= 1'b0;
38 rd_busy_d1 <= 1'b0;
39 end
40 else begin
41 rd_busy_d0 <= rd_busy;
42 rd_busy_d1 <= rd_busy_d0;
43 end
44 end
45
46 //循环读取SD卡中的两张图片(读完之后延时1s再读下一个)
47 always @(posedge clk or negedge rst_n) begin
48 if(!rst_n) begin
49 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 end
55 else begin
56 rd_start_en <= 1'b0;
57 case(rd_flow_cnt)
58 2'd0 : begin
59 //开始读取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_SECCTION_ADDR0;
65 else
66 rd_sec_addr <= PHOTO_SECTION_ADDR1;
67 end
68 2'd1 : begin
69 //读忙信号的下降沿代表读完一个扇区,开始读取下一扇区地址数据
70 if(neg_rd_busy) begin
71 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) begin
75 rd_sec_cnt <= 11'd0;
76 rd_flow_cnt <= rd_flow_cnt + 2'd1;
77 end
78 else
79 rd_start_en <= 1'b1;
80 end
81 end
82 2'd2 : begin
83 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 end
88 end
89 default : ;
90 endcase
91 end
92 end
93
94 endmodule
在代码的第11行至第14行定义了三个参数,PHOTO_SECTION_ADDR0(第一张图片扇区起始
地址)、PHOTO_SECTION_ADDR1(第二张图片扇区起始地址)和RD_SECTION_NUM(单张图片总
共读出的次数)。其中PHOTO_SECTION_ADDR0和PHOTO_SECTION_ADDR1是由WinHex软件查看得到
的两 张图 片的 扇区 起始 地址 ,具 体查 看的 方法 我们 在下 载验 证部 分再 详细 讲解。
RD_SECTION_NUM是读取单张图片总共需要读取的次数,即扇区数。单张图片的分辨率为640*480,
位宽为16位,读取一个扇区的字节数为512个字节,共256个16bit,所以单张图片需要读取的
扇区数为640*480/256=1200。
在代码的第47行开始的always语句块中,实现的功能是根据第一张图片的扇区地址向SD卡
控制器模块发送读命令,读完后延时1秒钟,并根据第二张图片的扇区地址向SD卡控制器模块
发送读命令,读完后再次延时1秒钟,并根据第一张图片的扇区地址向SD卡控制器模块再次发
送读命令,就这样循环往复读取SD卡中的两张图片。这个功能是由代码中定义的读流程控制计
数器(rd_flow_cnt)来实现,读忙信号的下降沿(neg_rd_busy)表示当前扇区读取完成,可
以进行其它操作。
图 40.4.3为控制SD卡读取图片过程中SignalTap抓取的波形图。
由图可知,在rd_sec_cnt(读扇区个数计数器)的值为1199(1200-1)时表示当前读取的是图片的最后一个扇区的数据,
rd_busy(读忙信号)拉低后,单张图片的最后一个扇区地址读完,此时rd_flow_cnt加1,延
时计数器(delay_cnt)开始计数,等待延时完成后读取下一张图片。
图 40.4.3 控制SD卡读取图片SignalTap波形图
下载验证
首先我们打开SD卡图片显示实验(VGA显示)工程,在工程所在的路径下打开
top_sd_photo_vga/par文件夹,在里面找到“top_sd_photo_vga.qpf”并双击打开。注意工程
所在的路径名只能由字母、数字以及下划线组成,不能出现中文、空格以及特殊字符等。工程
打开后如图 40.5.1所示:
图 40.5.1 SD卡图片显示实验(VGA显示)工程
在打开下载界面之前,我们还需要先做一些准备工作,也就是向SD卡中导入bin格式的图
片。首先来介绍一下如何利用工具“Img2Lcd”将图片转成bin文件,该工具位于开发板所随附
的资料“6_软件资料/1_软件/Img2Lcd”目录下找到“Img2Lcd.exe”并双击打开,软件打开后
界面如图40.5.2所示。
在菜单栏中点击“打开”,然后在弹出的界面中选择一幅分辨率为640*480的jpg格式图片。
图片加载进来之后,在工具界面左侧设置输出数据类型为“二进制(*.bin)”,输出灰度为“16
位真彩色”,最大宽度和高度分别为“640”和“480”,选中高位在前(MSB First)。设置
完成后在菜单栏中点击“保存”,并在弹出的界面中选择bin文件的保存路径并输入文件名。
图 40.5.2 Img2Lcd工具界面
到这里我们已经成功地将第一张图片转成了bin文件,因为我们实现的功能是两张图片循
环切换显示,因此需要通过上面的方法再生成一个bin文件。此时,两张bin格式的图片文件制
作完成。
SD卡在经过多次存放数据与删除数据之后,存入的文件有可能不是按照连续的扇区地址存
储的,为了避免图片显示错误,我们将bin文件导入SD卡之前,先把SD卡格式化,格式化的设
置如图 40.5.3所示,然后点击开始按钮完成格式化。
图 40.5.3 SD卡格式化界面
接下来我们将生成的两个bin文件拷贝到SD卡中,拷贝完成后如下图所示:
图 40.5.4 SD卡bin文件拷贝完成
文件拷贝完成后,接下来我们使用WinHex工具软件查看这两个文件的扇区起始地址,该工
具位于开发板所随附的资料中“6_软件资料/1_软件/WinHex”目录下,双击“WinHex.exe”或
者“WinHex64.exe”打开软件。软件打开后,在菜单栏中点击“工具”,然后点击“打开磁盘”,
如下图所示。
图 40.5.5 WinHex打开界面
图 40.5.6 WinHex磁盘打开界面
在“物理驱动器”下,我们看到箭头2所指的地方有RM2、SD/MMC(7.5GB,USB)的字样,
可知该物理驱动器对应的是SD卡,标号为RM2,我们找到标号RM2在逻辑驱动器中的位置,即箭
头1所指的地方,选中后点击“确定”按钮即可查看文件的起始扇区地址,打开后的界面如下图所示:
图 40.5.7 WinHex查看扇区起始地址界面
由 上图可知,两张 bin 格式图片的起始扇区地址分别为 8256 和 9472 , 这和我们
sd_read_photo 模 块 定 义 的 PHOTO_SECTION_ADDR0 = 32'd8256 , PHOTO_SECTION_ADDR1 =
32'd9472是一致的。如果查看的值不是上图中的值,需要将代码中定义的这两个参数值改成
WinHex查看的扇区地址,然后重新编译工程。
接下来我们将SD卡适配器(用于插入MicroSD卡)或者SD卡插入开发板的SD卡插槽,注意
带有金属引脚的一面朝上;然后将VGA连接线一端连接显示器,另一端与开发板上的VGA接口连
接;接下来将下载器一端连接电脑,另一端与开发板上对应端口连接,最后连接电源线并打开
电源开关。
接下来我们下载程序,验证SD卡的VGA图片显示功能。工程打开后通过点击工具栏中的
“Programmer” 图 标 打 开 下 载 界 面 , 通 过 “Add File” 按 钮 选 择 top_sd_photo_vga
/par/output_files目录下的“top_sd_photo_vga.sof”文件。开发板电源打开后,在程序下
载界面点击 “Hardware Setup” ,在弹出的对话框中选择当前的硬件连接为“USB
Blaster[USB-0]”。然后点击“Start”将工程编译完成后得到的sof文件下载到开发板中,如
图 40.5.所示:
图 40.5.8 程序下载完成界面
程序下载完成后,此时显示器上循环切换显示SD卡中的两张图片,说明SD卡图片显示实验
(VGA显示)下载验证成功。如图 40.5.8和图 40.5.9所示:
图 40.5.8 VGA器显示第一张图片
图 40.5.9 VGA器显示第二张图片
相关推荐
- 小车五位自动循环往返控制_小车自动往返控制系统
-
需求描述:用三相异步电动机拖动一辆小车在A、B、C、D、E五点之间自动循环往返运行,小车初始在A点,按下启动按钮,小车依次前进到B、C、D、E点,并分别停止2s返回到A点停止。按下停止...
- 自动灌溉系统_自动灌溉系统by
-
需求描述:PLC时钟设定每日6:00、18:00自动启动灌溉系统,每次运行15分钟后停止;非定时时段按下手动灌溉按钮,立即启动并运行15分钟;土壤湿度传感器检测到湿润时,跳过本次定时灌溉...
- 主板ERP开启还是关闭好_主板设置erp是什么
-
主板功能的开启与关闭,本质是在“节能环保”和“使用便利”之间做选择。为帮你快速决策,先给出直接结论,再深入解析原理、影响及操作步骤,让你根据自身需求精准设置。一、直接结论:ERP功能如何选?...
- 新电脑必做5项设置!做完再玩,流畅安全多用三年
-
刚拿到新电脑,兴奋之余先别急着开机畅玩!做好以下这5大设置,能让你的爱机长期保持流畅如新,安全又省心。尤其是最后一招,很多老用户都不知道!1关闭隐私常规,杜绝数据偷跑新电脑首次开机进行系统初始化时,...
- 属于 PHP 开发者的 Supervisor 实用指南
-
属于PHP开发者的Supervisor实用指南在PHP开发中,我们经常需要运行一些后台进程:队列处理、长时间运行的脚本、WebSocket服务器等。这些进程可能会因为各种原因意外退出,手...
- 领导半夜12点微信派活?三句高情商回复,反手拿捏让他不敢再烦
-
友友们大家来啦!今天来和大家一起分享精彩话题老规矩先点赞再看文!0102别在这里害人了,现在能保住工作就烧高香了,再得瑟,明天早上去办离职0304很简单,把他一起拉上,每半小时打电话或语音汇报,一两次...
- "零点黑科技!硬盘自动备份+离线神操作,服务器数据安全躺赢"
-
公司有一台服务器,数据库需要每天零点进行数据库备份,要求在本机备份一次,再在移动硬盘上异地备份一次。备份完成后硬盘自动离线。具体思路如下:数据库自动备份时间为每天0点,备份过程约需1分钟。0点时开启硬...
- 峰谷电:白天贵、晚上便宜,你家真的适合开通吗?
-
电费单又超预算了?别急着关掉空调,其实你可能错过了一个"电费打折"的机会——峰谷电。它就像电影院的日场和夜场票,白天贵、晚上便宜,聪明利用,电费真的能省下来。一、峰谷电是什么?峰谷电把...
- 电脑开机密码设置全指南:从基础到进阶的安全防护
-
在数字化时代,电脑存储着大量个人隐私和重要数据,设置开机密码是保护信息安全的第一道防线。本文将系统介绍Windows、macOS、Linux三大主流操作系统及BIOS层面的密码设置方法,同时涵盖密码管...
- 自动喷香机_香薰机自动喷香机
-
需求描述:PLC时钟设定每日9:00、14:00、18:00自动启动喷雾,每次喷雾3秒后停止;非定时时段按下手动喷雾按钮,立即喷雾3秒;香薰液缺液传感器检测到液位过低时,停止喷雾并亮报警...
- macbook系统自动启动项在哪里查看
-
了解和管理MacBook的开机自动启动项,是优化系统启动速度和运行效率的好方法。下面我来为你介绍几种查看和管理这些启动项的方法。查看和管理MacBook启动项1.通过系统设置(最简单直接的方法)...
- 想让电脑自己到点开机和关机?这4个超实用的设置方法快收好!
-
嘿,你是不是也经常忙到忘记关电脑?或者早上想用电脑时发现还没开机?别慌,今天我就跟你分享几个超实用的方法,帮你轻松搞定电脑的定时开关机设置。不管你是电脑小白还是有点基础,这篇教程都能让你秒懂操作,省时...
- 定时关机这样操作小白也会 一招设定工作日关机 指定时间关机
-
在日常使用电脑的过程中,我们常常会遇到这样的情况:晚上睡觉前忘记手动关机,导致电脑整夜运行,既浪费电又缩短硬件寿命;或者在下载大文件时,需要等待很长时间才能完成,却不能一直守在电脑前,下载完成后也无法...
- 日本无线电操作证试题,这些问题你能答的上来吗?
-
一直以来,我们对于日本的业余无线电的印象都停留在“操作能力强,爱好者数目众多”上,然而我们对于他们的业余无线电体系所知甚少。日本业余无线电操作证的等级分作四级,最基本的四级操作证书具有8MHz以下、2...
- 你知道吗?单边带信号就像DNA分子一样!
-
我们在准备B级操作证书的过程中,避免不了的要接触到一个新的名词——SSB。单边带是传统AM模式的一种特殊的形式,在传送相同的信息的过程中,其占用的带宽仅为AM模式的一半,那么SSB模式到底是怎样的一种...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 如何绘制折线图 (52)
- javaabstract (48)
- 新浪微博头像 (53)
- grub4dos (66)
- s扫描器 (51)
- httpfile dll (48)
- ps实例教程 (55)
- taskmgr (51)
- s spline (61)
- vnc远程控制 (47)
- 数据丢失 (47)
- wbem (57)
- flac文件 (72)
- 网页制作基础教程 (53)
- 镜像文件刻录 (61)
- ug5 0软件免费下载 (78)
- debian下载 (53)
- ubuntu10 04 (60)
- web qq登录 (59)
- 笔记本变成无线路由 (52)
- flash player 11 4 (50)
- 右键菜单清理 (78)
- cuteftp 注册码 (57)
- ospf协议 (53)
- ms17 010 下载 (60)