LCD1602控制器Verilog

LCD1602的控制器模块和主模块

 LCD1602的时序和控制寄存器命令见http://www.cnblogs.com/qiweiwang/archive/2010/12/16/1908608.html

 

LCD1602的控制模块:

  
    
1 module LCD_Controller ( // Host Side
2   iDATA,iRS,
3 iStart,oDone,
4 iCLK,iRST_N,
5 // LCD Interface
6   LCD_DATA,
7 LCD_RW,
8 LCD_EN,
9 LCD_RS );
10   // CLK
11 parameter CLK_Divide = 16 ;
12
13 // Host Side
14 input [ 7 : 0 ] iDATA;
15 input iRS,iStart;
16 input iCLK,iRST_N;
17 output reg oDone;
18 // LCD Interface
19 output [ 7 : 0 ] LCD_DATA;
20 output reg LCD_EN;
21 output LCD_RW;
22 output LCD_RS;
23 // Internal Register
24 reg [ 4 : 0 ] Cont;
25 reg [ 1 : 0 ] ST;
26 reg preStart,mStart;
27
28 /////////////////////////////////////////////
29 // Only write to LCD, bypass iRS to LCD_RS
30 assign LCD_DATA = iDATA;
31 assign LCD_RW = 1 ' b0;
32 assign LCD_RS = iRS;
33 /////////////////////////////////////////////
34
35 always @( posedge iCLK or negedge iRST_N)
36 begin
37 if ( ! iRST_N)
38 begin
39 oDone <= 1 ' b0;
40 LCD_EN <= 1 ' b0;
41 preStart <= 1 ' b0;
42 mStart <= 1 ' b0;
43 Cont <= 0 ;
44 ST <= 0 ;
45 end
46 else
47 begin
48 ////// Input Start Detect ////// /
49 preStart <= iStart;
50 if ({preStart,iStart} == 2 ' b01)
51 begin
52 mStart <= 1 ' b1;
53 oDone <= 1 ' b0;
54 end
55 ///////////////////////////////// /
56 if (mStart)
57 begin
58 case (ST)
59 0 : ST <= 1 ; // Wait Setup
60 1 : begin
61 LCD_EN <= 1 ' b1;
62 ST <= 2 ;
63 end
64 2 : begin
65 if (Cont < CLK_Divide)
66 Cont <= Cont + 1 ' b1;
67 else
68 ST <= 3 ;
69 end
70 3 : begin
71 LCD_EN <= 1 ' b0;
72 mStart <= 1 ' b0;
73 oDone <= 1 ' b1;
74 Cont <= 0 ;
75 ST <= 0 ;
76 end
77 endcase
78 end
79 end
80 end
81
82 endmodule

主模块

 

  
    
// 9'h120 @ 9'h140 ` 9'h160
// ! 9'h121 A 9'h141 a 9'h161
// " 9'h122 B 9'h142 b 9'h162
// # 9'h123 C 9'h143 c 9'h163
// $ 9'h124 D 9'h144 d 9'h164
// % 9'h125 E 9'h145 e 9'h165
// & 9'h126 F 9'h146 f 9'h166
// ' 9'h127 G 9'h147 g 9'h167
// ( 9'h128 H 9'h148 h 9'h168
// ) 9'h129 I 9'h149 i 9'h169
// * 9'h12A J 9'h14A j 9'h16A
// + 9'h12B K 9'h14B k 9'h16B
// , 9'h12C L 9'h14C l 9'h16C
// - 9'h12D M 9'h14D m 9'h16D
// . 9'h12E N 9'h14E n 9'h16E
// / 9'h12F O 9'h14F o 9'h16F

// 0 9'h130 P 9'h150 p 9'h170
// 1 9'h131 Q 9'h151 q 9'h171
// 2 9'h132 R 9'h152 r 9'h172
// 3 9'h133 S 9'h153 s 9'h173
// 4 9'h134 T 9'h154 t 9'h174
// 5 9'h135 U 9'h155 u 9'h175
// 6 9'h136 V 9'h156 v 9'h176
// 7 9'h137 W 9'h157 w 9'h177
// 8 9'h138 X 9'h158 x 9'h178
// 9 9'h139 Y 9'h159 y 9'h179
// : 9'h13A Z 9'h15A z 9'h17A
// ; 9'h13B [ 9'h15B { 9'h17B
// < 9'h13C ¥ 9'h15C | 9'h17C
// = 9'h13D ] 9'h15D } 9'h17D
// > 9'h13E ^ 9'h15E → 9'h17E
// ? 9'h13F _ 9'h15F ← 9'h17F
module LCD ( // Host Side
iCLK,iRST_N,
mLCD_DATA,mLCD_RS,mLCD_Start,mLCD_Done,
data);
// Host Side
input iCLK,iRST_N,mLCD_Done;
input [ 23 : 0 ] data;
output reg mLCD_Start;
output reg [ 7 : 0 ] mLCD_DATA;
output reg mLCD_RS;
// Internal Wires/Registers
reg [ 5 : 0 ] LUT_INDEX;
reg [ 8 : 0 ] LUT_DATA;
reg [ 5 : 0 ] mLCD_ST;
reg [ 17 : 0 ] mDLY;

parameter LCD_INTIAL = 0 ;
parameter LCD_LINE1 = 5 ;
parameter LCD_CH_LINE = LCD_LINE1 + 16 ; // 21
parameter LCD_LINE2 = LCD_LINE1 + 16 + 1 ; // 22
parameter LUT_SIZE = LCD_LINE1 + 32 + 1 ; // 38

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 ' h3FFFE)
mDLY <= mDLY + 1 ' b1;
else
begin
mDLY
<= 0 ;
mLCD_ST
<= 3 ;
end
end
3 : begin
LUT_INDEX
<= LUT_INDEX + 1 ' b1;
mLCD_ST <= 0 ;
end
endcase
end
else
begin
mLCD_ST
<= 0 ;
LUT_INDEX
<= LCD_INTIAL + 3 ;
end
end
end

always @ ( * )
begin
case (LUT_INDEX)
// Initial
LCD_INTIAL + 0 : LUT_DATA <= 9 ' h038;//显示模式设置
LCD_INTIAL + 1 : LUT_DATA <= 9 ' h00C;//显示状态开关设置
LCD_INTIAL + 2 : LUT_DATA <= 9 ' h001;//清屏
LCD_INTIAL + 3 : LUT_DATA <= 9 ' h006;//显示光标移动设置
LCD_INTIAL + 4 : LUT_DATA <= 9 ' h080;//置数据存贮器地址
// Line 1
LCD_LINE1 + 0 : LUT_DATA <= 9 ' h120; //
LCD_LINE1 + 1 : LUT_DATA <= 9 ' h120;
LCD_LINE1 + 2 : LUT_DATA <= { 5 ' b10011,data[23:20]};
LCD_LINE1 + 3 : LUT_DATA <= { 5 ' b10011,data[19:16]};
LCD_LINE1 + 4 : LUT_DATA <= 9 ' h13A;
LCD_LINE1 + 5 : LUT_DATA <= { 5 ' b10011,data[15:12]};
LCD_LINE1 + 6 : LUT_DATA <= { 5 ' b10011,data[11:8]};
LCD_LINE1 + 7 : LUT_DATA <= 9 ' h13A;
LCD_LINE1 + 8 : LUT_DATA <= { 5 ' b10011,data[7:4]};
LCD_LINE1 + 9 : LUT_DATA <= { 5 ' b10011,data[3:0]};
LCD_LINE1 + 10 : LUT_DATA <= 9 ' h120;
LCD_LINE1 + 11 : LUT_DATA <= 9 ' h157;
LCD_LINE1 + 12 : LUT_DATA <= 9 ' h141;
LCD_LINE1 + 13 : LUT_DATA <= 9 ' h14E;
LCD_LINE1 + 14 : LUT_DATA <= 9 ' h147;
LCD_LINE1 + 15 : LUT_DATA <= 9 ' h120;
// Change Line
LCD_CH_LINE: LUT_DATA <= 9 ' h0C0;
// Line 2
LCD_LINE2 + 0 : LUT_DATA <= 9 ' h132; //
LCD_LINE2 + 1 : LUT_DATA <= 9 ' h130;
LCD_LINE2 + 2 : LUT_DATA <= 9 ' h131;
LCD_LINE2 + 3 : LUT_DATA <= 9 ' h130;
LCD_LINE2 + 4 : LUT_DATA <= 9 ' h12D;
LCD_LINE2 + 5 : LUT_DATA <= 9 ' h131;
LCD_LINE2 + 6 : LUT_DATA <= 9 ' h131;
LCD_LINE2 + 7 : LUT_DATA <= 9 ' h12D;
LCD_LINE2 + 8 : LUT_DATA <= 9 ' h131;
LCD_LINE2 + 9 : LUT_DATA <= 9 ' h136;
LCD_LINE2 + 10 : LUT_DATA <= 9 ' h120;
LCD_LINE2 + 11 : LUT_DATA <= 9 ' h120;
LCD_LINE2 + 12 : LUT_DATA <= 9 ' h177;
LCD_LINE2 + 13 : LUT_DATA <= 9 ' h165;
LCD_LINE2 + 14 : LUT_DATA <= 9 ' h169;
LCD_LINE2 + 15 : LUT_DATA <= 9 ' h120;
default : LUT_DATA <= 9 ' h000;
endcase
end

endmodule

 

你可能感兴趣的:(Verilog)