2012年11月21日 星期三

LAB04 LCD1602 Display

LAB04 LCD1602 Display 適用於DE2-70

源自於
http://www.cnblogs.com/halflife/archive/2011/07/02/2096463.html






























源自於 http://www.haogongju.net/art/19738


//LCD1602 
/*
LCD_RW PIN_K4
LCD_EN PIN_K3
LCD_RS PIN_K1
LCD_DATA[0] PIN_J1
LCD_DATA[1] PIN_J2
LCD_DATA[2] PIN_H1
LCD_DATA[3] PIN_H2
LCD_DATA[4] PIN_J4
LCD_DATA[5] PIN_J3
LCD_DATA[6] PIN_H4
LCD_DATA[7] PIN_H3
LCD_ON PIN_L4
LCD_BLON PIN_K2
*/


module LCM(
input  CLOCK_50,
input  [3:0]KEY,
inout  [7:0] LCD_DATA,
output LCD_EN,
output LCD_RS,
output LCD_RW,
output LCD_ON,
output LCD_BLON
);

//initial//

wire RTSN;
wire[7:0] LCD_D_1;
wire LCD_RS_1;
wire LCD_RW_1;
wire LCD_EN_1;
wire DLY_RST;

assign LCD_DATA=LCD_D_1;
assign LCD_RS=LCD_RS_1;
assign LCD_RW=LCD_RW_1;
assign LCD_EN=LCD_EN_1;
assign LCD_ON=1'b1;
assign LCD_BLON=1'b0;

Reset_Delay r0(.iCLK(CLOCK_50), .oRESET(DLY_RST));


LCD1602_TEST u1(    
//Host Side
.iCLK(CLOCK_50),
.iRST_N(DLY_RST),

//LCD Side
.LCD_DATA(LCD_D_1),
.LCD_RW(LCD_RW_1),
.LCD_EN(LCD_EN_1),
.LCD_RS(LCD_RS_1)
);

endmodule





//Reset_Delay

module Reset_Delay(iCLK,oRESET);
input iCLK;
output reg oRESET;
reg[19:0] Cont;


