LCD接口(附8051LCD1602显示:源码+原理图)

工程源码及原理图:链接:https://pan.baidu.com/s/1KgmiGkFdl_sFE5GTm5MSsQ?pwd=l1gp
提取码:l1gp

LCD(Liquid Crystal Display):又称液晶显示器

LCD引脚

LCD一共有14个引脚,如下图:

image-20231206175851955

以LCD1602为例:

image-20231206180044336

以下我们对引脚进行逐个解释:

VSS,VDD,VO

引脚 功能
VSS
VDD 电源正极(4.5~5.5V)
VO 对比度调节电压(一般接在可变电阻上以调节电压)

 

RS(寄存器选择)

数据/指令选择,1为数据,0为指令

若RS=0,选择==指令代码寄存器==,允许用户发送指令,如清屏,使光标返回初始位置。

若RS=1,选择==数据寄存器==,允许用户发送数据显示在LCD上

 

RW(read/write)

读/写选择,1为读,0为写

E(使能)

使能,1为数据有效,下降沿执行命令

D0~D7

数据输入/输出

A/K

A:背光灯电源正极

K:背光灯电源负极

 

其内部结构图如下:image-20231206181354663

数据显示在屏幕上的流程:

数据——>DDRAM——>字模库——>屏幕

DDRAM比屏幕显示内存更多以便实现滚动字符等的效果。

 

LCD1602指令集

1.清屏指令( 0000 0001 )

1.清除液晶显示器,即将DDRAM的内容全部清除。
2.光标回到液晶屏左上方。
3.地址计数器(AC)的值设置为0。

2.光标归位指令(0000 001x)

1.把光标返回到液晶屏左上方。
2.把地址计数器(AC)的值设置为0。
3.保持DDRAM的内容不变。

3.模式设置指令(0000 01 I/D S)

设定每次写入一位数据后光标的移动方向,并且设定每次写入一个字符是否移动。
I/D:0写入新数据后光标左移,1写入新数据后光标右移。
S :0写入新数据后显示屏不移动,1写入新数据后显示屏整体右移一个字符。

4.显示开关控制指令(0000 1 D C B)

D:0显示关,1显示开。
C:0无光标,1有光标。
B:0光标不闪烁,1光标闪烁。

5.设定显示屏或光标移动方向指令(000 1 S/C R/L x x)

S/C R/L
0 0 光标左移一格,且AC减一。
0 1 光标右移一格,且AC加一。
1 0 显示器字符全部左移一格,光标不动。
1 1 显示器字符全部右移一格,光标不动。

6.功能设定指令(00 1 DL N F x x)

DL:0数据总线为4位,1数据总线为8位。
N: 0显示 1 行,1显示 2 行。
F: 0 58字符点阵,1 510字符点阵。

7.设定CGRAM地址指令(01 aaaaaa)6位地址

8.设定DDRAM地址指令(1 aaaaaaa)7位地址

9.读取忙信号或AC地址指令(BF aaaaaaa)

BF:0空闲,1忙。
aaaaaaa:读取AC地址。

10.数据写入DDRAM或CGRAM指令

11.从DDRAM或CGRAM读出数据指令

 

 

函数功能实现

初始化

发送指令0x38 //八位数据接口,两行显示,5*7点阵

发送指令0x0C //显示开,光标关,闪烁关

发送指令0x06 //数据读写操作后,光标自动加一,画面不动

发送指令0x01 //清屏

1
2
3
4
5
6
7
void LCD_Init(void)
{
LCD_WriteCommand(0x38);
LCD_WriteCommand(0x0C);
LCD_WriteCommand(0x06);
LCD_WriteCommand(0x01);
}

 

LCD1602写命令

1
2
3
4
5
6
7
8
9
10
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_E=1;
LCD_Delay();
LCD_E=0;
LCD_Delay();
}

LCD1602写数据

1
2
3
4
5
6
7
8
9
10
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort=Data;
LCD_E=1;
LCD_Delay();
LCD_E=0;
LCD_Delay();
}

LCD1602设置光标位置

1
2
3
4
5
6
7
8
9
10
11
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else
{
LCD_WriteCommand(0x80|(Column-1)+0x40);
}
}

在LCD1602指定位置开始显示所给字符串

  • Line 起始行位置,范围:1~2
  • Column 起始列位置,范围:1~16
  • String 要显示的字符串
