always@(posedge Sys_Clk or negedge Rst)
begin
if(!Rst) begin
down_delay<=1'b0;
end
else if(down_rise==1'b1)
down_delay<=1'b1;
else if(state != IDLE)
down_delay<=1'b0;
else
down_delay<=down_delay;
end
always@(posedge Sys_Clk or negedge Rst)
begin
if(!Rst) begin
right_delay<=1'b0;
end
else if(right_rise==1'b1)
right_delay<=1'b1;
else if(state != IDLE)
right_delay<=1'b0;
else
right_delay<=right_delay;
end
always@(posedge Sys_Clk or negedge Rst)
begin
if(!Rst) begin
data_in_delay<=1'b0;
end
else if(data_in_rise==1'b1)
data_in_delay<=1'b1;
else if(state != IDLE)
data_in_delay<=1'b0;
else
data_in_delay<=data_in_delay;
end
always@(posedge Sys_Clk or negedge Rst)
begin
if(!Rst) begin
clear_delay<=1'b0;
end
else if(clear_rise==1'b1)
clear_delay<=1'b1;
else if(state != IDLE)
clear_delay<=1'b0;
else
clear_delay<=clear_delay;
end
//state machine description,8个状态 只要用把位二进制就可以全部表示
parameter IDLE=8'b00_000_000;//初始状态
parameter SETFUNCTION=8'b00_000_001;//功能设置,8-bit+基本指令集0x30
parameter SETFUNCTION2=8'b00_000_010;//同上
parameter SWITCHMODE=8'b00_000_100;//设置显示开和光标闪烁关闭
parameter CLEAR=8'b00_001_000;//清屏操作
parameter SETMODE=8'b00_010_000;//点设置
parameter SETDDRAM=8'b00_100_000;//起始行设置
parameter WRITERAM=8'b01_000_000;//写设置
parameter STOP=8'b10_000_000;//LCD操作停止,释放其控制
parameter POWERUP =8'b00_000_011;//初始状态
//设置好RS、RW、E
always@(posedge LCD_Clk or negedge Rst)
begin
if(!Rst)
LCD_RS<=1'b0;
else if(state==WRITERAM)
LCD_RS<=1'b1;
else
LCD_RS<=1'b0;
end
//descible the state machine
always@(posedge LCD_Clk or negedge Rst)
begin
if(!Rst) begin
state<=POWERUP;
lcd_data_out<=8'bzz_zzz_zzz;
x <= 3'b1;
y <= 4'b0;
flag<=1'b1;
end
else begin
case(state)
POWERUP: begin
state<=SETFUNCTION;
lcd_data_out<=8'h30;
flag<=1'b1;
end
IDLE: begin
flag<=1'b1;
if(down_delay == 1'b1) begin
if(x == 3'd4)
x <= 3'b1;
else
x <= x +3'b1;
state <= SETDDRAM;
end
else if(right_delay == 1'b1) begin
state <= SETDDRAM;
y <= y +4'b1;
if((x == 3'd4) &&(y == 4'd15))
x <= 3'd1;
else if(y == 4'd15)
x <= x +3'b1;
else
x <= x;
end
else if(data_in_delay == 1'b1) begin
state <= WRITERAM;
y <= y +4'b1;
if((x == 3'd4) &&(y == 4'd15))
x <= 3'd1;
else if(y == 4'd15)
x <= x +3'b1;
else
x <= x;
end
else if(clear_delay == 1'b1) begin
state<=SETFUNCTION;
lcd_data_out<=8'h30;
flag<=1'b1;
x <= 1;
y <= 0;
end
else begin
x <= x;
y <= y;
end
end
SETFUNCTION: begin
state<=SWITCHMODE;
state<=SETFUNCTION2;
lcd_data_out<=8'h30;
end
SETFUNCTION2:begin
state<=SWITCHMODE;
lcd_data_out<=8'h30;
end
SWITCHMODE:begin
state<=CLEAR;
lcd_data_out<=8'h0f;//显示设置,全显示开,光标和闪烁关
end
CLEAR:begin
state<=SETMODE;
lcd_data_out<=8'h01;//清屏、
end
SETMODE: begin
state<=SETDDRAM;
lcd_data_out<=8'h06;//点设置,光标右移,地址加一,整体不动
end
SETDDRAM: begin //设置起始位置
state<=IDLE;
if(x==3'd1)
lcd_data_out<=8'h80 +y;//line1
else if(x==3'd2)
lcd_data_out<=8'h90 +y;//line2
else if(x==3'd3)
lcd_data_out<=8'h88 +y;//line3
else if(x==3'd4)
lcd_data_out<=8'h98 +y;//line4
else
lcd_data_out<=8'h80;
end
WRITERAM: begin
lcd_data_out <= data;
if(y==4'b0)
state <= SETMODE;
else
state <= IDLE;
end
STOP: state<=IDLE;
default: state<=IDLE;
endcase
end
end
always@(char_cnt)
begin
case(char_cnt)
6'd0:data_disp="G";
6'd1:data_disp="U";
6'd2:data_disp="X";
6'd3:data_disp="I";
6'd4:data_disp="A";
6'd5:data_disp="N";
6'd6:data_disp="Y";
6'd7:data_disp="I";
6'd8:data_disp="L";
6'd9:data_disp="C";
6'd10:data_disp="D";
6'd11:data_disp="!";