📄 lcd.v
字号:
module lcd(clk,rst,lcd_e,lcd_rw,lcd_rs,data);
input clk,rst;
output lcd_e,lcd_rw,lcd_rs;
output [7:0] data;
reg lcd_e,lcd_rw,lcd_rs;
reg [7:0] data;
reg [10:0] state;
reg flag,flag1;
reg [5:0] address;
parameter IDLE =11'b00000000000;
parameter CLEAR =11'b00000000001; //清屏
parameter RETURNCURSOR =11'b00000000010; //归home位
parameter SETMODE =11'b00000000100;
//输入方式设置,读写数据后ram地址增/减1;画面动/不动
parameter SWITCHMODE =11'b00000001000;
//显示状态设置,显示开/关;光标开/关;闪烁开/关
parameter SHIFT =11'b00000010000;
//光标画面滚动 画面/光标平移一位;左/右平移一位
parameter SETFUNCTION =11'b00000100000;
//工作方式设置 1:8/1:4位数据接口;两行/一行显示;5x10/5x7点阵
parameter SETCGRAM =11'b00001000000; //设置CGRAM
parameter SETDDRAM =11'b00010000000; //设置DDRAM
parameter SETDDRAM1 =11'b00010000001;
parameter READFLAG =11'b00100000000; //
parameter WRITERAM =11'b01000000000; //写RAM
parameter READRAM =11'b10000000000; //读RAM
parameter cur_inc =1;
parameter cur_dec =0;
parameter cur_shift =1;
parameter cur_noshift =0;
parameter open_display =1;
parameter open_cur =0;
parameter blank_cur =0;
parameter shift_display =1;
parameter shift_cur =0;
parameter right_shift =1;
parameter left_shift =0;
parameter datawidth8 =1;
parameter datawidth4 =0;
parameter twoline =1;
parameter oneline =0;
parameter font5x10 =1;
parameter font5x7 =0;
function [7:0] ddram;
input [5:0] n;
begin
case(n)
6'b000_000:ddram=8'h43; //C
6'b000_001:ddram=8'h68; //h
6'b000_010:ddram=8'h61; //a
6'b000_011:ddram=8'h6e; //n
6'b000_100:ddram=8'h67; //g
6'b000_101:ddram=8'h73; //s
6'b000_110:ddram=8'h68; //h
6'b000_111:ddram=8'h61; //a
6'b001_000:ddram=8'h4d; //M
6'b001_001:ddram=8'h69; //i
6'b001_010:ddram=8'h6e; //n
6'b001_011:ddram=8'h67; //g
6'd12:ddram=8'h77; //w
6'd13:ddram=8'h65; //e
6'd14:ddram=8'h69; //i
6'd15:ddram=8'h21; //!
6'd16:ddram=8'h44; //D
6'd17:ddram=8'h65; //e
6'd18:ddram=8'h73; //s
6'd19:ddram=8'h69; //i
6'd20:ddram=8'h67; //g
6'd21:ddram=8'h6e; //n
6'd22:ddram=8'h62; //b
6'd23:ddram=8'h79; //y
6'd24:ddram=8'h3a; //:
6'd25:ddram=8'h53; //S
6'd26:ddram=8'h68; //h
6'd27:ddram=8'h75; //u
6'd28:ddram=8'h77; //w
6'd29:ddram=8'h61; //a
6'd30:ddram=8'h6e; //n
6'd31:ddram=8'h67; //g
endcase
end
endfunction
reg [15:0] clkcnt;
always @ (posedge clk)
if(!rst)
clkcnt<=16'b0000_0000_0000_0000;
else
begin
if(clkcnt==16'b1001_1100_0100_0000)
//if(clkcnt==16'b1001_1000_0100_0000)
clkcnt<=16'b0000_0000_0000_0000;
else
clkcnt<=clkcnt+1;
end
wire tc_clkcnt;
assign tc_clkcnt=(clkcnt==16'b1001_1100_0100_0000)?1:0;
//assign tc_clkcnt=(clkcnt==16'b1001_1000_0100_0000)?1:0;
reg clkdiv;
always @ (posedge tc_clkcnt)
if(!rst)
clkdiv<=0;
else
clkdiv<=~clkdiv;
reg clk_int;
always @ (posedge clkdiv)
if(rst==0)
clk_int<=0;
else
clk_int<=~clk_int;
always @ (negedge clkdiv)
if(rst==0)
lcd_e<=0;
else
lcd_e<=~lcd_e;
always @ (posedge clk_int or negedge rst)
if(!rst)
begin
state<=IDLE;
address<=6'b000_000;
flag<=0;
end
else
begin
case(state)
IDLE :begin
data<=8'bzzzz_zzzz;
if(flag==0)
begin
state<=SETFUNCTION;
flag<=1;
end
else
state<=SHIFT;
end
CLEAR :begin lcd_rs<=0;lcd_rw<=0;data<=8'b0000_0001;
state<=SETMODE;end
SETMODE :begin lcd_rs<=0;lcd_rw<=0;data[7:2]<=6'b000001;data[1]<=cur_inc;data[0]<=cur_noshift;
state<=SETDDRAM;end
RETURNCURSOR :begin lcd_rs<=0;lcd_rw<=0;data<=8'b00000010;
state<=SETDDRAM;end
SWITCHMODE :begin lcd_rs<=0;lcd_rw<=0;data[7:3]<=5'b00001;data[2]<=open_display;data[1]<=open_cur;data[0]<=blank_cur;
state<=CLEAR;end
SHIFT :begin lcd_rs<=0;lcd_rw<=0;data[7:4]<=4'b0001;data[3]<=shift_cur;data[2]<=left_shift;data[1:0]<=2'b00;
state<=IDLE;end
SETFUNCTION :begin lcd_rs<=0;lcd_rw<=0;data[7:5]<=3'b001;data[4]<=datawidth8;data[3]<=twoline;data[2]<=font5x10;data[1:0]<=2'b00;
state<=SWITCHMODE;end
SETCGRAM :begin lcd_rs<=0;lcd_rw<=0;data<=8'b01000000;state<=IDLE;end
SETDDRAM :begin lcd_rs<=0;lcd_rw<=0;data<=8'b10000000;state<=WRITERAM;end
SETDDRAM1 :begin lcd_rs<=0;lcd_rw<=0;data<=8'b11000000;state<=WRITERAM;end //设置第二行首地址
WRITERAM :begin
if(address<=6'd15)
begin
lcd_rs<=1;
lcd_rw<=0;
data<=ddram(address);
address<=address+1;
state<=WRITERAM;
flag1<=1;
end
else
begin
if (address>=6'd16&&address<=6'd31&&flag1)
begin
flag1<=0;
state<=SETDDRAM1;
end
else
begin
if (address<=6'd31)
begin
lcd_rs<=1;
lcd_rw<=0;
data<=ddram(address);
address<=address+1;
state<=WRITERAM;
end
else
begin
lcd_rs<=0;
lcd_rw<=0;
state<=SHIFT;
//state<=CLEAR;
address<=6'b000_000;
end
end
end
end
endcase
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -