资源描述
module charlcd1(clk,reset,lcd_rs,lcd_rw,lcd_e,data,clk_out);
input clk,reset;
output reg lcd_rs,lcd_rw;
output wire clk_out;
output reg lcd_e;
output reg [7:0] data;
parameter [10:0] idle =11'b00000000000;
parameter [10:0] clear =11'b00000000001;
parameter [10:0] returncursor=11'b00000000010;
parameter [10:0] setmode =11'b00000000100;
parameter [10:0] switchmode =11'b00000001000;
parameter [10:0] shift =11'b00000010000;
parameter [10:0] setfunction =11'b00000100000;
parameter [10:0] setcgram =11'b00001000000;
parameter [10:0] setddram =11'b00010000000;
parameter [10:0] readflag =11'b00100000000;
parameter [10:0] writeram =11'b01000000000;
parameter [10:0] readram =11'b10000000000;
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;
reg [10:0] state;
reg [6:0] counter;
reg [3:0] div_counter;
reg flag;
parameter divss=15;
reg [5:0] char_addr;
//reg [7:0] data_in;
wire [7:0] data_in;
//时钟信号clkdiv的相关变量定
reg clk_int;
reg [18:0] clkcnt;
parameter divcnt=19'b1111001110001000000;
reg clkdiv;
reg tc_clkcnt;
//产生时钟信号clkdiv
always@(posedge clk or negedge reset)
begin
if(reset==0)
begin
clkcnt<=0;tc_clkcnt<=0; //重置
end
else if(clkcnt==divcnt)
begin
clkcnt<=0;tc_clkcnt<=1; //每计数到x"79c40",to_clkcnt赋予高电平
end
else begin
clkcnt<=clkcnt+1;tc_clkcnt<=0;
end
end
//clkdiv是以2倍的x"79c40"为周期的时钟信号
always@(posedge tc_clkcnt or negedge reset)
begin
if(reset==0)
clkdiv<=0;
else clkdiv<=~clkdiv;
end
//产生周期为clkdiv的2倍的时钟信号clk_int,并赋给clk_out
assign clk_out=clk_int;
always@(posedge clkdiv or negedge reset)
begin
if(reset==0)
clk_int<=0;
else clk_int<=~clk_int;
end
//产生周期为clkdiv的2倍的时钟信号lcd_e,与clk_int相错90°
always@(negedge clkdiv or negedge reset)
begin
if(reset==0)
lcd_e<=0;
else lcd_e<=~lcd_e;
end
/*****************调用char_ram元件************************/
char_ram aa(clk,char_addr,data_in);
/*********************************************************/
always@(posedge clk)
begin
if(state==writeram)
lcd_rs<=1;
else if(state==readram)
lcd_rs<=1;
else lcd_rs<=0;
end
always@(posedge clk)
begin
if(state==idle)
lcd_rw<=1;
else if(state==readram)
lcd_rw<=1;
else lcd_rw<=0;
end
always@(posedge clk)
begin
case(state) //各状态下,给data赋值,完成拼接工作
clear: data<=8'b00000001;
returncursor: data<=8'b00000010;
setmode: data<=8'b00000110;//{6'b000001,cur_inc,cur_noshift};也可以用双斜线后面的写法,我当时为了自己方便看就直接写了出来
switchmode: data<=8'b00001100;//{5'b00001,open_display,open_cur,blank_cur};
shift: data<=8'b00011000;//{4'b0001,shift_display,left_shift,2'b00};
setfunction: data<=8'b00111100;//{3'b001,datawidth8,twoline,font5x10,2'b00};
setcgram: data<=8'b01000000;
setddram:begin
if(counter==0) data<=8'b10000000;
else data<=8'b11000000;
end
writeram: data<=data_in;
default: data<=8'bzzzzzzzz;
endcase
end
always@(posedge clk)
begin
if(state==writeram)
if(counter<40)
char_addr<=counter;
else if(counter>40 && counter<73)
char_addr<=counter-33;
else if(counter>73 && counter<81)
char_addr<=counter-73;
else char_addr<=0;
end
/*********************************************************/
always@(posedge clk_int or negedge reset)
begin
if(reset==0)
begin
state<=idle;
counter<=0;
flag<=0;
div_counter<=0;
end
else
case(state)
idle:begin
if(flag==0)
begin
state<=setfunction;
flag<=1;
counter<=0;
div_counter<=0;
end
else if(div_counter<divss)
begin
div_counter<=div_counter+1;
state<=idle;
end
else
begin
div_counter<=0;
state<=shift;
end
end
clear: state<=setmode;
setmode: state<=writeram;
// returncursor: state<=writeram;
switchmode: state<=clear;
shift: state<=idle;
setfunction: state<=switchmode;
// setcgram: state<=idle;
setddram: state<=writeram;
// readflag: state<=idle;
writeram:begin
if(counter<40)
begin
state<=writeram;
counter<=counter+1;
end
else if(counter==40)
begin
state<=setddram;
counter<=counter+1;
end
else if(counter<81)
begin
state<=writeram;
counter<=counter+1;
end
else state<=shift;
end
// readram: state<=idle;
// default: state<=idle;
endcase
end
endmodule
(2)
module char_ram(clk,address,data);
input clk;
input [5:0] address;
output reg [7:0] data;
/*这里注释掉的因为我一直没用对,还在学习中,有人知道的吗?请多多指教^^
function [7:0] char_to_integer;
input indata;
begin
case(indata)
" ":char_to_integer=32;
"!":char_to_integer=33;
"\"":char_to_integer=34;
"#":char_to_integer=35;
"$":char_to_integer=36;
"%":char_to_integer=37;
"&":char_to_integer=38;
"\'":char_to_integer=39;
"(":char_to_integer=40;
")":char_to_integer=41;
"*":char_to_integer=42;
"+":char_to_integer=43;
",":char_to_integer=44;
"-":char_to_integer=45;
".":char_to_integer=46;
"/":char_to_integer=47;
"0":char_to_integer=48;
"1":char_to_integer=49;
"2":char_to_integer=50;
"3":char_to_integer=51;
"4":char_to_integer=52;
"5":char_to_integer=53;
"6":char_to_integer=54;
"7":char_to_integer=55;
"8":char_to_integer=56;
"9":char_to_integer=57;
":":char_to_integer=58;
";":char_to_integer=59;
"<":char_to_integer=60;
"=":char_to_integer=61;
">":char_to_integer=62;
"?":char_to_integer=63;
"@":char_to_integer=64;
"A":char_to_integer=65;
"B":char_to_integer=66;
"C":char_to_integer=67;
"D":char_to_integer=68;
"E":char_to_integer=69;
"F":char_to_integer=70;
"G":char_to_integer=71;
"H":char_to_integer=72;
"I":char_to_integer=73;
"J":char_to_integer=74;
"K":char_to_integer=75;
"L":char_to_integer=76;
"M":char_to_integer=77;
"N":char_to_integer=78;
"O":char_to_integer=79;
"P":char_to_integer=80;
"Q":char_to_integer=81;
"R":char_to_integer=82;
"S":char_to_integer=83;
"T":char_to_integer=84;
"U":char_to_integer=85;
"V":char_to_integer=86;
"W":char_to_integer=87;
"X":char_to_integer=88;
"Y":char_to_integer=89;
"Z":char_to_integer=90;
"[":char_to_integer=91;
//"\\":char_to_integer=92;
"]":char_to_integer=93;
"^":char_to_integer=94;
"_":char_to_integer=95;
"`":char_to_integer=96;
"a":char_to_integer=97;
"b":char_to_integer=98;
"c":char_to_integer=99;
"d":char_to_integer=100;
"e":char_to_integer=101;
"f":char_to_integer=102;
"g":char_to_integer=103;
"h":char_to_integer=104;
"i":char_to_integer=105;
"j":char_to_integer=106;
"k":char_to_integer=107;
"l":char_to_integer=108;
"m":char_to_integer=109;
"n":char_to_integer=110;
"o":char_to_integer=111;
"p":char_to_integer=112;
"q":char_to_integer=113;
"r":char_to_integer=114;
"s":char_to_integer=115;
"t":char_to_integer=116;
"u":char_to_integer=117;
"v":char_to_integer=118;
"w":char_to_integer=119;
"x":char_to_integer=120;
"y":char_to_integer=121;
"z":char_to_integer=122;
"{":char_to_integer=123;
"|":char_to_integer=124;
"}":char_to_integer=125;
"~":char_to_integer=126;
default:char_to_integer=32;
endcase
end
endfunction
*/
//输入显示的字符“Welecome BAIXUN Board! ”
always@(posedge clk)
begin
case(address)
6'b000000:data<=87;//char_to_integer("W");
6'b000001:data<=101;//char_to_integer("e");
6'b000010:data<=108;//char_to_integer("l");
6'b000011:data<=101;//char_to_integer("e");
6'b000100:data<=99;//char_to_integer("c");
6'b000101:data<=111;//char_to_integer("o");
6'b000110:data<=109;//char_to_integer("m");
6'b000111:data<=101;//char_to_integer("e");
6'b001000:data<=32;//char_to_integer(" ");
6'b001001:data<=32;//char_to_integer(" ");
6'b001010:data<=66;//char_to_integer("B");
6'b001011:data<=65;//char_to_integer("A");
6'b001100:data<=73;//char_to_integer("I");
6'b001101:data<=88;//char_to_integer("X");
6'b001110:data<=85;//char_to_integer("U");
6'b001111:data<=78;//char_to_integer("N");
6'b010000:data<=32;//char_to_integer(" ");
6'b010001:data<=32;//char_to_integer(" ");
6'b010010:data<=66;//char_to_integer("B");
6'b010011:data<=111;//char_to_integer("o");
6'b010100:data<=97;//char_to_integer("a");
6'b010101:data<=114;//char_to_integer("r");
6'b010110:data<=100;//char_to_integer("d");
6'b010111:data<=33;//char_to_integer("!");
default:data<=32;//char_to_integer(" ");
endcase
end
endmodule
展开阅读全文