FPGA学习笔记03——RGB LCD显示屏

这篇具有很好参考价值的文章主要介绍了FPGA学习笔记03——RGB LCD显示屏。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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使能。
fpga  rgb888,fpga开发,学习,笔记
以1024600分辨率显示器为例,图中灰色部分为显示器黑框部分,白色区域才是有效显示区域,在进行行列扫描时可以用计数器控制DE信号,使其仅仅在有效显示区域内为高电平。
fpga  rgb888,fpga开发,学习,笔记
对于每一行的扫描,需要先经过行同步时间(HSPW)、显示后延时间(HBP)才能到达有效显示时间(HOZVAL),在此之后还有一段时间的显示前沿(HFP)。列扫描同理。
fpga  rgb888,fpga开发,学习,笔记
fpga  rgb888,fpga开发,学习,笔记
不同显示器的时序参数如图,这里使用1024
600屏。
fpga  rgb888,fpga开发,学习,笔记

系统框图

系统分为LCD显示模块和LCD驱动模块。
LCD显示模块定义显示的区域和对应颜色,
LCD驱动模块定义行扫描、列扫描、DE等信号,使LCD屏工作
fpga  rgb888,fpga开发,学习,笔记

LCD屏显示彩条

对不同的显示区域赋给对应的颜色值

//屏幕分辨率为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内。
fpga  rgb888,fpga开发,学习,笔记
fpga  rgb888,fpga开发,学习,笔记文章来源地址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模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • LCD1602液晶显示屏

    主函数 LCD1602.c LCD1602.h 接线图:   1、1602屏幕=16x2=32个字符,总共有32个字符  2、每个字符由35个像素组成 每个像素由一小块液晶控制 --------------------------------------------------------------------------------------------------------------------------------- 液晶的控制原理: 不施加电压——液晶完

    2024年02月07日
    浏览(46)
  • LCD拼接屏、LED显示屏和OLED显示屏的主要区别

    我们在生活或工作中经常看到大大小小的显示屏,但很多人却分不清楚这些屏到底属于哪一类,今天sostron与大家一起来分享下关于:LCD拼接屏、LED显示屏、OLED透明屏三者的区别。 LCD拼接屏、LED显示屏和OLED显示屏是不同类型的显示技术,它们在构成、工作原理和特点上存在明

    2024年02月17日
    浏览(44)
  • 矩阵键盘控制LCD1602显示屏显示数字

     主函数部分,其中的LCD1602.h的头文件是在哔哩哔哩江科大自化协的博主的视频资料 总结:     首先是我学习时遇到的问题: 在我一开始运行的时候出现的问题就是,一开始在给主函数的keynumber赋值的时候,等号的左值是叫做Matrixkey的函数,当我按下1按键时显示屏显示01,

    2024年02月11日
    浏览(42)
  • STM32—LCD液晶显示屏

    目录 LCD液晶显示屏介绍 液晶的组成  物理特性 液晶显示屏内部构造  颜色深度 点亮LCD显示屏 查看原理图 图片显示 保存到工程用户代码的Inc目录下 参数为数组名 字符显示  汉字显示 某些物质在熔融状态或被溶剂溶解之后,尽管失去固态物质的刚性,却获得了液体的易流动

    2024年02月04日
    浏览(46)
  • 【STM32篇】驱动LCD显示屏

    本次使用的硬件设备为野火的霸道V2开发板,显示器控制芯片型号为ILI9341,实际型号为ST7789V。在编写代码时参考的是ILI9341数据手册,二者差别不大,都是240*320分辨率。         ILI9341是一个用于TFT液晶显示的单芯片控制驱动器,具有262144色的240RGB x 320像素显示解决方案。

    2024年02月12日
    浏览(40)
  • LCD12864显示屏原理及使用教程

            LCD12864液晶显示模块是 128×64点阵的汉字图形型液晶显示模块,可显示汉字及图形,内置 8192个中文汉字(16X16 点阵)(需带有字库的型号才能显示中文)、128 个字符(8X16 点阵)及 64X256 点阵显示 RAM(GDRAM)。可与 CPU 直接接口,提供两种界面来连接微处理机:8

    2024年01月19日
    浏览(38)
  • STM32 使用LCD12864显示屏(串行方式)

    12864LCD液晶显示模块是一款4位/8位并行、2线或3线接口方式,内部含有国际一级、二级简体中文字库的图形点阵液晶模块。显示分辨率为128 64,内置8198个16 16点汉字,和128个16*8点ASCII字符集。 CS片选信号 (如果只有一款屏,可以将CS直接接到VCC上,实现两线通讯。) SID数据传

    2024年02月05日
    浏览(50)
  • 中景园0.96寸 OLED 显示屏 学习笔记

    OLED ,即 有机 发光二极管( Organic Light Emitting Diode )。OLED由于同时具备 自发光,不需背光源、对比度高、厚度薄 、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被认为是下一代的平面显示器新兴应用技术。 LCD都需要背光,而

    2023年04月08日
    浏览(37)
  • 5、江科大stm32视频学习笔记——OLED显示屏

    目录 1、OLED简介  2、OLED硬件电路 3、OLED驱动函函数简介和应用 4、用keil进行调试 4引脚OLED SCL和SDA是I2C通信引脚,需要接在I2C通信的引脚上 实验中用的模块是GPIO口模拟的I2C通信,故SCL和SDA两个端口可以接在任意的GPIO口上 7引脚OLED 右边5个引脚是SPI通信协议的引脚 如果是GPI

    2024年02月14日
    浏览(38)
  • 单片机 用LCD显示屏 输出字符串源代码(附Proteus图)

    附:字符型LCD显示屏型号:LM016L;这个代码应该是可以直接运行的

    2024年02月14日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包