📄 1602显示.v
字号:
//那位帮我看看这个程序:1602 LCD显示,编译无错,总是什么都不能显示 xiexie ge wei le :
module lcd1602(clk,rst,lcd_rs,clklcd,lcd_rw,data,en);
input clk,rst;
output lcd_rs,lcd_rw,clklcd,en;
output[7:0] data;
reg lcd_rs,lcd_rw,en;
reg[5:0] address;
wire clk_16;
reg[3:0] count;
reg[15:0] clkcnt;
reg tc_clkcnt;
reg clklcd;
reg clkint;
reg [10:0] state;
reg[6:0] counter;
reg[7:0] data,datas;
reg flag;
reg[3:0] counter1;
parameter
IDLE1=11'b00000000000,
CLEAR=11'b00000000001,
RETURNCURSOR=11'b00000000010,
SETMODE=11'b00000000100,
SWITCHMODE=11'b00000001000,
SHIFT=11'b00000010000,
SETFUNCTION=11'b00000100000,
SETCGRAM=11'b00001000000,
SETDDRAM=11'b00010000000,
READFLAG=11'b00100000000,
WRITERAM=11'b01000000000,
READRAM =11'b10000000000;
always @(posedge clk or negedge rst)
begin
if (!rst)
count <= 'b0;
else
count <= count +1;
end
assign clk_16 = count[3];
always @(posedge clk_16 or negedge rst)
begin
if(!rst)
begin
clkcnt<=16'b0000000000000000;
tc_clkcnt<=0;
end
else
if(clkcnt==16'b1001110001000000)
begin
clkcnt<=16'b0000000000000000;
tc_clkcnt<=~tc_clkcnt;
end
else
clkcnt<=clkcnt+1;
end
always @(posedge tc_clkcnt or negedge rst)
begin
if(!rst)
clkint<=0;
else
clkint<=~clkint;
end
always @(negedge tc_clkcnt or negedge rst)
begin
if(!rst)
clklcd<=0;
else
clklcd<=~clklcd;
end ///前面分频产生所需的时钟信号
always @(posedge clkint or negedge rst)
begin
if(!rst)
begin
state<=IDLE1;
counter<=0;
counter1<=0;
flag<=0;
end
else
begin
case (state)
IDLE1 :
begin
if(flag==0) //判断显示是否结束,第一次就开始显示,否则调到shift执行移位命令
begin
state<=SETFUNCTION;
counter<=0;
flag<=1;
counter1<=0;
end
else if(counter1<4'b1111)
begin
counter1<=counter1+1;
state<=IDLE1;
end
else
begin
state<=SHIFT;
counter1<=0;
end
end
CLEAR : state<=SETMODE; //状态转移
SETMODE : state<=WRITERAM;
RETURNCURSOR : state<=WRITERAM;
SWITCHMODE : state<=CLEAR;
SHIFT : state<=IDLE1;
SETFUNCTION : state<=SWITCHMODE;
SETCGRAM : state<=IDLE1;
SETDDRAM : state<=WRITERAM;
READFLAG : state<=IDLE1;
WRITERAM :
begin
if(counter<=11 )//第一行显示11个字符
begin
state<=WRITERAM;
counter<=counter+1;
end
else if(counter<=25)
begin
if(counter==12)//设置第2行地址
begin
state<=SETDDRAM;
counter<=counter+1;
end
else
begin
counter<=counter+1;
state<=WRITERAM;
end
end
else
state<=SHIFT;
end
READRAM : state<=IDLE1;
default : state<=IDLE1;
endcase
end
end
always@(address) //选出需要显示的字符
begin
case (address)
6'b000000: datas<=8'd72;//显示H
6'b000001: datas<=8'd79;
6'b000010: datas<=8'd87;
6'b000011: datas<=8'd32;
6'b000100: datas<=8'd65;
6'b000101: datas<=8'd82;
6'b000110: datas<=8'd69;
6'b000111: datas<=8'd32;
6'b001000: datas<=8'd89;
6'b001001: datas<=8'd79;
6'b001010: datas<=8'd85;
6'b001011: datas<=8'd32;
6'b001100: datas<=8'd32;
6'b001101: datas<=8'd70;
6'b001110: datas<=8'd73;
6'b001111: datas<=8'd78;
6'b010000: datas<=8'd69;
6'b010001: datas<=8'd32;
6'b010010: datas<=8'd84;
6'b010011: datas<=8'd72;
6'b010100: datas<=8'd65;
6'b010101: datas<=8'd78;
6'b010110: datas<=8'd75;
6'b010111: datas<=8'd83;
default : datas<=8'd32;
endcase
end
always
begin
lcd_rs<=((state ==WRITERAM) | (state == READRAM))? 1: 0;
lcd_rw<=((state ==READFLAG) | (state == READRAM)| (state == IDLE1))? 1: 0;
en<=1;
if(state==WRITERAM)
address<=counter;
else
address<=0;
case(state)
CLEAR: data <=8'b00000001;
RETURNCURSOR:data <=8'b00000010;
SETMODE:data <=8'b00000110;
SWITCHMODE:data <=8'b00001111;
SHIFT :data <=8'b00011000;
SETFUNCTION:data <=8'b00111100;
SETCGRAM:data <=8'b01000000;
SETDDRAM :
begin
if(counter==0)//判断显示字符的地址,开始默认的是00,如果需要在第2行显示,就在data输出11000000,由于显示一个字符后自动加1,所以它会在第2行继续显示。
data <=8'b10000000;
else data<=8'b11000000;
end
WRITERAM:
data <=datas;
default data <=8'bZZZZZZZZ;//输出要z状态,否则可能出错
endcase
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -