先上接线图:
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;
设置流程大概就是先设置好初始配置,然后定义写入地址,送入写的数据
这里我提醒下,因为电压的原因,好像FPGA不能进行两行显示,显示的话可以,但是字符暗的几乎看不到。。。。你们可以试一试,可能我这里有错误
代码如下:
modulelcd1602_driver( clk, rst_n, RSel, R_W, En, Lcd_data, Lcd_Vcc, Lcd_GND, Lcd_A, Lcd_K); inputclk; //输入时钟inputrst_n; outputregRSel; //数据指令选择outputR_W; //读写选择outputregEn; //使能outputreg[7:0]Lcd_data; //数据位outputLcd_Vcc; //lcd电源开关+outputLcd_GND; //lcd电源开关-outputLcd_A; //lcd背光+outputLcd_K; //lcd背光-/*--------------初始化功能设置-------------*/parameterMode_Set=8'h31,//显示模式设置Cursor_Dis_Set=8'h0c,//光标显示设置Cursor_Move_Set=8'h80,//光标移动设置Clear_Set=8'h01,//清屏Init_ADDr_Set=8'h80;//起始位置/*-------------背光设置--------------------*/assignLcd_Vcc=1'b1;//供电assignLcd_GND=1'b0;//assignLcd_A=1'b1;//背光常开assignLcd_K=1'b0;//assignR_W=1'b0;//只写/*---------任务列表------------*/taskWrite_order; input [7:0] order;//指令beginRSel<=1'b0;En<=1'b1;state<=state+1'b1;Lcd_data<=order; endendtasktaskEn_Negedge; beginEn<=1'b0;state<=state+1'b1;endendtasktaskWrite_data; input [7:0] order_1;//数据beginRSel<=1'b1;En<=1'b1;state<=state+1'b1;Lcd_data<=order_1; endendtask/*--------驱动时钟------------*/wirelcd_clk=(cnt_clk==16'd24999);reg [15:0]cnt_clk; always@(posedgeclkornegedgerst_n)beginif(rst_n==1'b0)begincnt_clk<=1'b0;endelseif(cnt_clk==16'd24999)begin//延时500uscnt_clk<=1'b0;endelsebegincnt_clk<=cnt_clk+1'b1;endend/*---------显示状态配置--------*/reg [4:0] state; always@(posedgeclkornegedgerst_n)beginif(rst_n==1'b0)beginRSel<=1'b0;En<=1'b0;state<=5'd0;Lcd_data<=1'b0;endelseif(lcd_clk==1'b1)begincase(state) /*----------------初始化设置---------------------*/5'd0:beginWrite_order(Mode_Set); end5'd1:beginEn_Negedge(); end5'd2:beginWrite_order(Cursor_Dis_Set);//设置光标显示end5'd3:beginEn_Negedge(); end5'd4:beginWrite_order(Cursor_Move_Set);//设置光标移动end5'd5:beginEn_Negedge(); end5'd6:beginWrite_order(Clear_Set);//清屏end5'd7:beginEn_Negedge(); end/*-----显示区--------*/5'd8:beginWrite_order(Init_ADDr_Set);//设置写入地址end5'd9:beginEn_Negedge(); end5'd10:beginWrite_data("F"); end5'd11:beginEn_Negedge(); end5'd12:beginWrite_data("P"); end5'd13:beginEn_Negedge(); end5'd14:beginWrite_data("G"); end5'd15:beginEn_Negedge(); end5'd16:beginWrite_data("A"); end5'd17:beginEn_Negedge(); enddefault:state<=5'bxxxx;endcaseendelsebeginRSel<=RSel; En<=En; Lcd_data<=Lcd_data; endendendmodule