博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NIOS2随笔——BMP解码与VGA显示
阅读量:6573 次
发布时间:2019-06-24

本文共 3559 字,大约阅读时间需要 11 分钟。

1. 系统概述

本设计采用NIOS2 32位处理器,通过SPI接口将SD/TF卡中的BMP图片数据读取到内存中,SD/TF卡的文件系统为FAT32,NIOS2软件实现BMP解码后,启动framereader和Clocked Video Output模块,最终在VGA显示器上显示BMP图像,系统框图如下:

2. BMP格式

BMP(Bitmap)是Windows操作系统中的标准图像文件格式,采用位映射存储格式,没有采用任何压缩技术。图像深度可为1、4、8和24bit,图像的扫描方式是按照从左到右、从下到上的顺序。

BMP图像文件由四部分组成:

  • 位图头文件数据结构

  • 位图信息数据结构

  • 调色板(可选)

  • 位图数据

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
//位图文件头   
typedef 
struct 
tagBITMAPFILEHEADER
{
    
WORD 
bfType;     
//位图文件的类型,必须为BM-0x424d(1-2字节)
    
DWORD 
bfSize;    
//位图文件的大小,以字节为单位(3-6字节,低位在前)
    
WORD 
bfReserved1;
//位图文件保留字,必须为0(7-8字节)
    
WORD 
bfReserved2;
//位图文件保留字,必须为0(9-10字节)
    
DWORD 
bfOffBits; 
//位图数据的起始位置,以相对于位图(11-14字节,低位在前)
                     
//文件头的偏移量表示,以字节为单位
}BITMAPFILEHEADER;
//位图信息头  
typedef 
struct 
tagBITMAPINFOHEADER{
    
DWORD 
biSize;
//本结构所占用字节数(15-18字节)
    
LONG 
biWidth;
//位图的宽度,以像素为单位(19-22字节)
    
LONG 
biHeight;
//位图的高度,以像素为单位(23-26字节)
    
WORD 
biPlanes;
//目标设备的级别,必须为1(27-28字节)
    
WORD 
biBitCount;
//每个像素所需的位数,必须是1(双色),(29-30字节)
    
//4(16色),8(256色)16(高彩色)或24(真彩色)之一
    
DWORD 
biCompression;
//位图压缩类型,必须是0(不压缩),(31-34字节)
    
//1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
    
DWORD 
biSizeImage;
//位图的大小(其中包含了为了补齐行数是4的倍数而添加的空字节),以字节为单位(35-38字节)
    
LONG 
biXPelsPerMeter;
//位图水平分辨率,每米像素数(39-42字节)
    
LONG 
biYPelsPerMeter;
//位图垂直分辨率,每米像素数(43-46字节)
    
DWORD 
biClrUsed;
//位图实际使用的颜色表中的颜色数(47-50字节)
    
DWORD 
biClrImportant;
//位图显示过程中重要的颜色数(51-54字节)
}BITMAPINFOHEADER;

3. 搭建Qsys

在博文的基础上,在Qsys平台上添加framereader和Clocked Video Output组件,设置分辨率为640*480,VGA相关内容可以参考博文。

搭好的Qsys平台如下图:

4. NIOS2软件设计

往SD卡中保存一幅分辨率为640*480的24位BMP格式图片,图片名为:friend.bmp,电脑中打卡如下图:

在博文的软件基础上,编写软件代码。

由于图像是24位图,没有调色板信息,所以软件只要按照BMP格式偏移54个字节后,读取的便是第一个图像字节数据。VGA显示部分,要对framereader组件初始化,然后存放在数组中的图像数据便会不停地被读取到Clocked Video Output模块,最后数据会被送到VGA编码芯片显示。软件代码设计如下:

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//filename: main.c
//author:   shugen.yin
//date:     2016.12.29
//function: BMP decode and VGA show
#include <stdio.h>
#include <system.h>
#include <string.h>
#include <io.h>
#include "unistd.h"
#include "sd_spi.h"
#include "ff.h"
#include "altera_avalon_pio_regs.h"
 
