FPGA-LCD1602显示-第一次尝试使用task写可综合程序

先上接线图:

VL:对比度,正常接一个1K的电阻就好了,如果电阻过大会出现一个个黑方块,而你要显示的就看不清楚了,反之如果电阻过小,就会根本显示不出东西,亮亮的一片。也可以接1K的电位器实现改对比度的功能。

RS:数据指令选择端: 0 写指令 1 读指令

RW:读写选择端           0 写指令/数据 1 读状态/数据

EN:使能端:下降沿使得指令数据生效

这些都是控制端口,要留心注意他们的接线

D0-D7:这些是数据端口,用来传递数据的。

Bl-  、 Bl+ :这些是背光电源,如果你上电连LCD都不亮就要检查一下这里。

HD44780内置了 DDRAM、CGROM和 CGRAM。

在 LCD模块上也固化
了字模存储器,这就是 CGROM和 CGRAM。HD44780内置了 192个常用字符的字模,
存于字符产生器 CGROM(Character Generator ROM)中,另外还有 8 个允许用户
自定义的字符产生 RAM,称为 CGRAM(Character Generator RAM)。下图说明了
CGROM和 CGRAM与字符的对应关系。

指令集:

信号真值表:

  RS     |    R/W    |      E    |     功能     |

   0       |      0       | 下降沿 | 写指令

   0       |      1       | 高电平 | 读状态

   1       |      0       | 下降沿 | 写数据

   1       |      1       | 高电平 | 读数据

简单写一下常用的指令:

显示开关光标设置:0x0f;(打开光标显示闪烁)

清屏设置: 0x01;

功能设置:0x31:;

显示地址设置0x06;

设置流程大概就是先设置好初始配置,然后定义写入地址,送入写的数据

代码如下:

module lcd1602_driver(
	clk,
	rst_n,     
	RSel,    
	R_W,     
	En,      
	Lcd_data,
	Lcd_Vcc, 
	Lcd_GND, 
	Lcd_A,   
	Lcd_K    
);
	input               clk;   //输入时钟
	input             rst_n;
	output         reg RSel;   //数据指令选择
	output              R_W;   //读写选择
	output           reg En;   //使能
	output reg[7:0]Lcd_data;  //数据位
	output          Lcd_Vcc;  //lcd 电源开关 +
	output          Lcd_GND;  //lcd 电源开关 -
	output            Lcd_A;  //lcd 背光 +
	output            Lcd_K;  //lcd 背光 -
	/*--------------初始化功能设置-------------*/
	parameter           Mode_Set =8'h31,//显示模式设置
				  Cursor_Dis_Set =8'h0c,//光标显示设置
		         Cursor_Move_Set =8'h80,//光标移动设置
				       Clear_Set =8'h01,//清屏
				   Init_ADDr_Set =8'h80;//起始位置
	/*-------------背光设置--------------------*/	         
	assign Lcd_Vcc=1'b1;//供电
	assign Lcd_GND=1'b0;//
	assign   Lcd_A=1'b1;//背光常开
	assign   Lcd_K=1'b0;//
	assign     R_W=1'b0;//只写
	
	/*---------任务列表------------*/
	task Write_order;
		input [7:0] order;//指令
		begin
			RSel<=1'b0;
			En<=1'b1;
			state<=state+1'b1;
			Lcd_data<=order;
		end
	endtask

	task En_Negedge;
		begin
			En<=1'b0;
			state<=state+1'b1;
		end
	endtask
	
	task Write_data;
		input [7:0] order_1;//数据
		begin
			RSel<=1'b1;
			En<=1'b1;
			state<=state+1'b1;
			Lcd_data<=order_1;
		end
	endtask
	/*--------驱动时钟------------*/
	wire lcd_clk=(cnt_clk==16'd24999);
	reg [15:0]cnt_clk;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			cnt_clk<=1'b0;
		end
		else if(cnt_clk==16'd24999)begin//延时500us
			cnt_clk<=1'b0;
		end
		else begin
			cnt_clk<=cnt_clk+1'b1;
		end
	end
	/*---------显示状态配置--------*/
	reg [4:0] state;
	always@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)begin
			RSel<=1'b0;
			En<=1'b0;
			state<=5'd0;
			Lcd_data<=1'b0;
		end
		else if(lcd_clk==1'b1)begin
			case(state)
			/*----------------初始化设置---------------------*/
			5'd0:begin
				Write_order(Mode_Set);
			end
			5'd1:begin
				En_Negedge();
			end
			5'd2:begin
				Write_order(Cursor_Dis_Set);//设置光标显示
			end
			5'd3:begin
				En_Negedge();
			end
			5'd4:begin
				Write_order(Cursor_Move_Set);//设置光标移动
			end
			5'd5:begin
				En_Negedge();
			end
			5'd6:begin
				Write_order(Clear_Set);//清屏
			end
			5'd7:begin
				En_Negedge();
			end
			/*-----显示区--------*/
			5'd8:begin
				Write_order(Init_ADDr_Set);//设置写入地址
			end
			5'd9:begin
				En_Negedge();
			end
			5'd10:begin
				Write_data("F");
			end
			5'd11:begin
				En_Negedge();
			end
			5'd12:begin
				Write_data("P");
			end
			5'd13:begin
				En_Negedge();
			end
			5'd14:begin
				Write_data("G");
			end
			5'd15:begin
				En_Negedge();
			end
			5'd16:begin
				Write_data("A");
			end
			5'd17:begin
				En_Negedge();
			end
			default:state<=5'bxxxx;
			endcase
		end
		else begin
			RSel<=RSel;
			En<=En;
			Lcd_data<=Lcd_data;
		end
	end
	
endmodule


 

猜你喜欢

转载自blog.csdn.net/weixin_41445387/article/details/89190269