程序中用了one-hot编码,用的不是很成熟。1602模块程序接口不是很好,有待改进。
程序包括lcd1602和lcd1602_test两个模块,lcd1602模块为基本模块,lcd1602_test为测试模块。此液晶显示模块已在EP2C8Q208C8芯片50M晶振条件下测试成功。显示结果为:液晶第一行显示“0123456789ABCDEFGH”,第二行显示“abcdefghijklmnop”(显示内容详见lcd1602_test内调用lcd1602时传递的参数)。
下面为程序源码。
/******************************************************
//module name:lcd1602
//designer:kang
//date:2010-10-18
//version:1.00
******************************************************/
module lcd1602(
//input signals
clk,
rst,
addr,
d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16,
//output signals
lcd_e,
lcd_rs,
lcd_rw,
lcd_d
);
//input signals
input clk;
input rst;
input [1:0] addr;
input [7:0] d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16;
wire clk;
wire rst;
wire [1:0] addr;
wire [7:0] d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16;
//output signals
output lcd_e;
output lcd_rs;
output lcd_rw;
output [7:0] lcd_d;
reg lcd_e;
reg lcd_rs;
reg lcd_rw;
reg [7:0] lcd_d;
parameter DIVNUM=16'd40000;
parameter DELAY=15;
parameter IDLE=0;
parameter SETMOD=1; //0x38
parameter CLR=2; //0x01
parameter SETADDMODE=3; //0X06
parameter SETCURSOR=4; //0X0C
parameter W_ADD=5;
parameter W_DAT1=6;
parameter W_DAT2=7;
parameter W_DAT3=8;
parameter W_DAT4=9;
parameter W_DAT5=10;
parameter W_DAT6=11;
parameter W_DAT7=12;
parameter W_DAT8=13;
parameter W_DAT9=14;
parameter W_DAT10=15;
parameter W_DAT11=16;
parameter W_DAT12=17;
parameter W_DAT13=18;
parameter W_DAT14=19;
parameter W_DAT15=20;
parameter W_DAT16=21;
//internal signals
reg [15:0] counter;
reg clk_en;
reg [21:0] current_state;
reg [21:0] next_state;
reg [7:0] delaynum;
reg [7:0] dat1,dat2,dat3,dat4,dat5,dat6,dat7,dat8,dat9,dat10,dat11,dat12,dat13,dat14,dat15,dat16;
reg [1:0] add;
//counter
always @(posedge clk or negedge rst)
if(!rst) counter<=16'h0;
else if(counter==DIVNUM) counter<=16'h0;
else counter<=counter+1'b1;
//clk_en
always @(posedge clk or negedge rst)
if(!rst) clk_en<=0;
else if(counter==DIVNUM) clk_en<=1;
else clk_en<=0;
//lcd_e
always @(posedge clk or negedge rst)
if(!rst) lcd_e<=0;
else if(counter<=DIVNUM[15:1]) lcd_e<=1;
else lcd_e<=0;
//dat1-16
always @(posedge clk)
begin
if(current_state[SETCURSOR])
begin
add<=addr;
dat1<=d1;
dat2<=d2;
dat3<=d3;
dat4<=d4;
dat5<=d5;
dat6<=d6;
dat7<=d7;
dat8<=d8;
dat9<=d9;
dat10<=d10;
dat11<=d11;
dat12<=d12;
dat13<=d13;
dat14<=d14;
dat15<=d15;
dat16<=d16;
end
end
//current_state
always @(posedge clk or negedge rst)
if(!rst) current_state<=0;
else current_state<=next_state;
//next_state
always @(posedge clk or negedge rst)
if(!rst)
begin
next_state<=0;
delaynum<=0;
end
else if(clk_en)
begin
next_state<=0;
case(1'b1)
current_state[IDLE]:
begin
if(delaynum>=DELAY)
begin
next_state[SETMOD]<=1'b1;
delaynum<=0;
end
else
begin
next_state[IDLE]<=1'b1;
delaynum<=delaynum+1'b1;
end
end
current_state[SETMOD]:
begin
if(delaynum>=DELAY)
begin
next_state[CLR]<=1'b1;
delaynum<=0;
end
else
begin
next_state[SETMOD]<=1'b1;
delaynum<=delaynum+1'b1;
end
end
current_state[CLR]:next_state[SETADDMODE]<=1'b1;
current_state[SETADDMODE]:next_state[SETCURSOR]<=1'b1;
current_state[SETCURSOR]:next_state[W_ADD]<=1'b1;
current_state[W_ADD]:next_state[W_DAT1]<=1'b1;
current_state[W_DAT1]:next_state[W_DAT2]<=1'b1;
current_state[W_DAT2]:next_state[W_DAT3]<=1'b1;
current_state[W_DAT3]:next_state[W_DAT4]<=1'b1;
current_state[W_DAT4]:next_state[W_DAT5]<=1'b1;
current_state[W_DAT5]:next_state[W_DAT6]<=1'b1;
current_state[W_DAT6]:next_state[W_DAT7]<=1'b1;
current_state[W_DAT7]:next_state[W_DAT8]<=1'b1;
current_state[W_DAT8]:next_state[W_DAT9]<=1'b1;
current_state[W_DAT9]:next_state[W_DAT10]<=1'b1;
current_state[W_DAT10]:next_state[W_DAT11]<=1'b1;
current_state[W_DAT11]:next_state[W_DAT12]<=1'b1;
current_state[W_DAT12]:next_state[W_DAT13]<=1'b1;
current_state[W_DAT13]:next_state[W_DAT14]<=1'b1;
current_state[W_DAT14]:next_state[W_DAT15]<=1'b1;
current_state[W_DAT15]:next_state[W_DAT16]<=1'b1;
current_state[W_DAT16]:next_state[SETCURSOR]<=1'b1;
default:next_state[IDLE]<=1'b1;
endcase
end
//lcd_rs,lcd_rw,lcd_d
always @(posedge clk or negedge rst)
if(!rst)
begin
lcd_rs<=0;
lcd_rw<=0;
lcd_d<=0;
end
else if(clk_en)
begin
case(1'b1)
current_state[IDLE]:;
current_state[SETMOD]:
begin
lcd_rs<=0;
lcd_rw<=0;
lcd_d<=8'h38;
end
current_state[CLR]:
begin
lcd_rs<=0;
lcd_rw<=0;
lcd_d<=8'h01;
end
current_state[SETADDMODE]:
begin
lcd_rs<=0;
lcd_rw<=0;
lcd_d<=8'h06;
end
current_state[SETCURSOR]:
begin
lcd_rs<=0;
lcd_rw<=0;
lcd_d<=8'h0c;
end
current_state[W_ADD]:
begin
if(add==2'd1)
begin
lcd_rs<=0;
lcd_rw<=0;
lcd_d<=8'h80;
end
else if(add==2'd2)
begin
lcd_rs<=0;
lcd_rw<=0;
lcd_d<=8'hc0;
end
end
current_state[W_DAT1]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat1;
end
current_state[W_DAT2]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat2;
end
current_state[W_DAT3]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat3;
end
current_state[W_DAT4]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat4;
end
current_state[W_DAT5]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat5;
end
current_state[W_DAT6]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat6;
end
current_state[W_DAT7]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat7;
end
current_state[W_DAT8]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat8;
end
current_state[W_DAT9]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat9;
end
current_state[W_DAT10]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat10;
end
current_state[W_DAT11]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat11;
end
current_state[W_DAT12]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat12;
end
current_state[W_DAT13]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat13;
end
current_state[W_DAT14]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat14;
end
current_state[W_DAT15]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat15;
end
current_state[W_DAT16]:
begin
lcd_rs<=1'b1;
lcd_rw<=0;
lcd_d<=dat16;
end
default:;
endcase
end
endmodule
/******************************************************
//module name:lcd1602_test
//designer:kang
//date:2010-10-18
//version:1.00
******************************************************/
module lcd1602_test(
//input signals
clk,
rst,
//output signals
LCD_E,
LCD_RS,
LCD_RW,
LCD_D
);
//input signals
input clk;
input rst;
wire clk;
wire rst;
//output signals
output LCD_E;
output LCD_RS;
output LCD_RW;
output [7:0] LCD_D;
wire LCD_E;
wire LCD_RS;
wire LCD_RW;
wire [7:0] LCD_D;
//internal signals
reg [7:0] dat1,dat2,dat3,dat4,dat5,dat6,dat7,dat8,dat9,dat10,dat11,dat12,dat13,dat14,dat15,dat16;
reg [24:0] counter;
reg [1:0] add;
//counter
always @(posedge clk or negedge rst)
begin
if(!rst) counter<=0;
else if(counter==24'd800000) counter<=0;
else counter<=counter+1'b1;
end
//add and data
always @(posedge clk)
begin
if(counter<=400000)
begin
add<=2'd1;
dat1<=8'h30;
dat2<=8'h31;
dat3<=8'h32;
dat4<=8'h33;
dat5<=8'h36;
dat6<=8'h37;
dat7<=8'h38;
dat8<=8'h39;
dat9<=8'h41;
dat10<=8'h42;
dat11<=8'h43;
dat12<=8'h44;
dat13<=8'h45;
dat14<=8'h46;
dat15<=8'h47;
dat16<=8'h48;
end
else
begin
add<=2'd2;
dat1<=8'h61;
dat2<=8'h62;
dat3<=8'h63;
dat4<=8'h64;
dat5<=8'h65;
dat6<=8'h66;
dat7<=8'h67;
dat8<=8'h68;
dat9<=8'h69;
dat10<=8'h6a;
dat11<=8'h6b;
dat12<=8'h6c;
dat13<=8'h6d;
dat14<=8'h6e;
dat15<=8'h6f;
dat16<=8'h70;
end
end
lcd1602 lcd1602(
clk,
rst,
add,
dat1,dat2,dat3,dat4,dat5,dat6,dat7,dat8,dat9,dat10,dat11,dat12,dat13,dat14,dat15,dat16,
LCD_E,
LCD_RS,
LCD_RW,
LCD_D
);
endmodule
用户425426 2012-11-18 14:20
请问一下你的SDRAM调试成功了吗?想请教请教你
用户425426 2012-11-18 14:18
用户420241 2012-10-29 10:03
用户403866 2011-8-7 20:33
用户282447 2010-12-8 21:39
用户193497 2010-12-7 15:51