顶层代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
module lcd1602(
input CLOCK_50,
input RST_N,
inout[7:0] LCD_DATA,
output LCD_EN,
output LCD_RS,
output LCD_RW,
output LCD_ON,
output LCD_BLON
);
//initial//
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
|
RST_N初始延迟代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
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.njodin.com
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'h16A;
//j
LCD_LINE2+7: LUT_DATA <= 9'h16F;
//o
LCD_LINE2+8: LUT_DATA <= 9'h164;
//d
LCD_LINE2+9: LUT_DATA <= 9'h169;
//i
LCD_LINE2+10: LUT_DATA <= 9'h16E;
//n
LCD_LINE2+11: LUT_DATA <= 9'h12E;
//.
LCD_LINE2+12: LUT_DATA <= 9'h163;
//c
LCD_LINE2+13: LUT_DATA <= 9'h16F;
//o
LCD_LINE2+14: LUT_DATA <= 9'h16D;
//m
LCD_LINE2+15: LUT_DATA <= 9'h120;
//
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
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
|
效果图:
![](https://i-blog.csdnimg.cn/blog_migrate/30e0a8687677ba8e186191bd1e786c37.jpeg)