RGB LCD显示原理
LCD屏与FPGA芯片接口如下,其中LCD_R0—R7,G0—G7,B0—B7为RGB888信号,
LCD_BL:背光板使能,为高时背光板才亮
LCD_DE:RGB数据使能,为高时RGB数据有效
LCD_VSYNC:竖直(列)扫描有效
LCD_HSYNC:水平(行)扫描有效
LCD_CLK:显示器时钟
//在控制RGB LCD屏时,即可使用DE使能,也能用VSYNC和HSYNC使能。
以1024600分辨率显示器为例,图中灰色部分为显示器黑框部分,白色区域才是有效显示区域,在进行行列扫描时可以用计数器控制DE信号,使其仅仅在有效显示区域内为高电平。
对于每一行的扫描,需要先经过行同步时间(HSPW)、显示后延时间(HBP)才能到达有效显示时间(HOZVAL),在此之后还有一段时间的显示前沿(HFP)。列扫描同理。
不同显示器的时序参数如图,这里使用1024600屏。
系统框图
系统分为LCD显示模块和LCD驱动模块。
LCD显示模块定义显示的区域和对应颜色,
LCD驱动模块定义行扫描、列扫描、DE等信号,使LCD屏工作
LCD屏显示彩条
对不同的显示区域赋给对应的颜色值文章来源:https://www.toymoban.com/news/detail-777279.html
//屏幕分辨率为1024*600,显示彩条
module LCD_colorbar_top(
input clk,
input rst_n,
output lcd_de,
output lcd_hs,
output lcd_vs,
output lcd_bl,
output lcd_clk,
inout [23:0] lcd_rgb
);
wire pixel_xpos ;
wire pixel_ypos ;
wire h_disp ;
wire v_disp ;
wire pixel_data ;
wire pixel_xpos ;
wire pixel_ypos ;
wire h_disp ;
wire v_disp ;
LCD_display u_LCD_display(
.clk (clk ),
.rst_n (rst_n ),
.pixel_xpos (pixel_xpos ),
.pixel_ypos (pixel_ypos ),
.h_disp (h_disp ),
.v_disp (v_disp ),
.pixel_data (pixel_data )
);
LCD_driver u_LCD_driver(
.clk (clk ),
.rst_n (rst_n ),
.pixel_data (pixel_data ),
.pixel_xpos (pixel_xpos ),
.pixel_ypos (pixel_ypos ),
.h_disp (h_disp ),
.v_disp (v_disp ),
.lcd_de (lcd_de ),
.lcd_hs (lcd_hs ),
.lcd_vs (lcd_vs ),
.lcd_bl (lcd_bl ),
.lcd_clk (lcd_clk ),
.lcd_rgb (lcd_rgb )
);
endmodule
//显示模块
module LCD_display(
input clk,
input rst_n,
input [10:0] pixel_xpos,
input [10:0] pixel_ypos,
input h_disp,
input v_disp,
output reg [23:0] pixel_data
);
parameter WHITE = 24'hffffff;
parameter BLACK = 24'h000000;
parameter RED = 24'hff0000;
parameter GREEN = 24'h00ff00;
parameter BLUE = 24'h0000ff;
//不同区域显示不同颜色
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
pixel_data <= BLACK;
else begin
if((pixel_xpos > 0) && (pixel_xpos <= h_disp/5*1))
pixel_data <= WHITE;
else if ((pixel_xpos > h_disp/5*1) && (pixel_xpos <= h_disp/5*2))
pixel_data <= BLACK;
else if ((pixel_xpos > h_disp/5*2) && (pixel_xpos <= h_disp/5*3))
pixel_data <= RED;
else if ((pixel_xpos > h_disp/5*3) && (pixel_xpos <= h_disp/5*4))
pixel_data <= GREEN;
else
pixel_data <= BLUE;
end
endmodule
//驱动模块
module LCD_driver(
input clk,
input rst_n,
input [23:0] pixel_data,
//像素位置
output [10:0] pixel_xpos,
output [10:0] pixel_ypos,
output h_disp,
output v_disp,
//RGB LCD control
output lcd_de,
output lcd_hs,
output lcd_vs,
output lcd_bl,
output lcd_clk,
output [23:0] lcd_rgb
);
parameter H_SYNC_7016 = 11'd20;
parameter H_BACK_7016 = 11'd140;
parameter H_DISP_7016 = 11'd1024;
parameter H_FRONT_7016 = 11'd160;
parameter H_TOTAL_7016 = 11'd1344;
parameter V_SYNC_7016 = 11'd3;
parameter V_BACK_7016 = 11'd20;
parameter V_DISP_7016 = 11'd600;
parameter V_FRONT_7016 = 11'd120;
parameter V_TOTAL_7016 = 11'd635;
wire lcd_en;
reg [10:0] h_cnt;
reg [10:0] v_cnt;
assign lcd_bl = 1;
assign lcd_hs = 1;
assign lcd_vs = 1;
assign lcd_clk = clk;
assign h_disp = H_DISP_7016;
assign v_disp = V_DISP_7016;
assign lcd_de = lcd_en;
assign lcd_en = (h_cnt >= H_SYNC_7016 + H_BACK_7016) && (h_cnt <= H_SYNC_7016 + H_BACK_7016 + H_DISP_7016)
&& (v_cnt >= V_SYNC_7016 + V_BACK_7016) && (v_cnt <= V_SYNC_7016 + V_BACK_7016 + V_DISP_7016)
? 1 : 0;
assign data_reg = (h_cnt >= H_SYNC_7016 + H_BACK_7016 - 1) && (h_cnt <= H_SYNC_7016 + H_BACK_7016 + H_DISP_7016 - 1)
&& (v_cnt >= V_SYNC_7016 + V_BACK_7016) && (v_cnt <= V_SYNC_7016 + V_BACK_7016 + V_DISP_7016)
? 1 : 0;
assign lcd_rgb = lcd_en ? pixel_data : 24'd0;
assign pixel_xpos = data_reg ? (h_cnt - (H_SYNC_7016 + H_BACK_7016 - 1)) : 11'd0;
assign pixel_ypos = data_reg ? (v_cnt - (V_SYNC_7016 + V_BACK_7016 - 1)) : 11'd0;
//水平扫描计数器和竖直扫描计数器
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
h_cnt <= 0;
else begin
if(h_cnt == H_BACK_7016 - 1)
h_cnt <= 0;
else
h_cnt <= h_cnt + 1;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
v_cnt <= 0;
else if(h_cnt == H_BACK_7016 - 1) begin
if(v_cnt == V_BACK_7016 - 1)
v_cnt <= 0;
else
v_cnt <= v_cnt + 1;
end
end
endmodule
LCD屏显示字符和图片
显示字符和图片时LCD_driver不变,通过改变pixel_data的值来显示不同的内容。
文字的显示是通过特定像素的高亮来实现的,用PCtoLCD2002软件可实现字符到字模的转换。
使用PicToLCD软件可将图片转换为coe文件并存储到ROM IP内。
文章来源地址https://www.toymoban.com/news/detail-777279.html
//显示字符和图片
module LCD_display(
input clk,
input rst_n,
input [10:0] pixel_xpos,
input [10:0] pixel_ypos,
input h_disp,
input v_disp,
output reg [23:0] pixel_data
);
//背景和字符的颜色
parameter BACK_COLOR = 24'hffffff;
parameter CHAR_COLOR = 24'h000000;
//字符起始位置和尺寸
parameter CHAR_X_START = 11'd1;
parameter CHAR_Y_START = 11'd110;
parameter CHAR_WITH = 11'd96;
parameter CHAR_HEIGHT = 11'd32;
//图片起始位置和尺寸
parameter PIC_X_START = 11'd1;
parameter PIC_Y_START = 11'd1;
parameter PIC_WITH = 11'd100;
parameter PIC_HEIGHT = 11'd100;
wire [10:0] x_cnt;
wire [10:0] y_cnt;
wire rom_rd_en;
reg [95:0] char [31:0];
assign rom_rd_en = 1;
assign x_cnt = pixel_xpos - CHAR_X_START;
assign y_cnt = pixel_ypos - CHAR_Y_START;
//字模数据,3个字,每个字尺寸32*32,总共96*32
always @(*) begin
char[0] <= 96'h000000000000000000000000;
char[1] <= 96'h000000000000000000000000;
char[2] <= 96'h003C1C000000000000001000;
char[3] <= 96'h003C1E300000004010441980;
char[4] <= 96'h003C1C7803FFFFE00FE231C0;
char[5] <= 96'h3FFFFFFC000001F008633100;
char[6] <= 96'h183C1C000000038008613200;
char[7] <= 96'h003C1C000000060008612220;
char[8] <= 96'h01FC1C0000000C00086FFFF0;
char[9] <= 96'h01E0C0000000300008606000;
char[10] <= 96'h03C3C060000160000FE06000;
char[11] <= 96'h03FFFFF00001C00008604018;
char[12] <= 96'h0387E0F00001C000087FFFFC;
char[13] <= 96'h07C731E00001801008608200;
char[14] <= 96'h0EEE39C00001803808618300;
char[15] <= 96'h0E7E1F803FFFFFFC08630380;
char[16] <= 96'h1F7C1F00000180000866FEE0;
char[17] <= 96'h3BBC3F00000180000FED823E;
char[18] <= 96'h33FFFF800001800008718618;
char[19] <= 96'h03FC03E00001800008618600;
char[20] <= 96'h01E007FC0001800008618620;
char[21] <= 96'h03FFFFFE000180001863FFF0;
char[22] <= 96'h07E1C0380001800018610060;
char[23] <= 96'h1E31C0000001800018600060;
char[24] <= 96'h3879DE000001800010600460;
char[25] <= 96'h00F9C78000018000107FFE60;
char[26] <= 96'h01E1C3E00001800010600060;
char[27] <= 96'h03C1C0F00021800020600060;
char[28] <= 96'h071FC070001F800023C00FC0;
char[29] <= 96'h1E07C0700007000040C003C0;
char[30] <= 96'h000380000002000040000180;
char[31] <= 96'h000000000000000000000000;
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
pixel_data <= BACK_COLOR;
//显示图片
else if((pixel_xpos >= PIC_X_START) && (pixel_xpos <= PIC_X_START + PIC_WITH) && (pixel_ypos >= PIC_Y_START) && (pixel_ypos <= PIC_Y_START + PIC_HEIGHT))
//从ROM中读取图片数据
pixel_data <= rom_rd_data;
//显示字符
else if((pixel_xpos >= CHAR_X_START) && (pixel_xpos <= CHAR_X_START + CHAR_WITH) && (pixel_ypos >= CHAR_Y_START) && (pixel_ypos <= CHAR_Y_START + CHAR_HEIGHT))
//当char的数据为1时,像素高亮
if(char[y_cnt][CHAR_WITH - 1 - x_cnt])
pixel_data <= CHAR_COLOR;
else
pixel_data <= BACK_COLOR;
end
always @(posedge lcd_pclk or negedge rst_n) begin
if(!rst_n)
rom_addr <= 14'd0;
//当横纵坐标位于图片显示区域时,累加ROM地址
else if((pixel_xpos >= PIC_X_START) && (pixel_xpos <= PIC_X_START + PIC_WITH) && (pixel_ypos >= PIC_Y_START) && (pixel_ypos <= PIC_Y_START + PIC_HEIGHT))
rom_addr <= rom_addr + 1'b1;
//当横纵坐标位于图片区域最后一个像素点时,ROM地址清零
else if((pixel_ypos >= PIC_Y_START + PIC_HEIGHT))
rom_addr <= 14'd0;
end
//ROM_IP:存储图片
blk_mem_gen_0 blk_mem_gen_0 (
.clka (clk), // input wire clka
.ena (rom_rd_en), // input wire ena
.addra (rom_addr), // input wire [13 : 0] addra
.douta (rom_rd_data) // output wire [23 : 0] douta
);
endmodule
到了这里,关于FPGA学习笔记03——RGB LCD显示屏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!