0%

在树莓派4B上使用LCD1602液晶屏

raspberry-pi-logo-1920.png

LCD1602技术原理

LCD1602.png

简介

LCD1602可以显示16 x 2个字符,且只支持标准ASCII码字符和日文希腊文字符。

引脚定义

LCD1602一共有16个针脚,如果直接将其连接在树莓派上的话非常占用资源,所以我这里用的是和 I2C(I2C)模块集成在一起的板子。I2C 只有四个针脚,这样就可以大幅度节约树莓派针脚去干其他事,I2C接口引脚如下:

引脚 功能
GND 接地
VCC 控制电压
SDA I2C数据
SCL I2C时钟

接线

LCD1602连接树莓派GPIO.png

准备工作

安装i2c-tools

使用命令:

1
sudo apt install i2c-tools

安装python-smbus

使用命令:

1
sudo apt install python-smbus

查看I2C设备地址

使用命令及返回:

1
2
3
4
5
6
7
8
9
10
$ sudo i2cdetect -y 1 
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

看到地址为0x27。这说明已经成功连接了1602A 。接下来就可以控制1602A显示信息了。

程序

代码来自:树莓派通过 I2C 驱动 LCD1602 液晶屏 | 树莓派实验室 (nxez.com)

驱动程序LCD1602.py

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
import time
import smbus
BUS = smbus.SMBus(1)
LCD_ADDR = 0x27
BLEN = 1 #turn on/off background light

def turn_light(key):
global BLEN
BLEN = key
if key ==1 :
BUS.write_byte(LCD_ADDR ,0x08)
else:
BUS.write_byte(LCD_ADDR ,0x00)

def write_word(addr, data):
global BLEN
temp = data
if BLEN == 1:
temp |= 0x08
else:
temp &= 0xF7
BUS.write_byte(addr ,temp)

def send_command(comm):
# Send bit7-4 firstly
buf = comm & 0xF0
buf |= 0x04 # RS = 0, RW = 0, EN = 1
write_word(LCD_ADDR ,buf)
time.sleep(0.002)
buf &= 0xFB # Make EN = 0
write_word(LCD_ADDR ,buf)

# Send bit3-0 secondly
buf = (comm & 0x0F) << 4
buf |= 0x04 # RS = 0, RW = 0, EN = 1
write_word(LCD_ADDR ,buf)
time.sleep(0.002)
buf &= 0xFB # Make EN = 0
write_word(LCD_ADDR ,buf)

def send_data(data):
# Send bit7-4 firstly
buf = data & 0xF0
buf |= 0x05 # RS = 1, RW = 0, EN = 1
write_word(LCD_ADDR ,buf)
time.sleep(0.002)
buf &= 0xFB # Make EN = 0
write_word(LCD_ADDR ,buf)

# Send bit3-0 secondly
buf = (data & 0x0F) << 4
buf |= 0x05 # RS = 1, RW = 0, EN = 1
write_word(LCD_ADDR ,buf)
time.sleep(0.002)
buf &= 0xFB # Make EN = 0
write_word(LCD_ADDR ,buf)

def init_lcd():
try:
send_command(0x33) # Must initialize to 8-line mode at first
time.sleep(0.005)
send_command(0x32) # Then initialize to 4-line mode
time.sleep(0.005)
send_command(0x28) # 2 Lines & 5*7 dots
time.sleep(0.005)
send_command(0x0C) # Enable display without cursor
time.sleep(0.005)
send_command(0x01) # Clear Screen
BUS.write_byte(LCD_ADDR ,0x08)
except:
return False
else:
return True

def clear_lcd():
send_command(0x01) # Clear Screen

def print_lcd(x, y, str):
if x < 0:
x = 0
if x > 15:
x = 15
if y <0:
y = 0
if y > 1:
y = 1

# Move cursor
addr = 0x80 + 0x40 * y + x
send_command(addr)

for chr in str:
send_data(ord(chr))

if __name__ == '__main__':
init_lcd()
print_lcd(0, 0, 'Hello, world!')

显示时间的示例程序time.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/user/bin/env python 
import smbus
import time
import sys
import LCD1602 as LCD

if __name__ == '__main__':
LCD.init_lcd()
time.sleep(1)
LCD.print_lcd(2, 0, 'WWW.QUWJ.COM')
for x in range(1, 4):
LCD.turn_light(0)
LCD.print_lcd(4, 1, 'LIGHT OFF')
time.sleep(0.5)
LCD.turn_light(1)
LCD.print_lcd(4, 1, 'LIGHT ON ')
time.sleep(0.5)

LCD.turn_light(1)

while True:
now = time.strftime('%m/%d %H:%M:%S', time.localtime(time.time()))
LCD.print_lcd(1, 1, now)
time.sleep(0.2)