您的位置:首页 > 其它

verilog简单驱动LCD1602

2017-10-04 14:54 239 查看
module lcd1602(                //50Mhz
clk,rst_n,            //input
lcd_on,lcd_blon,      //output
lcd_en,lcd_rw,lcd_rs,
lcd_data
);

input clk,rst_n;
output lcd_on,lcd_rw,lcd_blon;
output reg lcd_rs;
output wire lcd_en;
output reg [7:0] lcd_data;
//-------------------------------------
assign lcd_on=1'b1;
assign lcd_blon=1'b1;
assign lcd_rw=1'b0;     //设置高延迟 就不check busy 无需读取状态
//--------------input clk 50000,000----------------------
//---------------2^16==65536>50000 1ms-------------------
//------------------------分频成1ms---------------------
reg [15:0] cnt;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) cnt<=16'b0;
else if(cnt==50_000) cnt<=16'b0;
else cnt=cnt+1'b1;
end

reg [3:0] ms;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) ms<=1'b0;
else if(cnt==50_000) ms<=ms+1'b1;
end

//--------------------------------------------------------
//初始化以及显示字符  只初始化一次 一直显示一个字符
parameter lcd1=3'b000;
parameter lcd2=3'b001;
parameter lcd3=3'b011;
parameter lcd4=3'b010;
parameter lcd5=3'b110;
parameter lcd6=3'b111;
parameter lcd7=3'b101;
parameter lcd8=3'b100;

//状态转移
reg [2:0] current_state,next_state;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) current_state<=0;
//一开始设置的条件是  ms==15 但是时钟是clk 所以状态会一直转移 无法正确驱动lcd
// add cnt==16'h0000   确保状态只转移一次
else if(ms==15 && cnt==16'h0000)
current_state<=next_state;
end

//判断下一个状态 初始化完了之后一直循环1个状态
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) next_state<=lcd1;
else
case(current_state)
lcd1:next_state<=lcd2;
lcd2:next_state<=lcd3;
lcd3:next_state<=lcd4;
lcd4:next_state<=lcd5;
lcd5:next_state<=lcd6;
lcd6:next_state<=lcd7;
lcd7:next_state<=lcd8;
lcd8:next_state<=lcd8;
endcase
end

//根据状态输出相应数据
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
lcd_rs=0;
end
else
case(current_state)
lcd1:begin lcd_rs=0; lcd_data=8'h38; end
lcd2:begin lcd_rs=0; lcd_data=8'h08; end
lcd3:begin lcd_rs=0; lcd_data=8'h01; end
lcd4:begin lcd_rs=0; lcd_data=8'h06; end
lcd5:begin lcd_rs=0; lcd_data=8'h0c; end
lcd6:begin lcd_rs=1; lcd_data="h"; end       //cs
lcd7:begin lcd_rs=1; lcd_data="a"; end       //show
lcd8:begin lcd_rs=1; lcd_data="h"; end       //cs
endcase
end

//----------------lcd_en使能1ms---------------------
assign lcd_en=current_state==lcd8?1'b0:ms==15?1'b1:1'b0;
//assign lcd_en=current_state==lcd8?1'b0:ms==15?(cnt[15]==1?1'b1:1'b0):1'b0;  //以上会多输出一个a
endmodule
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: