为了实现16位彩色图像的显示,需要对图片缩小(片上ROM的限制)。本人采用60*100像素的图片(总计72000bits),即显示的时候需要将图像放大8倍显示(800×480的屏幕)。同样使用Img2Lcd软件图片转为需要的bmp格式(水平扫描模式、16位真彩色)(或者用PS、qq截图(保存为bmp格式)、电脑自带画图软件等,都可以完成转换)。
之后使用Matlab将bmp文件信息转化为RGB565格式的mif文件,m文件的代码如下。
clear; clc; n=6000;%100*60--16bit myImg = imread('C:\Users\Administrator\Desktop\love24bit2.bmp');%读取.bmp文件 fid=fopen('C:\Users\Administrator\Desktop\love16.mif','w');%打开待写入的.mif文件 fprintf(fid,'WIDTH=16;\n');%写入存储位宽16位 fprintf(fid,'DEPTH=6000;\n');%写入存储深度6000 fprintf(fid,'ADDRESS_RADIX=UNS;\n');%写入地址类型为无符号整型 fprintf(fid,'DATA_RADIX=HEX;');%写入数据类型为16进制 fprintf(fid,'CONTENT BEGIN\n');%起始内容 image(myImg); for i=0:n-1 %RGB888 -> RGB565 x = mod(i,100)+1; y = fix(i/100)+1; r = uint16(myImg(y,x,1)/8); g = uint16(myImg(y,x,2)/4); b = uint16(myImg(y,x,3)/8);%由于输出的图像为uint8,所以等式左边的变量无法赋值为其他类型 r = dec2bin(r); g = dec2bin(g); b = dec2bin(b);%十进制转二进制 r = num2str(r); g = num2str(g); b = num2str(b);%数字转字符串 if length(r)==1 %根据字符串长度补零--r r = strcat('0000',r); elseif length(r)==2 r = strcat('000',r); elseif length(r)==3 r = strcat('00',r); elseif length(r)==4 r = strcat('0',r); else r = r; end if length(g)==1 %根据字符串长度补零--g g = strcat('00000',g); elseif length(g)==2 g = strcat('0000',g); elseif length(g)==3 g = strcat('000',g); elseif length(g)==4 g = strcat('00',g); elseif length(g)==5 g = strcat('0',g); else g = g; end if length(b)==1 %根据字符串长度补零--b b = strcat('0000',b); elseif length(b)==2 b = strcat('000',b); elseif length(b)==3 b = strcat('00',b); elseif length(b)==4 b = strcat('0',b); else b = b; end k = strcat(r,g,b);%但是此处可以 %k = str2num(k); k = bin2dec(k); fprintf(fid,'\t%d:%x;\n',i,k); %disp(k); end fprintf(fid,'END;\n'); fclose(fid);%关闭文件
查阅Matlab中文手册得知,软件读取8位的bmp图像时转化为单个矩阵。而读取16位bmp图像时,将其转化为3个8位矩阵,所以提取图像数据转为RGB565时需要除以特定的数。因为Matlab会把数据自动转化为uint8类型,所以需要将数据强制类型转换为二进制。在数据的高位补零后,再用字符串连接函数,将其连接为16位的字符串。最后用二进制转十进制函数,把字符串直接转为数字,存与指定的mif文件中。
定制好ROM为16位,6000深度,例化下载后,其显示结果如下(其实,由于matlab读取16位bmp图像时,将其转化为3个8位矩阵。故,可不需要用软件转换为16位的bmp文件再用matlab提取数据)。
从以上图像可以看出,最终完成了基于ROM的TFT屏图像完美显示。
显示的Verilog主要程序如下:
/*color_rom--彩色-16位*/ localparam BMP_W = 11'd100, //显示区域宽度 = 图片宽 BMP_H = 11'd60; //显示区域高度 = 图片高 wire [12:0] pic_addr; wire [15:0] q; assign pic_addr = hcount[10:3] + vcount[10:3]*BMP_W; color16_rom color16_rom( .address(pic_addr), .clock(clk), .q(q) ); assign disp_data = q; /*color_rom-end*/