#define FRAME_ADDR  (framebuf0 + 0x00000000)
#define FRAME_WIDTH   640
#define FRAME_HEIGHT  480
#define FRAME_SIZE  (FRAME_WIDTH*FRAME_HEIGHT)
unsigned 
int 
framebuf0[FRAME_SIZE];
 
void 
FrameRd_init(){
    
IOWR(ALT_VIP_VFR_0_BASE, 3, 0);             
// Frame Select
    
IOWR(ALT_VIP_VFR_0_BASE, 4, framebuf0);     
// Frame 0 Base Address
    
IOWR(ALT_VIP_VFR_0_BASE, 5, FRAME_SIZE/8);  
// Frame 0 Words => 640*480
    
IOWR(ALT_VIP_VFR_0_BASE, 6, FRAME_SIZE);    
// Frame 0 Single Cycle Color Patterns
    
IOWR(ALT_VIP_VFR_0_BASE, 7, 0);             
// Frame 0 Reserved Bit
    
IOWR(ALT_VIP_VFR_0_BASE, 8, FRAME_WIDTH);   
// Frame 0 Width
    
IOWR(ALT_VIP_VFR_0_BASE, 9, FRAME_HEIGHT);  
// Frame 0 Height
    
IOWR(ALT_VIP_VFR_0_BASE, 10, 3);            
// Frame 0 Interlaced => 3 = 0011 bedeutet progressive output
    
IOWR(ALT_VIP_VFR_0_BASE, 0, 1);             
// start Frame Reader
 
}
 
void 
frame_init(){
    
BYTE 
pic_buf[FRAME_SIZE*3+54];
    
UINT 
i;
    
UINT 
j=0;
 
    
f_mount(&fs,
""
,0);
    
res=f_open(&fdst,
"0:/friend.bmp"
, FA_READ);
    
if
(res==FR_OK)
    
{
       
res = f_read(&fdst,pic_buf,FRAME_SIZE*3+54,&br);
       
f_close(&fdst);
    
}
 
    
printf
(
"file read success!\n"
);
 
    
for
(i=54;i<FRAME_SIZE*3+54;i=i+3)
    
{
        
j++;
        
framebuf0[FRAME_SIZE-j] = pic_buf[i]+(pic_buf[i+1])*256+(pic_buf[i+2])*65536;
 
    
}
    
printf
(
"image processed done!\n"
);
}
 
int 
main (
void
)
{
    
frame_init();
    
FrameRd_init();
 
    
while
(1);
 
    
return 
0;
}

5. 编译运行

编译成功后,以Hardware方式运行,终端打印:file read success! image processed done!

6. 最终结果

图片正常显示,和电脑上打开的friend.bmp一致。

本文转自 shugenyin 51CTO博客,原文链接:http://blog.51cto.com/shugenyin/1887551

转载地址:http://anmjo.baihongyu.com/

你可能感兴趣的文章
Android控件之HorizontalScrollView 去掉滚动条
查看>>
UVM中的class--2
查看>>
关于异常的合理处理方式
查看>>
javascript ES3小测试
查看>>
Android - Animation(二)
查看>>
Android6.0指纹识别开发
查看>>
Lucene简介
查看>>
Hibernate概述
查看>>
tomcat与jetty的区别
查看>>
elasticsearch备份与恢复4_使用ES-Hadoop将ES中的索引数据写入HDFS中
查看>>
简单的Verilog测试模板结构
查看>>
flex确认提示框
查看>>
mac 截图快捷键
查看>>
30hibernate_fetch_1_select
查看>>
PHP 可变函数经典用法
查看>>
任务调度器配置文件
查看>>
【JavaScript吉光片羽】--- 滑动条
查看>>
ORACLE 存储过程异常捕获并抛出
查看>>
arcgis api for js之echarts开源js库实现地图统计图分析
查看>>
Microsoft JDBC Driver 4.0 for SQL Server
查看>>