1
2
3
4
5
6
7
8
9
void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!='\0';i++)
{
LCD_WriteData(String[i]);
}
}

在LCD1602指定位置开始显示所给数字

  • Line 起始行位置,范围:1~2
    • Column 起始列位置,范围:1~16
    • Number 要显示的数字,范围:0~65535
    • Length 要显示数字的长度,范围:1~5
1
2
3
4
5
6
7
8
9
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData('0'+Number/LCD_Pow(10,i-1)%10);
}
}

在LCD1602指定位置开始以有符号十进制显示所给数字

  • Line 起始行位置,范围:1~2
  • Column 起始列位置,范围:1~16
  • Number 要显示的数字,范围:-32768~32767
  • Length 要显示数字的长度,范围:1~5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
unsigned char i;
unsigned int Number1;
LCD_SetCursor(Line,Column);
if(Number>=0)
{
LCD_WriteData('+');
Number1=Number;
}
else
{
LCD_WriteData('-');
Number1=-Number;
}
for(i=Length;i>0;i--)
{
LCD_WriteData('0'+Number1/LCD_Pow(10,i-1)%10);
}
}

在LCD1602指定位置开始以十六进制显示所给数字

  • Line 起始行位置,范围:1~2
  • Column 起始列位置,范围:1~16
  • Number 要显示的数字,范围:0~0xFFFF
  • Length 要显示数字的长度,范围:1~4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
unsigned char SingleNumber;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
SingleNumber=Number/LCD_Pow(16,i-1)%16;
if(SingleNumber<10)
{
LCD_WriteData('0'+SingleNumber);
}
else
{
LCD_WriteData('A'+SingleNumber-10);
}
}
}

在LCD1602指定位置开始以二进制显示所给数字

  • Line 起始行位置,范围:1~2
    • Column 起始列位置,范围:1~16
    • Number 要显示的数字,范围:0~1111 1111 1111 1111
    • Length 要显示数字的长度,范围:1~16
1
2
3
4
5
6
7
8
9
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData('0'+Number/LCD_Pow(2,i-1)%2);
}
}

 

在LCD1602显示姓名学号

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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#include <REGX52.H>
#include "LCD1602.h"

sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_E=P2^2;
#define LCD_DataPort P0

void Delay(unsigned int xms);

void LCD_Init(void);
void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_WriteCommand(unsigned char Command);

void main()
{
LCD_Init(); //LCD初始化

LCD_ShowString(1,1,"yourname"); //第一行第一列开始显示名字
LCD_ShowNum(2,1,12138,5); //第二行第一列显示12138
LCD_ShowNum(2,6,12138,5); //第二行第六列开始显示12138

while(1)
{
}
}

void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}

void LCD_Delay() //@12.000MHz 1ms
{
unsigned char i, j;

i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}

void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort=Data;
LCD_E=1;
LCD_Delay();
LCD_E=0;
LCD_Delay();
}

void LCD_Init(void)
{
LCD_WriteCommand(0x38);
LCD_WriteCommand(0x0C);
LCD_WriteCommand(0x06);
LCD_WriteCommand(0x01);
}

void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else
{
LCD_WriteCommand(0x80|(Column-1)+0x40);
}
}
void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Char);
}
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_E=1;
LCD_Delay();
LCD_E=0;
LCD_Delay();
}

void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!='\0';i++)
{
LCD_WriteData(String[i]);
}
}

int LCD_Pow(int X,int Y)
{
unsigned char i;
int Result=1;
for(i=0;i<Y;i++)
{
Result*=X;
}
return Result;
}

void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData('0'+Number/LCD_Pow(10,i-1)%10);
}
}

void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
unsigned char i;
unsigned int Number1;
LCD_SetCursor(Line,Column);
if(Number>=0)
{
LCD_WriteData('+');
Number1=Number;
}
else
{
LCD_WriteData('-');
Number1=-Number;
}
for(i=Length;i>0;i--)
{
LCD_WriteData('0'+Number1/LCD_Pow(10,i-1)%10);
}
}

void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
unsigned char SingleNumber;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
SingleNumber=Number/LCD_Pow(16,i-1)%16;
if(SingleNumber<10)
{
LCD_WriteData('0'+SingleNumber);
}
else
{
LCD_WriteData('A'+SingleNumber-10);
}
}
}

void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData('0'+Number/LCD_Pow(2,i-1)%2);
}
}




image-20231206213916889