always@(posedge iCLK)
begin
if(Cont!=20'hfffff)
begin
Cont<=Cont+1'b1;
oRESET<=1'b0;
end
else
oRESET<=1'b1;
end

endmodule




//LCD1602_TEST

module LCD1602_TEST(
input iCLK,iRST_N,  //Host Side
output[7:0] LCD_DATA,   //LCD1602 Side
output LCD_RS,LCD_RW,LCD_EN
);

//Internal Wires/Registers
reg[5:0] LUT_INDEX;
reg[8:0] LUT_DATA;
reg[5:0] mLCD_ST;
reg[17:0] mDLY;
reg[7:0] mLCD_DATA;
reg mLCD_Start;
reg mLCD_RS;
wire mLCD_Done;

parameter LCD_INITIAL   =   0;
parameter LCD_LINE1     =   5;  //Just have 5 control command
parameter LCD_CH_LINE   =   LCD_LINE1+16;   //Change Line
parameter LCD_LINE2     =   LCD_LINE1+16+1;
parameter LUT_SIZE      =   LCD_LINE1+32+1;

always@(posedge iCLK or negedge iRST_N)
begin
if(!iRST_N)
begin
LUT_INDEX   <=   0;
mLCD_ST     <=   0;
mDLY        <=   0;
mLCD_Start  <=   0;
mLCD_DATA   <=   0;
mLCD_RS     <=   0;
end
else
begin
if(LUT_INDEX<LUT_SIZE)
begin
case(mLCD_ST)
0:  begin
mLCD_DATA   <=   LUT_DATA[7:0];
mLCD_RS     <=   LUT_DATA[8];
mLCD_Start  <=   1;
mLCD_ST     <=   1;
end

1:  begin
if(mLCD_Done)
begin
mLCD_Start  <=   0;
mLCD_ST     <=   2;
end
end

2:  begin
if(mDLY<18'h3ffff)
mDLY    <=   mDLY+18'b1;
else
begin
mDLY    <=   0;
mLCD_ST <=   3;
end
end

3:  begin
LUT_INDEX   <=   LUT_INDEX+6'b1;
mLCD_ST     <=   0;
end
endcase

end
end
end

always
begin
case(LUT_INDEX)

//  Inital
LCD_INITIAL+0:  LUT_DATA    <=   9'h038; //?置16x2?示,5x7??,8位?据接口
LCD_INITIAL+1:  LUT_DATA    <=   9'h00C; //?置??示,不?示光?
LCD_INITIAL+2:  LUT_DATA    <=   9'h001; //?示清零,?据指?清零
LCD_INITIAL+3:  LUT_DATA    <=   9'h006; //?一?字符后地址指?加一
LCD_INITIAL+4:  LUT_DATA    <=   9'h080; //Line1 First Address

//  Line1

LCD_LINE1+0:    LUT_DATA    <=   9'h120; //  Welcome to
LCD_LINE1+1:    LUT_DATA    <=   9'h120; //
LCD_LINE1+2:    LUT_DATA    <=   9'h120; //
LCD_LINE1+3:    LUT_DATA    <=   9'h157; //w
LCD_LINE1+4:    LUT_DATA    <=   9'h165; //e
LCD_LINE1+5:    LUT_DATA    <=   9'h16C; //l
LCD_LINE1+6:    LUT_DATA    <=   9'h163; //c
LCD_LINE1+7:    LUT_DATA    <=   9'h16F; //o
LCD_LINE1+8:    LUT_DATA    <=   9'h16D; //m
LCD_LINE1+9:    LUT_DATA    <=   9'h165; //e
LCD_LINE1+10:   LUT_DATA    <=   9'h120; //
LCD_LINE1+11:   LUT_DATA    <=   9'h174; //t
LCD_LINE1+12:   LUT_DATA    <=   9'h16F; //o
LCD_LINE1+13:   LUT_DATA    <=   9'h120; //
LCD_LINE1+14:   LUT_DATA    <=   9'h120; //
LCD_LINE1+15:   LUT_DATA    <=   9'h120; //
//  Change Line
LCD_CH_LINE:    LUT_DATA    <=   9'h0C0;
//  Line 2
LCD_LINE2+0:    LUT_DATA    <=   9'h120; //  www.nctu.edu.tw
LCD_LINE2+1:    LUT_DATA    <=   9'h157; //w
LCD_LINE2+2:    LUT_DATA    <=   9'h157; //w
LCD_LINE2+3:    LUT_DATA    <=   9'h157; //w
LCD_LINE2+4:    LUT_DATA    <=   9'h12E; //.
LCD_LINE2+5:    LUT_DATA    <=   9'h16E; //n
LCD_LINE2+6:    LUT_DATA    <=   9'h163; //c
LCD_LINE2+7:    LUT_DATA    <=   9'h174; //t
LCD_LINE2+8:    LUT_DATA    <=   9'h175; //u
LCD_LINE2+9:    LUT_DATA    <=   9'h12E; //.
LCD_LINE2+10:   LUT_DATA    <=   9'h165; //e
LCD_LINE2+11:   LUT_DATA    <=   9'h164; //d
LCD_LINE2+12:   LUT_DATA    <=   9'h175; //u
LCD_LINE2+13:   LUT_DATA    <=   9'h12E; //.
LCD_LINE2+14:   LUT_DATA    <=   9'h174; //t
LCD_LINE2+15:   LUT_DATA    <=   9'h177; //w
default:        LUT_DATA    <=   9'h120;

endcase
end

LCD1602_Controller  u0  (   //Host Side
.iDATA(mLCD_DATA),
.iRS(mLCD_RS),
.iStart(mLCD_Start),
.oDone(mLCD_Done),
.iCLK(iCLK),
.iRST_N(iRST_N),
//LCD1602 Interface
.LCD_DATA(LCD_DATA),
.LCD_RW(LCD_RW),
.LCD_EN(LCD_EN),
.LCD_RS(LCD_RS)
);

endmodule





//LCD1602_Controller
module LCD1602_Controller(
//Host Side
input iCLK,iRST_N,
input iRS,iStart,
input[7:0] iDATA,
output reg oDone,
//LCD1602 Interface
output[7:0] LCD_DATA,
output LCD_RS,
output LCD_RW,
output reg LCD_EN
);

//Internal Register
reg[4:0] Cont;
reg[1:0] ST;
reg preStart,mStart;

//Only write to LCD,bypass iRS to LCD_RS
assign LCD_DATA =   iDATA;
assign LCD_RS   =   iRS;
assign LCD_RW   =   1'b0;
parameter CLK_Divide    =   16;

always@(posedge iCLK or negedge iRST_N)
begin
if(!iRST_N)
begin
oDone   <=   1'b0;
LCD_EN  <=   1'b0;
preStart<=   1'b0;
mStart  <=   1'b0;
Cont    <=   0;
ST      <=   0;
end
else
begin
//Input Start Detect
preStart    <=   iStart;
if({preStart,iStart}==2'b01)
begin
mStart  <=   1'b1;
oDone   <=   1'b0;
end
if(mStart)
begin
case(ST)
0:  ST  <=   1;  //Wait Setup
1:  begin
LCD_EN  <=   1'b1;
ST      <=   2;
end
2:  begin
if(Cont<CLK_Divide)
Cont    <=   Cont+5'b1;
else
ST      <=   3;
end

3:  begin
LCD_EN  <=   1'b0;
mStart  <=   1'b0;
oDone   <=   1'b1;
Cont    <=   0;
ST      <=   0;
end

endcase

end
end
end

endmodule







沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...