树莓 Raspberry Pi PICO - LCD 1602 - Python(未完成)
LCD1602 液晶显示器是广泛使用的一种字符型液晶显示模块。很多单片机、开发板等都有它的踪影,语言中无论是 C/C++、Python、Arduino 等都已经有许多大佬帮它写了初始化、SDK、头文件、模块... 只需下载直接就能调用,不用理解显示器内部运作方式。
在这里我想试试自己写 {:10_301:}
以下代码(未完成),因为怕忘记,所以先笔记。{:5_99:}{:5_99:}
from machine import Pin, PWM
from micropython import const
from time import sleep_us
LOW = const(0)
HIGH = const(1)
# 将数据 (二进制) 写入八位引脚
def setting(D: "引脚", data: "二进制数据") -> None:
res = list()
i = 8
while i:
i -= 1
res.append(data & 1)
data >>= 1
for i, d in res[::-1]:
D.high() if d else D.low()
class LCD1602:
def __init__(self, GND, VCC, VO, RS, RW, EN, A, K, *D):
# 电源控制引脚
self.GND = GND
self.VCC = VCC
self.GND.value(LOW)
self.VCC.value(HIGH)
# 液晶显示控制引脚
self.VO = VO # LCD 对比度 - 脉冲引脚
self.A = A # LCD 背光 - Anode
self.K = K # LCD 背光 - Cathode
self.A.value(HIGH)
self.K.value(LOW)
self.VO.duty_16(65535 >> 1) # 将占空比设为 50%
self.VO.init(freq = 5000, duty_ns = 5000) # 重新初始化,周期为 200us,占空比为 5us
self.VO.duty_ns(3000) # 设置脉冲宽度为 3us
# 数据控制引脚
self.RS = RS # 寄存器选择
self.RW = RW # 读 / 写数据
self.EN = EN # enable 启用
self.D = D # 8 bits (0000 0000)
def __del__(self):
self.VO.deinit() # 结束脉冲信号
# 清屏指令 (clear display) # RS RW 0 0 0 0 0 0 0 1
def Clear(self):
"""
清除液晶显示器,即将 DDRAM 中的内容全部填入 20H (空白字符)
光标撤回显示屏左上方
将地址计数器 (AC) 设为 0
光标移动方向为从左向右,并且 DDRAM 的自增量为 1 (ID = 1)
"""
self.RS.low()
self.RW.low()
setting(self.D, 0x01) # 8bits 0000 0001
# 光标归位指令 (Return Home) # RS RW 0 0 0 0 0 0 1 X
def Home(self):
"""
将地址计数器 (AC) 设为 00H
DDRAM 内容保持不变
光标移至左上脚
** DB0: X (未知逻辑电平)
"""
self.RS.low()
self.RW.low()
pin.value(LOW) for pin in self.D
self.D.value(HIGH)
# 进入模式设置指令 (Entry Mode Set) RS RW 0 0 0 0 0 1 ID SH
def Entry(self, ID = LOW, SH = HIGH):
""" 设定每次定入 1 位数据后,光标移位方向并且设定次写入一个字符是否移动
ID = 0 光标左移,DDRAM 地址自增 1
ID = 1 光标右移,DDRAM 地址自增 1 (当从 CGRAM 中读取或写入数据时,CGRAM 操作与 DDRAM 相同)
SH = 0 且 DDRAM是读操作(CGRAM读或写),整个屏幕不移动
SH = 1 且 DDRAM 是写操作,整个屏幕移动,移动方向由I/D决定
** ID: Increment / decrement of DDRAM address (cursor or blink)
** SH: Shift of entire display
"""
self.RS.low()
self.RW.low()
setting(self.D, 0b100 | ID << 1 | SH)
# 显示开关控制 (Display ON/OFF Control)
def OnOff(self, D = HIGH, C = HIGH, B = LOW): # RS RW 0 0 0 0 1 D C B
"""
D = 1 显示功能开
D = 0 显示功能关,但是 DDRAM 中的数据依然保留
C = 1 有光标
C = 0 没有光标
B = 1 光标闪烁
B = 0 光标不闪烁
** D: Display ON/OFF control bit
** C: Cursor ON/OFF control bit
** B: Cursor Blink ON/OFF control bit
"""
self.RS.low()
self.RW.low()
setting(self.D, 0b1000 | D << 2 | C << 1 | B)
# 设置显示屏或光标移动方向的指令 RS RW 0 0 0 1 SC RL X X
def Shift(self, SC = HIGH, RL = HIGH):
""" 整屏的移动或光标移动
S/C = 0 R/L = 0 光标左移,地址计数器减 1 (即显示内容和光标一起左移)
S/C = 0 R/L = 1 光标右移,地址计数器加 1 (即显示内容和光标一起右移)
S/C = 1 R/L = 0 显示内容左移,光标不移动
S/C = 1 R/L = 1 显示内容右移,光标不移动
** S/C: Screen / Cursor
** R/L: Right / Left
"""
self.RS.low()
self.RW.low()
self.D.value(state) for pin, state in enumerate(, start = 2)
# 功能设定指令 RS RW 0 0 1 DL N F XX
def Set(self, DL = HIGH, N = HIGH, F = HIGH):
""" 设定数据总线位数、显示的行数及字形
DL = 1 数据总线是 8 位
DL = 0 数据总线是 4 位
N = 0 显示一行
N = 1 显示两行
F = 0 5x8 点阵/字符
F = 1 5x11 点阵/字符
** DL: Interface data length control bit
** N: Display line number control bit
** F: Display font type control bit
"""
self.RS.low()
self.RW.low()
self.D.value(state) for pin, state in enumerate(, start = 2)
# 设定 DDRAM 地址指令 RS RW 1 AC6 AC5 AC4 AC3 AC2 AC1 AC0
# 设定 CGRAM 地址指令 RS RW 01AC5 AC4 AC3 AC2 AC1 AC0
def Write(self, data):
""" 设定下一个要存入数据的 CGRAM 地址
DB5 DB4 DB3 为字符号,即将显示该字符用到的字符地址 8 bits
DB2 DB1 DB0 为行号 111 / 000
** CGRAM: Character generate RAM 自定义的字符或图形,存储在 CGRAM 中
** CGROM: Character generate ROM 常用字符原本就已经存储在 CGROM 中,可以直接调用
** DDRAM: Display Data Random Access Memory 显示用的地址
DDRAM 地址与显示位置对应关系如下:
00H 01H 02H 03H 04H 05H 06H 07H 08H 09H 10H 11H 12H 13H 14H 15H
40H 41H 42H 43H 44H 45H 46H 47H 48H 49H 4AH 4BH 4CH 4DH 4EH 4FH
-----------------------------------------------------------------------------------
|command| |running|
|function | instruction encoding | time |
-----------------------------------------------------------------------------------
| set | RS| RW| DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0 | |
| DDRAM |----------------------------------------------------------- 40us |
|address|0|0|1| CGRAM address (7 bits) | |
-----------------------------------------------------------------------------------
###################################################################################
-----------------------------------------------------------------------------------
|command| |running|
|function | instruction encoding | time |
-----------------------------------------------------------------------------------
| set | RS| RW| DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0 | |
| CGRAM |----------------------------------------------------------- 40us |
|address|0|0|0|1| CGRAM address (6 bits) | |
-----------------------------------------------------------------------------------
"""
self.RS.low()
self.RW.low()
setting(self.D, address)
sleep_us(100) # 延迟 100毫秒,以确保数据接受完毕 (数据接收至少需要 40us)
"编写中..."
pass
def Read(self, data):
"编写中..."
pass
if __name__ == "__main__":
# 引脚 GPIO 0 ~ 15
GND = Pin(0, Pin.OUT)
VCC = Pin(1, Pin.OUT)
VO= PWM(2)
RS= Pin(3, Pin.OUT)
RW= Pin(4, Pin.OUT)
EN= Pin(5, Pin.OUT)
D = Pin(i, Pin.OUT) for i in range(6, 14)
A = Pin(14, Pin.OUT)
K = Pin(15, Pin.OUT)
lcd = LCD1602(GND, VCC, VO, RS, RW, EN, A, K, D)
虽然对这方面一窍不通啊,但是还是加油了{:10_257:}
另外可以像@元豪 做植物大战僵尸的时候开一个栏目,容易被评分{:10_256:} hziyan 发表于 2023-1-29 13:07
虽然对这方面一窍不通啊,但是还是加油了
另外可以像@元豪 做植物大战僵尸的时候开一个栏目, ...
{:10_254:} hziyan 发表于 2023-1-29 13:07
虽然对这方面一窍不通啊,但是还是加油了
另外可以像@元豪 做植物大战僵尸的时候开一个栏目, ...
{:10_256:}
页:
[1]