20221213-VGA显示图像详细总结

https://blog.csdn.net/weixin_44406200/article/details/103823607

VGA 显示原理

VGA 概念

VGA 不是用来显示的那块屏幕,而是用来传输信号的接口,VGA 全称是video graphics array 及视频图形阵列,是模拟信号的一种视频传输标准,VGA 传输接口实物图如下

自测试 地址码 蓝基色 绿基色 红基色

数字地 蓝地 绿地 红地
地址码 场同步 行同步 地址码 地址码

操作VGA 的过程就是给你一块有横纵坐标范围的区域,区域上的每一个坐标点就是一个像素点,你可以做的事情是给这个像素点特定的rgb 色彩,既可以通过自定义rgb 也可以去取图像某个像素点的rgb ,这也就提供了你在vga 上画图以及显示图片的能力

VGA 分辨率及理解误区

640 * 480 的规格就是显示屏幕上每行有640 个像素点,总共有480行,注意,一件很重要的事情是,虽然你看到的屏幕上的大小是640 * 480 的 但是它实际大小并不只有那么点,形象一点就是说,VGA 的扫描范围是包含了你能够看到的640 480 这一块区域的更大区域,他会在周围一圈你看不到的区域部分进行扫描,因此,我们在处理扫描信号的时候一定要注意只有扫描到有效区域的时候才能把像素点数据传给 VGa 显示

VGA 显示器扫描方式从屏幕左上角一点开始,从左向右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期 间,CRT 对电子束进行消隐,每行结束时,用行同步信号进行同步,当扫描完所有的行,形成一帧,用场同步信号进行场同步,并使扫描回到屏幕左上方,同时进行场消隐,开始下一帧,完成一行扫描的时间称为水平扫描时间,其倒数称为行频率,完成一帧,扫描的时间称为垂直扫描时间,其倒数称为场频率,及屏幕的刷新频率,其扫描示意图如下图所示

有效显示区域

关于那一块非有效显示区域,实际上是因为每一行和每一列的扫描区间都是由以下几部分组成

行扫描 Hor Sync 、Hor Back Porch 、Hor Active Video和Hor Front Porch

Hor Scan Time 是一个扫描周期,它会先扫描到hor sync 再扫描 hor back porch 然后才进入有效显示区 hor active video 最后是一段 hor front porch 可以看出来,四段区间只有hor active video 这一段是能够正常显示图像信息的,也就是屏幕上显示的那一块区间

列扫描也同理

给定参数

实际上,根据固定的分辨率大小,比如我们实验室的板子使用的640 480 的屏幕大小,这些非有效区间的长度值都是一个固定的常数,因此你只要在扫描的时候把这些常数稍加处理即可

下图罗列了不同分辨率所对应的各个参数,其中的a、b、c、d、e、f、g、h、i、k的含义,与上面给出的两张图的标注一一对应;我们实验使用的是第一组数据,可以看到行时序参数中的c代表每一行的有效显示区间640,列时序参数中的h代表每一列的有效显示区间480

需要扫描频率,很重要的一件事,无论是行扫描还是给像素点赋值,我们都需要用一个时钟,这个时钟不是系统时针,必须要先将50MHZ 的时钟分频为25MHZ 然后拿去作为扫描信号的时钟

这一点是特别需要注意的,否则到时候会出现out of range 的现象

前期准备 coe 文件的生成

coe 和ip 核介绍

我们调用VGA 的终极目标是想要能够显示一张图片,在这之前,我们要先对这张图片进行一些预处理,因为我们是通过verilog 语言去调用图片数据的,但是verilog 并不知道怎么从一张已有的图片上去取相应的数据

因此我们要先将图片转换为coe 文件,coe 文件实际上就是按照某种规律将图像每一个像素点的rgb 数据都摆放成单独一行 16进制,然后借助ISE 的IP 核生成将coe 文件转化成ROM ,生成的ROM.xco 和ROM.v 文件就可以被verilog 语言所识别调用,最终就能够取到图像的数据了

24位bmp 图像转换为coe 文件 复原代码

为了统一规范,这里我们使用24位真彩色的bmp 格式图像进行转换,好处是,bmp 的三通道数据特征是非常明显的,易于处理

如何获取24位bmp 图像

然后bmp 格式也有很多种,如单色 16色 24 256 ,这里我们统一选择24位位图选项,点击保存即可

使用matlab 将24位真彩色bmp 位图转化为coe 文件

由于24位共rgb 三个通道,每个通道分到的是8位,占用资源太多,且老师给的ucf 引脚约束对rgb 每一个通道只给了4位,因此我们在转化为coe 文件的同时,要将每个通道压缩成4位,即整张图像同时转化为12位

