FPGA-LCD字符显示驱动

显示字符驱动

1.用字符取模软件取模

00000000;
00000000;
00000000;
00000000;
00000000;
00000000;
00000000;
00000000;
00000000;
00000000;
00000000;
0003C000;
0003C000;
0003C000;
0007E000;
0007E000;
0006E000;
0006E000;
000CF000;
000CF000;
000C7000;
000C7000;
00187800;
00187800;
00187800;
00183800;
00303C00;
00303C00;
00303C00;
00301C00;
00601E00;
00601E00;
00601E00;
00600E00;
00E00E00;
00C00F00;
00C00F00;
00FFFF00;
01FFFF00;
01800780;
01800780;
01800780;
03800780;
030003C0;
030003C0;
030003C0;
070003C0;
060001E0;
060001E0;
060001E0;
0E0001E0;
0E0001F0;
1F0001F8;
7FC00FFE;
7FC00FFE;
00000000;
00000000;
00000000;
00000000;
00000000;
00000000;
00000000;
00000000;
00000000;/*"A",0*/


调用rom

ROM是只读存储器(Read-Only Memory)的简称,是一种只能读出事先所存数据的固态半导体存储器。其特性是一旦储存资料就无法再将之改变或删除。通常用在不需经常变更资料的电子或电脑系统中,并且资料不会因为电源关闭而消失。

rom初始化文档创建

新建文本文件在前面写上:

MEMORY_INITIALIZATION_RADIX=16;(进制)
MEMORY_INITIALIZATION_VECTOR=

把文件格式调成 .coe

调用rom的IP核

在配置的第四页加载rom的初始化文件(具体配置不多说明)

上代码吧

top.v

module top(ext_clk_25m,ext_rst_n,lcd_light_en,lcd_clk,lcd_hsy,lcd_vsy,lcd_r,lcd_g,lcd_b
    );
	input ext_clk_25m;
	input ext_rst_n;
	output lcd_light_en;
	output lcd_clk;
	output lcd_hsy;
	output lcd_vsy;
	output [4:0] lcd_r;
	output [5:0] lcd_g;
	output [4:0] lcd_b;
	
	wire [31:0] rom_db;
	wire [5:0] rom_ab;
	lcd_controller uut_lcd_controller(
	.clk(ext_clk_25m),
	.rst_n(ext_rst_n),
	.lcd_light_en(lcd_light_en),
	.lcd_clk(lcd_clk),
	.lcd_hsy(lcd_hsy),
	.lcd_vsy(lcd_vsy),
	.lcd_r(lcd_r),
	.lcd_g(lcd_g),
	.lcd_b(lcd_b),
	.rom_db(rom_db),
	.rom_ab(rom_ab)
    );

	rom_controller uut_rom_controller (
  .clka(ext_clk_25m), // input clka
  .addra(rom_ab), // input [5 : 0] addra
  .douta(rom_db) // output [31 : 0] douta
);
endmodule

lcd_controller.v

