VGA图片汉字显示
彩条显示后本以为图片和汉字显示应该是很随意的事,可是却又折腾了几天才算显示的比较完美。下一步就要动态显示了,先把静态的显示再
总结
初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf
一下。
先说图片显示,因为自己上来也是很迷惑的所以最好的学习方式还是先借鉴别人的。最终决定让其显示64*64的图片一张挨着一张的效果。之前的vga时序驱动已经写好,现在最关键的问题就是把图片信息存入fpga内部的rom中。如何存?当然不会像复制粘贴那么简单,这是存入fpga内部的,并且她也不能识别bmp,jpg……等格式的图片文件。所以quartus有个功能就是在建立rom时会让你关联一个hex或者mif文件,而图像信息全部从放在hex或mif文件中。编译下载后自然就会存入fpga rom中。这不简单想办法把图片转换成为hex或者mif文件不就一切都ok了。我习惯性的在百度中苦找,发现就没这种转换软件,找着一个像的也毫无利用价值……tnnd一天下来时间全花在找软件上了。还是靠自己吧……记事本打开mif里面的文件格式不是很难,如下:
: DEPTH=4096;
WIDTH=8;
ADDRESS_RADIX=UNS;
DATA_RADIX=HEX;
CONTENT BEGIN
0:24;
1:24;
2:04;
…………
4095;12;
END;
0,1,2,代表的是在rom中的地址后面的是地址中的数据,当然前面的深度、数据宽度、地址和数据进制都要写上。决定还是自己写个转换程序,图片的格式编码我还都不会,估计也比较复杂,所以还要先用取模软件吧图片生成rgb数组信息(也就是我们平时单片机编程时取模取出的数组)。自己写的转换程序暂且叫做rgb2mif吧,他的作用就是有了这个图片取模出的数组文件就可以生成mif文件,rgb2mif还称不上是个软件,这能是个程序,没编写过电脑上的软件界面也不会做,所以只能通过dos来运行或者是用visul c++运行,运行完之后会在一个文件夹内生成mif文件格式的文档。这个程序的源代码如下:
#include
#include
unsigned long num; //
记录
混凝土 养护记录下载土方回填监理旁站记录免费下载集备记录下载集备记录下载集备记录下载
图片编码深度
#define BIT_WITH8
//
#define BIT_WITH1
void main()
{
char ch;
unsigned char v1,v2;
unsigned char i;
FILE *fpin,*fpout;
//定义两个文件指针
fpin=fopen("e:\\c\\zh\\in.txt","r"); //fpin指向in.txt文件
fpout=fopen("e:\\c\\zh\\out.txt","w");
//fpout指向out.txt文件
if((fpin!=NULL)&&(fpout!=NULL))printf("read have finish!\n"); //判断两个文件是否存在
fprintf(fpout,"--This program written on June 7, 2012.\n");
//在out的开头处加入注释
fprintf(fpout,"--Author:WZT\n");
//
a=ftell(fpout); //求出文件内部指针现在的位置
//
printf("a=%d",a);
fprintf(fpout," \n"); //给后面输出DEPTH= 留出空间
fprintf(fpout,"WIDTH=8;\n");
//图片rgb编码宽度
fprintf(fpout,"ADDRESS_RADIX=UNS;\n");
//地址编码格式
fprintf(fpout,"DATA_RADIX=HEX;\n");
//数据编码格式
fprintf(fpout,"CONTENT BEGIN\n");
//开始
ch=fgetc(fpin);
//读出in文件的第一个字节
while(ch!=EOF)
{
if((ch=='X')||(ch=='x'))
{
v1=fgetc(fpin);
v2=fgetc(fpin);
/*
fprintf(fpout,"%d:",num);
fputc(v1,fpout);
fputc(v2,fpout);
fprintf(fpout,";\n"); */
#ifdef BIT_WITH8
fprintf(fpout," %d:%c%c;\n",num,v1,v2);
num+=1;
#endif
#ifdef BIT_WITH1
if((v1-'0')<=9)v1=v1-'0';
else v1=v1-'A'+10;
if((v2-'0')<=9)v2=v2-'0';
else v2=v2-'A'+10;
printf("%d\n",v1);
printf("%d\n",v2);
for(i=0;i<4;i++)
{
if(v1&0x08) fprintf(fpout," %d:1;\n",num);
else fprintf(fpout," %d:0;\n",num);
v1<<=1;
num++;
}
for(i=0;i<4;i++)
{
if(v2&0x08) fprintf(fpout," %d:1;\n",num);
else fprintf(fpout," %d:0;\n",num);
v2<<=1;
num++;
}
#endif
}
ch=fgetc(fpin);
}
fprintf(fpout,"END;\n");
printf("ok!\n");
//
a=ftell(fpout);
fseek(fpout,55,0);
fprintf(fpout,"DEPTH=%d;",num);
fclose(fpin);
fclose(fpout);
exit(0);
}
现在还不是很完善,只能生成两种数据位宽的代码:8位和1位。
#define BIT_WITH8
//
#define BIT_WITH1切换的时候就是通过宏定义……另一句要屏蔽掉。事先还要按照如下路径建立两个txt:in.txt and out.txt
e:\\c\\zh\\in.txt e:\\c\\zh\out.txt要不然就是在其他地方建立这两个文件然后修改程序的文件路径。用时把数组信息复制进in.txt点击运行后打开out.txt里面就是想要的代码。虽然操作步骤有点多吧但是总比你手工输入成千上万个代码最后弄得眼花缭乱强的多了。
Rom本来是一个一维的存储空间,就是一个地址对应一数据。但是为了我们再下一步图片显示方便就要把rom内的数据想像为二维存储。这个是如何实现的呢?其实我们在生成mif文件的时候就设置过了,我们可以把数据前面的地址当成是x轴,数据位宽就是y轴,那么找到某些位通过两个偏移量就可以得到。
接下来就是真正的图片显示了,数据现在已经存进rom,剩下的就是让数据能有规律的读取出来。这里我们要显示的是64*64分辨率的图片,每个像素有1个字节进行存放需哦一共需要64*64*1=4096个字节。如上面的mif文件中的从地址0到4095共4096个字节。我们只要把这4096个信息读取出来再一个个的送到vga屏的64*64的区域进行扫描一张图片就复原了。下面是效果:
原理就是这个,代码更简单:
wire [7:0]RGB;
ROM_1
ROM_1_inst (
.address ( {vcount[5:0],hcount[5:0]} ),
.clock ( clk ),
.q (RGB)
);
if(dat_enable)
begin
{rgb[7:5]}<={RGB[7:5]};
{rgb[4:2]}<=RGB[4:2];
{rgb[1:0]}<=RGB[1:0];
End
第一部分就是例化ROM模块,可以看到地址是通过行扫描,场扫描计数的低六位构成的一个10位数。初始时vcount和hcount的值都为0,水平方向每加一个像素vcount的值就加一,而每加一行vcount才加一,所以第一行就是不断循环显示0-64(就是还原图片的第一行)地址上的像素值,第二行时就不断循环显示65—128地址的数据,这样第二行也显出来了,就这样下去到第63行结束整张图片都显示出来了(并且不止一张,我的水平分辨率是640,所以也就是640/64等于10张);而从64行开始就是又重复地第一行的,所以整个屏幕扫描完后就是一张挨着一张的图片挂在屏幕上!如果要在屏幕上指定的地点显示一张图片也不是很难,就要先划定个范围,在这个范围内再读取数据送往屏幕显示就可以了。
老师让最终做出动态的效果,还要把我们的班级名字显示在上面,所以文字显示肯定也是少不了的。或许有人会立马想到用显示图片的
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
先把字给截图把图片显示出来不是也是显示汉字,但是谁刚上来又不这样想呢,但是最终否定了这种方案,因为那样一张128*128的图片rom根本就存不下,别说接下来的动态显示了。图片一般是多种颜色的所以每一个像素都需要红绿蓝三基色信号,即一个字节,而文字就不同了,我们一般一个文字都是一种颜色所以我们可以仅仅用一位0和1来表示这个像素是现实还是不显示,这样就可以就可以节省大量存储空间。这次我要显示的是128*128的汉字,所以一行最多显示640/128=5个字符。为了节省存储空间我把用字模软件提取出来的是64*64的字。但显示时让他每一个数据显示两个像素点就可以放大为128*128的字。这次显示的是“应用 电子”,()中间的空格也算一个字。接下爱就和显示图片差不多了,下面就结合代码
分析
定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析
一下:(红字部分为分析)
module VGA (clk, h_sync, v_sync, rgb);
input clk;
output h_sync,v_sync;
output [7:0]rgb;
wire [7:0]RGB;
reg [7:0]rgb;
wire[63:0]out;
reg [9:0]
hcount;
//VGA行扫描计数器
reg [9:0] vcount;
//VGA场扫描计数器
wire
dat_enable;
wire
vga_clk;
`define RESOLUTION_640_480
//VGA行、场扫描时序参数表
`ifdef RESOLUTION_640_480
parameter
hdat_end
= 10'd639,
hsync_begin
= 10'd655,
hsync_end
= 10'd751,
h_end
= 10'd799,
vdat_end
= 10'd479,
vsync_begin
= 10'd489,
vsync_end
= 10'd491,
v_end
= 10'd524;
//调用PLL模块
PLL_25
PLL25_inst (
.inclk0 (clk),
.c0 (vga_clk)
);
`endif
ROM_1
ROM_1_inst (
.address ( {hcount[9:1]} ),
.clock ( clk ),
.q (out)
);
汉字ron的地址仅用行计数【9:1】位表示0到320。因为5个字的的共需要字节数位512即20480位,需要显示的区域为640*128,因为放大过2倍实际上是320*64,即64行,320列,在rom中我存放是也是按照这个规律,我在地址0出存放64位即第一列上的元素,只不过取模的时候和显示的时候高低位是相反的,这点的确很迷惑人,这个需要仔细琢磨。这也是我下面写if(out[63-vcount[6:1]])rgb<=8'b00011100;这句话里面用到63减的原因,让高低位翻转。还有汉字我是按照列的从上到下来取模的,我就不分析了,这可能也印证了我高中数学老师天天挂在嘴边的一句话:只可意会,不可言传。
这是汉字的取模设置
//************************VGA驱动部分*******************************
//行扫描
always @(posedge vga_clk)
begin
if (hcount==h_end)
hcount <= 10'd0;
else
hcount <= hcount + 10'd1;
end
assign hcount_ov = (hcount == h_end);
//场扫描
always @(posedge vga_clk)
begin
if (hcount_ov)
begin
if (vcount==v_end)
vcount <= 10'd0;
else
vcount <= vcount + 10'd1;
end
end
//数据、同步信号输
assign dat_enable =((hcount < hdat_end)&&(vcount < vdat_end));
assign h_sync=((hcount>hsync_begin)&&(hcountvsync_begin)&&(vcount=256&&vcount<384);
这里定义的是汉字显示区域,在汉字显示去读取出来64位的数据根据vcount来判断在是哪一行并判断是否显示该像素点,为1显示,为0不显示。
always@(posedge vga_clk)
begin
if(dat_enable)
begin
if(zi_area)
if(out[63-vcount[6:1]])rgb<=8'b00011100;
else rgb<=8'b10011011;
else rgb<=8'b10010010;
end
else rgb<=8'b00000000;
end
endmodule
效果如下:
Author
:wzt 2012年6月9日21:02:58