压缩图像是一件非常重要的事情,因为经过后续的实践我们发现,板子内存资源有限,无法同时加载多张大图

为了能够对多张图像进行批量处理,我使用matlab 写了一个 img2coe.m 函数,只要对bmp 图像调用这个函数即可转换成coe 文件了,转换过程介绍如下

先将rgb 提取为三个通道,用reshape 函数对转置后的矩阵进行重组,对rgb 三个分量的数据都右移,舍去细节,留下高四位作为最终的数据,然后写入到coe 文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
function img2coe(path,name)
% 利用imread函数把图片转化为一个三维矩阵
image_array = imread(path);

% 利用size函数把图片矩阵的三个维度大小计算出来
% 第一维为图片的高度,第二维为图片的宽度,第三维为图片的RGB分量
[height,width,z]=size(image_array);

red = image_array(:,:,1); % 提取红色分量,数据类型为uint8
green = image_array(:,:,2); % 提取绿色分量,数据类型为uint8
blue = image_array(:,:,3); % 提取蓝色分量,数据类型为uint8

% 把上面得到了各个分量重组成一个1维矩阵,由于reshape函数重组矩阵的
% 时候是按照列进行重组的,所以重组前需要先把各个分量矩阵进行转置以后再重组
% 利用reshape重组完毕以后,由于后面需要对数据拼接,所以为了避免溢出
% 这里把uint8类型的数据扩大为uint32类型
r = uint32(reshape(red' , 1 ,height*width));
g = uint32(reshape(green' , 1 ,height*width));
b = uint32(reshape(blue' , 1 ,height*width));

% 初始化要写入.coe文件中的RGB颜色矩阵
rgb=zeros(1,height*width);

% 因为导入的图片是24-bit真彩色图片,每个像素占用24-bit,其中RGB分别占用8-bit
% 而我这里需要的是12-bit,其中R为4-bit,G为4-bit,B为4-bit,所以需要在这里对24-bit的数据进行重组与拼接
% bitshift()函数的作用是对数据进行移位操作,其中第一个参数是要进行移位的数据,第二个参数为负数表示向右移,为
% 正数表示向左移,更详细的用法直接在Matlab命令窗口输入 doc bitshift 进行查看
% 所以这里对红色分量先右移4位取出高4位,然后左移11位作为ROM中RGB数据的第11-bit到第8-bit
% 对绿色分量先右移4位取出高4位,然后左移5位作为ROM中RGB数据的第7-bit到第4-bit
% 对蓝色分量先右移4位取出高4位,然后左移0位作为ROM中RGB数据的第3-bit到第0-bit
for i = 1:height*width
rgb(i) = bitshift(bitshift(r(i),-3),11) + bitshift(bitshift(g(i),-2),5) + bitshift(bitshift(b(i),-3),0);
end

fid = fopen( name , 'w+' );

% .coe文件的最前面一行必须为这个字符串,其中16表示16进制
fprintf( fid, 'memory_initialization_radix=16;\n');

% .coe文件的第二行必须为这个字符串
fprintf( fid, 'memory_initialization_vector =\n');

% 把rgb数据的前 height*width-1 个数据写入.coe文件中,每个数据之间用逗号隔开
fprintf( fid, '%x,\n',rgb(1:end-1));

% 把rgb数据的最后一个数据写入.coe文件中,并用分号结尾
fprintf( fid, '%x;',rgb(end));

fclose( fid ); % 关闭文件指针
end

中期准备 coe 转换为rom

经过上面的步骤我们已经得到了coe 文件

接下来就是把它转化成verilog 能够调用的rom 文件了

在ISE 工程中,点击右键新建文件,选择ip 核生成

选择Memories选项中的RAMs&ROMs里的Block Memory Generator

然后进入到这个设置参数的界面

其中width代表你设置的图片数据是几进制,由于之前写coe的时候是用16进制写的,因此这里写16;depth表示图像的大小,即长乘宽,由于我使用的是640480的图片,因此这里填207200(=640480)

当你的文件路径成功出现的时候,你就可以点击下方的generate生成了,当然这个generate也要很久很久,一般一张640 *480的图片要generate近一个小时左右才能生成

生成完毕的标志是creating结束,并且在你的目录下出现类型太阳的这个标记

后期调用与测试

VGA 显示的过程中会遇到很多小bug 有些小bug 的原因你根本找不出,比如 out of range ,你只能静下心来慢慢调试仿真

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2024 TeX_baitu
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~