module lcd_controller(clk,rst_n,lcd_light_en,lcd_clk,lcd_hsy,lcd_vsy,lcd_r,lcd_g,lcd_b,rom_db,rom_ab
    );
	input clk;
	input rst_n;
	input [31:0] rom_db;
	
	output [5:0]rom_ab;
	output lcd_light_en;
	output lcd_clk;
	output reg lcd_hsy;
	output reg lcd_vsy;
	output [4:0] lcd_r;
	output [5:0] lcd_g;
	output [4:0] lcd_b;
	
	parameter HSY_TH=9'D408-1'D1;//周期
	parameter HSY_THS=9'D30     ;//脉冲宽度
	parameter HSY_THB=9'D38     ;//后沿
	parameter HSY_TEP=9'D320    ;//显示周期
	parameter HSY_THE=9'D68     ;//同步周期
	parameter HSY_THF=9'D20     ;//前沿
	parameter VSY_TV=9'D262-1'D1;//周期
	parameter VSY_TVS=9'D3      ;//脉冲宽度
	parameter VSY_TVB=9'D15     ;//后沿
	parameter VSY_TVD=9'D240    ;//显示周期
	parameter VSY_TVF=9'D4      ;//前沿
	//lcd背光常开
	assign lcd_light_en=1'b1;
	
	//配置驱动时钟6.25mHz
	reg [1:0] lcd_cnt;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			lcd_cnt<=1'b0;
		end
		else begin
			lcd_cnt<=lcd_cnt+1'b1;
		end
	end
	assign lcd_clk=lcd_cnt[1];
	wire dchange ={lcd_cnt==2'd2};
	//X和Y轴计数器
	reg[8:0] xcnt;
	reg[8:0] ycnt;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			xcnt<=1'b0;
		end
		else if(dchange==1'b1)begin
			if(xcnt==HSY_TH)begin
				xcnt<=1'b0;
			end
			else begin
				xcnt<=xcnt+1'b1;
			end
		end
		else;
	end
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			ycnt<=1'b0;
		end
		else if(dchange&&xcnt==HSY_TH)begin
			if(ycnt==VSY_TV)begin
				ycnt<=1'b0;
			end
			else begin
				ycnt<=ycnt+1'b1;
			end
		end
		else begin
			ycnt<=ycnt;
		end
	end
	
	//lcd显示的有效区域
	reg valid;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			valid<=1'b0;
		end
		else if(ycnt>=(VSY_TVS+VSY_TVB)&&ycnt<(VSY_TVS+VSY_TVB+VSY_TVD)&&
		xcnt>=(HSY_THS+HSY_THB)&&xcnt<(HSY_TEP+HSY_THB+HSY_THE))begin
			valid<=1'b1;
		end
		else begin
			valid<=1'b0;
		end
	end
	
	//LCD驱动行场同步信号产生逻辑
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			lcd_hsy<=1'b1;
		end
		else if(xcnt==1'b0)begin
			lcd_hsy<=1'b0;
		end
		else if(xcnt>=HSY_THS)begin
			lcd_hsy<=1'b1;
		end
		else begin
			lcd_hsy<=lcd_hsy;
		end
	end
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			lcd_vsy<=1'b1;
		end
		else if(ycnt==1'b0)begin
			lcd_vsy<=1'b0;
		end
		else if(ycnt>=VSY_TVS)begin
			lcd_vsy<=1'b1;
		end
		else begin
			lcd_vsy<=lcd_vsy;
		end
	end
	
	assign rom_ab = ycnt-9'd18;
	
	reg [4:0]tmp_cnt;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			tmp_cnt<=1'b0;
		end
		else if(valid==1'b0)begin
			tmp_cnt<=1'b0;
		end
		else if(xcnt>=(HSY_THS+HSY_THB)&&xcnt<(HSY_THS+HSY_THB+6'd32)&&dchange)begin
				tmp_cnt<=tmp_cnt+1'b1;
		end
	end
	
	reg [15:0]lcd_db_rgb;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			lcd_db_rgb<=16'd0;
		end
		else if(ycnt>=(VSY_TVS+VSY_TVB)&&ycnt<(VSY_TVS+VSY_TVB+9'd64)
		&&xcnt>=(HSY_THS+HSY_THB)&&xcnt<(HSY_THS+HSY_THB+6'd32))begin
			if(dchange)begin  //数字区域
				if(rom_db[tmp_cnt]==1'b1)begin
					lcd_db_rgb<=16'h001f;
				end
				else begin
					lcd_db_rgb<=16'hf800;
				end
			end
			else;
		end
		else begin
			lcd_db_rgb<=1'b0;
		end
	end
	assign lcd_r =valid ? lcd_db_rgb[15:11]:5'd0;
	assign lcd_g =valid ? lcd_db_rgb[10:5]:6'd0;
	assign lcd_b =valid ? lcd_db_rgb[4:0]:5'd0;
	
endmodule

实验结果:(这里拍照的时候调了相机的亮度)

猜你喜欢

转载自blog.csdn.net/weixin_41445387/article/details/86532939
今日推荐