lcd1602代码
0赞
发表于 12/3/2012 5:01:17 PM
阅读(3511)
这是之前的lcd1602代码,自己觉得代码思路还是比较简洁清晰的,贴这里吧,初学verilog的可以看一下。下面的显示的都是内 部给出的数据,可以加进输入输入端显示外部输入数据,也方便代码的移植。自己写的时候没写注释,刚刚把注释全部加上去,结果 这里的文字跟代码全混到一起去了,这个编辑器还不熟练,几经修改,全都乱了。现在直接复制过来。。
module lcd1602(
input clk,
input rst_n,
// input [7:0] data_row1,
// input [7:0] data_row2,
output reg [7:0] lcd_data,
output lcd_e,
output reg lcd_rs,
output lcd_rw
);
reg [23:0] cnt;
reg [3:0] cstate;
reg [3:0] nstate;
reg start_flag;
reg [5:0] addr=6'b000000;
reg [255:0] data_in_buf;
parameter IDLE= 4'b0000,
SETF= 4'b0001, //6
CLER= 4'b0010, //1
SETM= 4'b0011, //3
SHIF= 4'b0100, //5
DISP= 4'b0101, //4
SETD1= 4'b0110,
SETD2= 4'b0111,
WRTM= 4'b1000;
parameter DATA_IN="ABCDEFG HIJKLMN OPQ RST UVW XYZ " ;
always @ (posedge clk, negedge rst_n)
if (!rst_n)
cnt <= 0;
else
cnt <= cnt + 1'b1;
wire lcd_clk = cnt[23];
always@(posedge lcd_clk,negedge rst_n)
if(~rst_n)
cstate<=IDLE;
else
cstate<=nstate;
always@(*)
case(cstate)
IDLE: if(~start_flag)
nstate= SETF;
else nstate= SHIF;
SETF: nstate= DISP;
CLER: nstate= SETM;
SETM: nstate= SETD1;
SHIF: nstate= IDLE;
DISP: nstate= CLER;
SETD1: nstate= WRTM;
WRTM: if(addr==15)
nstate= SETD2;
else if(addr==31)
nstate= SHIF;
else nstate= WRTM;
SETD2: nstate= WRTM;
default:nstate<=IDLE;
endcase
always@(posedge lcd_clk or negedge rst_n)
if(~rst_n)
begin
lcd_rs<=0;
lcd_data<=8'hzz;
start_flag<=0;
data_in_buf<=DATA_IN;
end
else case(nstate)
IDLE:
if(~start_flag)
begin
lcd_rs<=0;
start_flag<=1;
end
else ;
SETF: begin lcd_rs<=0;lcd_data<=8'h38;end
CLER: begin lcd_rs<=0;lcd_data<=8'h01;end
SETM: begin lcd_rs<=0;lcd_data<=8'h06;end
SHIF: begin lcd_rs<=0;lcd_data<=8'h14;end
DISP: begin lcd_rs<=0;lcd_data<=8'h0E;end
SETD1: begin lcd_rs<=0;lcd_data<=8'h80;end
WRTM: begin
lcd_rs<=1;
lcd_data<=data_in_buf[255:248];
data_in_buf<=data_in_buf<<8;
if(addr==31)
begin
lcd_rs<=0;
addr<=0;
end
else
addr<=addr+1;
end
SETD2: begin lcd_rs<=0;lcd_data<=8'hC0;end
default :;
endcase
assign lcd_e=lcd_clk;
assign lcd_rw=0;
