FPGA 27 RGB888的 图片(调用内部rom实现)显示
主要功能 :设计了Image_Send 图片发送模块
实现(设计)流程:根据RGB888 屏幕的工作原理以及数据传输协议方式,编写输出信号的发送,进而将我们要显示的图像显示到屏幕上。
实验目的 : 在fpga 内部划分出一部分ROM资源,存放一张图片的二进制编码在rom中,通过设计输入端口获取rgb888驱动的X轴和Y轴坐标,根据输入的坐标轴,读取rom中存放的图像像素点,最后输出给屏幕,实现屏幕显示.(注:实际上,哪怕用光所有rom资源,要显示一张图片也是很有难度的,所以只能是根据rom的大小,设置我们要显示的一个区域,让其他地方都是黑色即可)
实验现象 : 通过内部设计一个图片显示模块,实现图片通过rom 实现图片的显示.
注: 这里在读取的时候,需要考试输入时钟的问题,是选择50Mhz 还是 33Mhz ,本质来说,需要根据 X,Y轴的输出坐标时钟是最好的,可以避免出现亚稳态的情况。
在代码中:我们可以看到,模块内部加载了一个rom资源的配置,rom资源也是极其有限的,无法实现整个屏幕数据的像素点的保存。另外,addr 的地址是根据输入的X坐标和Y坐标来实现的,因为rom本身是一维的,也就是说,地址都是自加的,并不存在像二维数组那样,有2个坐标轴来构成.所以只能在模块内部,通过X 和Y 输入的坐标轴,做相应的处理,得到addr地址。
module Image_Send(
Clk_50M,
Rst_n,
tft_de,
hcount,
vcount,
data_in
);
input Clk_50M;
input Rst_n;
input tft_de;
input [9:0]hcount;
input [9:0]vcount;
output [15:0]data_in;
wire img_ack;
localparam IMG_H = 120,
IMG_V = 120;
localparam TFT_H = 800, // TFT 5.0 屏幕
TFT_V = 272 ;
localparam IMG_HM= TFT_H - IMG_H,//图片行方向可移动像素点个数
IMG_VM= TFT_V - IMG_V; //图片场方向可移动像素点个数
reg [9:0]img_hbegin = 250; // 图片左上角显示的第一个位置的行(X)坐标
reg [9:0]img_vbegin = 250; // 图片左上角显示的第一个位置的列 (Y) 坐标
reg [13:0]addr; //rom 图片的地址
wire [15:0]img_data; //图片数据
//
rom_img rom_img0(
.address(addr),
.clock(Clk_50M),
.q(img_data)
)
;
assign img_ack = tft_de && (hcount >= img_hbegin && hcount < img_hbegin+IMG_H)
&& (vcount >= img_vbegin && vcount < img_vbegin + IMG_V)?1'b1:1'b0 ;
// 图片数据发送使能信号条件:
// tft_de 必须使能
// hcount 接收 x轴坐标的值要 大于img_hbegin 且小于img_hbegin + IMG_H ,即认为x轴必须在该区间内
// vcount 接收 y轴的坐标要 大于imgimg_vbegin_hbegin img_vbegin + IMG_V ,即认为y轴必须在该区间内
// 计算出在x,y 需要读取rom 的地址,通过地址读取该数据值
always @(posedge Clk_50M or negedge Rst_n) begin
if(!Rst_n)
addr <= 14'd0;
else if(img_ack)
addr <= (hcount - img_hbegin)+(vcount -img_vbegin)*IMG_H;
else
addr <= 14'd0;
end
assign data_in = img_ack? img_data : 16'd0; //发送给屏幕的数据
endmodule