电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
树莓派基础实验29:I2C LCD1602实验
分 享
扫描二维码分享
树莓派基础实验29:I2C LCD1602实验
lcd1602
树莓派
张国平
关注
发布时间: 2020-05-26
丨
阅读: 948
## 一、介绍 众所周知,虽然液晶显示器和其他显示器大大的丰富了人机交互,但他们有一个共同的弱点。当它们连接到控制器时,需要占用大量的IO口,但是一般的控制器没有那么多的外部端口,也限制了控制器的其他功能。因此,开发具有I2C组件的LCD1602来解决该问题,LCD1602是一种只用来显示字母、数字、符号等的点阵型液晶模块。 字符型液晶显示模块是由字符型液晶显示屏LCD 、控制驱动主电路HD44780/KS0066及其扩展驱动电路HD44100或与其兼容的IC, 少量阻、容元件结构件等装配在PCB板上而成。 I2C总线是由PHLIPS发明的一种串行总线。它是一种高性能的串行总线,具有多主机系统所需的总线控制和高速或低速设备同步功能。I2C LCD1602上的蓝色电位器用于调整背光,以获得更好的显示效果。I2C使用两个双向极漏开路线,串行数据线(SDA)和串行时钟线(SCL),通过电阻上拉。使用的典型电压为5V或3.3V,但允许使用其他电压的系统。 ## 二、组件 ★Raspberry Pi 3主板*1 ★树莓派电源*1 ★40P软排线*1 ★I2C LCD1602模块*1 ★面包板*1 ★跳线若干 ## 三、实验原理 ![LCD1602正面](https://cf03.ickimg.com/bbsimages/202005/a99dd3c062379b049f89cc400b082b0c.jpg) ![LCD1602背面](https://cf03.ickimg.com/bbsimages/202005/566e433888a5028a5104feab5f810b21.jpg) ![LCD1602电路图](https://cf03.ickimg.com/bbsimages/202005/c6850ea5b92fdd39573bd134c3334562.png) 树莓派的GPIO端口数量有限,可通过IO扩展芯片增加GPIO的数量,使得树莓派可以适应更多的应用。本实验中的LCD1602模块有16个管脚,为节省GPIO端口,就使用了一款通过I2C总线扩展IO的芯片,PCF8574。单个PCF8574可扩展8个IO,一个I2C总线最多可挂载8个PCF8574,所以树莓派最多可扩展64个IO。 本实验中的编程原理比较复杂,所以一定要程序和硬件原理结合起来看才易理解。如果不想深度学习底层原理及驱动程序,掌握LCD1602的函数使用方法就可以了,但若想灵活运用LCD1602,最好了解一下。 本文是在网上查阅了很多中外资料,汇集诸多大神的智慧,10几天(当然,每天还是要上班的)才整理汇编而成,但仍有很多不懂和错误之处,特别是程序中有一长串“????”注释的地方,请大神们留言指出! ####3.1 LCD1602的存储器 LCD1602里面存储器有三种:CGROM、CGRAM、DDRAM。 DDRAM(Display Data RAM)就是显示数据RAM,用来寄存待显示的字符代码。共80个字节,其地址和屏幕的对应关系如下,如图: ![数据地址和屏幕对应的关系](https://cf03.ickimg.com/bbsimages/202005/bf6cd9bf47694121667be3cd53993305.png) DDRAM其实就是我们平时说的PC机的显存,如果说我们想要在屏幕上显示我们想要显示的,直接把需要的字符代码送入现实就可以了,很简单就能够在屏幕上显示我们想要显示的。相同的LCD1602总共存在80个字节的显存,就是DDRAM。遗憾的是LCD1602显示不出来这么多的字符,正是因为这样,不是每一个写在DDRAM上的字符都能够在显示器上显示出来,一次只能显示16个字符。正是因为这样,我们在程序中可以利用下面的“光标或显示移动指令”使字符慢慢移动到可见的显示范围内,看到字符的移动效果。 那么如何在液晶上显示字符呢,就是把要写入的字符给DDRAM。举个例子,我现在想在屏幕上显示“A”,我就把我要的字符“A”的字符代码41H写入DDRAM的00H地址处然后得到。那我们应该怎么去写入呢,我们在后面进行进一步的阐述。我们下面将要介绍的是A的字模,如图: ![A的字模](https://cf03.ickimg.com/bbsimages/202005/edee0726ff7d39343414824a3d4c27e7.png) 上面的图左侧显示的就是“A”的字模数据,上面的图右侧显示“○”代表0,用“■”代表 1。这样我们就能够显示出“A”这个字形。 在LCD1602模块上固化了字模存储器,就是CGROM和CGRAM,HD44780内置了192个常用字符的字模,存于字符产生器CGROM(Character Generator ROM)中,另外还有8个允许用户自定义的字符产生RAM,称为CGRAM(Character Generator RAM),留给自定义的位置只有8个地址,也就是最多自定义8个符号或者图形。 下图(字模表)说明了CGROM和CGRAM与字符的对应关系。从ROM和RAM的名称我们也可以知道,ROM是早已固化在LCD1602模块中的,只能读取;但是RAM即可以读又可以写。 ![字模表](https://cf03.ickimg.com/bbsimages/202005/41a5b905468690eee93946b1a2504df6.png) 若是只要求在屏幕上显示CGROM中已经拥有的字符,那就仅仅需要在DDRAM中写入它的字符代码就可以了;若是想显示的是CGROM中不存在的字符,例如美元的符号,那就只能先在CGRAM中规定,下一步再在DDRAM中写入我们之前自己定义的字符就可以。 ![字形和光标](https://cf03.ickimg.com/bbsimages/202005/cfcaf14419bc55a9a780fc9d18c5116a.jpg) 上面这个图说明的是5×8点阵和5×10点阵字符的字形和光标的位置。这里我们采用的是5×8点阵,那么定义这样一个字符需要8个字节,每个字节的前3个位没有被使用。 ![设置CGRAM地址指令](https://cf03.ickimg.com/bbsimages/202005/c0b62cf69ec05daf824318c19f792aea.png) 上面这个图说明的是设置CGRAM地址指令。从这个指令的格式中我们可以看出,它共有aaaaaa这6位,一共可以表示64个地址,即64个字节。一个5×8点阵字符共占用8个字节,那么这64个字节一共可以自定义8个字符。也就是说,上面这个图的6位地址中的DB5DB4DB3用来表示8个自定义的字符,DB2DB1DB0用来表示每个字符的8个字节。这DB5DB4DB3所表示的8个自定义字符(0--7)就是要写入DDRAM中的字符代码。 ####3.2 管脚 加装了I2C转接版的LCD1602,能够同时显示16x02即32个字符。(16列2行)1602字符型LCD通常有16条引脚线的LCD: | 引脚 | 符号 |功能说明| |:-|:-|:-| |1|VSS|一般接地| |2|VDD|接电源(+5V)| |3|V0|晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度)。| |4|RS|RS为寄存器选择,**高电平(1)时选择数据寄存器、低电平(0)时选择指令寄存器。**| |5|R/W|R/W为读写选择,**高电平(1)时进行读操作,低电平(0)时进行写操作。**| |6|E|**E(或EN)端为使能(enable)端,写操作时,下降沿使能。读操作时,E高电平有效**| |7|DB0|低4位三态、 双向数据总线 0位(最低位)| |8|DB1|低4位三态、 双向数据总线 1位| |9|DB2|低4位三态、 双向数据总线 2位| |10|DB3|低4位三态、 双向数据总线 3位| |11|DB4|高4位三态、 双向数据总线 4位| |12|DB5|高4位三态、 双向数据总线 5位| |13|DB6|高4位三态、 双向数据总线 6位| |14|DB7|高4位三态、 双向数据总线 7位(最高位)(也是busy flag)| |15|BLA|背光电源正极| |16|BLK|背光电源负极| ####3.3 LCD1602的基本操作及时序 本系列模块内部具有两个 8 位寄存器:指令寄存器(IR)和数据寄存器(DR)。用户可以通过 RS 和 R/W 输入信号的组合选择指定的寄存器,进行相应的操作。下表中列出了组合选择方式: |RS |R/W |操作说明| |:-:|:-:|:-| |0 |0 |写入指令寄存器(清除屏等)| |0 |1 |读busy flag(DB7),以及读取位址计数器(DB0~DB6)值| |1 |0 |写入数据寄存器(显示各字型等)| |1 |1 |从数据寄存器读取数据| LCD1602的基本操作: 1. 读状态:输入RS=0,RW=1,E=高脉冲。输出:D0—D7为状态字。 2. 读数据:输入RS=1,RW=1,E=高脉冲。输出:D0—D7为数据。 3. 写命令:输入RS=0,RW=0,E=高脉冲。输出:无。(写完置E=高脉冲) 4. 写数据:输入RS=1,RW=0,E=高脉冲。输出:无。 注意:E(或EN)端为使能(enable)端,写操作时,下降沿使能。读操作时,E高电平有效。 读操作时序图: ![读操作时序图](https://cf03.ickimg.com/bbsimages/202005/a5cc846e8cb8d85056a5cfaf06af9e88.jpg) 写操作时序图: ![写操作时序图](https://cf03.ickimg.com/bbsimages/202005/bf112e73e1ecc73809550189f13e1037.jpg) 时序时间参数: ![时序时间参数](https://cf03.ickimg.com/bbsimages/202005/18d5d9097c6b654bb286224b54509d69.jpg "时序时间参数") ####3.4 LCD1602的指令说明 1602液晶模块内部的控制器共有11条控制指令: ![LCD1602控制命令表](https://cf03.ickimg.com/bbsimages/202005/ce1154ce791174c224e2acfac159c0a7.jpg) 1602液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。 **指令1:**清显示,指令码01H,光标复位到地址00H位置。 说明:清除屏幕显示内容。光标返回屏幕左上角。执行这个指令时需要一定时间。 **指令2:**光标复位,光标返回到地址00H。 说明:光标返回屏幕左上角,它不改变屏幕显示内容。 **指令3:**光标和显示模式设置 ![进入模式设置指令](https://cf03.ickimg.com/bbsimages/202005/09184d2ecd279261ab87e173a2c03899.jpg) I/D=1:写入新数据后光标右移。 I/D=0:写入新数据后光标左移。 S=1:显示移动。 S=0:显示不移动。 说明:这里的设置是0x06。 **指令4:**显示开关控制。 ![显示开关控制指令](https://cf03.ickimg.com/bbsimages/202005/358ee46916ca93c8a36253f4614a0928.jpg) D=1:显示开,D=0:显示关。 C=1:光标显示,C=0:光标不显示。 B=1:光标闪烁,B=0:光标不闪烁。 说明:这里的设置是显示开,不显示光标,光标不闪烁,设置字为0x0c。 **指令5:**光标或显示移位 ![光标或显示移动指令](https://cf03.ickimg.com/bbsimages/202005/3298720bcc323b692afd9b81aa99236e.png) ![光标或显示移动指令说明](https://cf03.ickimg.com/bbsimages/202005/bc0a3707a21f3fbbf126ea2f842474ce.jpg) 说明:在需要进行整屏移动时,这个指令非常有用,可以实现屏幕的滚动显示效果。初始化时不使用这个指令。 **指令6:**功能设置命令 ![工作方式设置指令](https://cf03.ickimg.com/bbsimages/202005/bc06e5615d9fde72624fcae32f2a1d10.png) ×:不关心,也就是说这个位是0或1都可以,一般取0。 DL:设置数据接口位数。 DL=1:8位数据接口(D7—D0)。 DL=0:4位数据接口(D7—D4)。 N=0:一行显示。 N=1:两行显示。 F=0:5×8点阵字符。 F=1:5×10点阵字符。 说明:因为是写指令字,所以RS和RW都是0。LCD1602只能用并行方式驱动,不能用串行方式驱动。而并行方式又可以选择8位数据接口或4位数据接口。这里我们选择4位数据接口(D3—D0)。我们的设置是4位数据接口,两行显示,5×8点阵,即0b00101000也就是0x28。(注意:NF是10或11的效果是一样的,都是两行5×8点阵。因为它不能以两行5×10点阵方式进行显示,换句话说,这里用0x28或0x2c是一样的)。 **指令7:**字符发生器CGRAM地址设置。 ![设置CGRAM地址指令](https://cf03.ickimg.com/bbsimages/202005/b8e8efbe7e5a0d36c881375089f7bbc0.png) **指令8:**DDRAM地址设置。 ![设置DDRAM地址指令](https://cf03.ickimg.com/bbsimages/202005/27a51727f87fac7f62a0eae5731e73f7.png) 说明:这个指令用于设置DDRAM地址。在对DDRAM进行读写之前,首先要设置DDRAM地址,然后才能进行读写。前面我们说过,DDRAM就是LCD1602的显示存储器。我们要在它上面进行显示,就要把要显示的字符写入DDRAM。同样,我们想知道DDRAM某个地址上有什么字符,也要先设置DDRAM地址,然后将它读出到单片机。 **指令9:**读忙信号和光标地址 ![读忙信号和地址计数器AC](https://cf03.ickimg.com/bbsimages/202005/a86ef6fc9aa1c5e9d840eafbf65a49af.png) BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据。如果为低电平表示不忙。 说明:这个指令用来读取LCD1602状态。对于单片机来说,LCD1602属于慢速设备。当单片机向其发送一个指令后,它将去执行这个指令。这时如果单片机再次发送下一条指令,由于LCD1602速度较慢,前一条指令还未执行完毕,它将不接受这新的指令,导致新的指令丢失。因此这条读忙指令可以用来判断LCD1602是否忙,能否接收单片机发来的指令。当BF=1,表示LCD1602正忙,不能接受单片机的指令;当BF=0,表示LCD1602空闲,可以接收单片机的指令。RS=0,表示是指令;RW=1,表示是读取。这条指令还有一个副产品:即可以得到地址记数器AC的值(address counter)。LCD1602维护了一个地址计数器AC,用来记录下一次读写CGRAM或DDRAM的位置。需要强调的是:这条指令我一次也没有执行成功。很多网友似乎也是这样。好在我们有另外的办法,也就是延时。通过查看每条指令的执行时间,再经过一些试验,可以确定指令的延时。这样就可以在上一条指令执行完毕后再执行下一条指令了。 **指令10:**写数据。 ![写数据到CGRAM或DDRAM指令](https://cf03.ickimg.com/bbsimages/202005/59ab4ca3486e4dc4b9ac73ddb70534c6.png) 说明:RS=1,数据;RW=0,写。指令执行时,要在DB7—DB0上先设置好要写入的数据,然后执行写命令。 **指令11:**读数据。 ![从CGRAM或DDRAM读数据指令](https://cf03.ickimg.com/bbsimages/202005/f35085848edeb36339fd6703cd9d2060.jpg) 说明:RS=1,数据;RW=1,读。先设置好CGRAM或DDRAM的地址,然后执行读取命令。数据就被读入后DB7—DB0。 ####3.5 初始化 如果电路电源能满足内部RESET电路的如下要求, 初始化可自动完成: ![自动初始化](https://cf03.ickimg.com/bbsimages/202005/fba96666a14cd372c2ad706e7a6b65dc.jpg) 如果电路电源不能满足内部RESET电路的要求的话,需要用初始化程序来实现初始化,有8位总线和4位总线两种模式。 8位数据传输模式: ![8位总线模式初始化](https://cf03.ickimg.com/bbsimages/202005/08b856405acddaf72473865edc18cfe8.jpg) 本次实验中使用4位数据传输模式: ![4位总线初始化参数示例](https://cf03.ickimg.com/bbsimages/202005/5440ca7af0ed4878c5cc4855c0a2c5d1.jpg) ####3.6 DDRAM地址 1602字符液晶显示可分为上下两部分各16位进行显示,处于不同行时的字符显示地址如下: |显示字符 |1|2|3|4|......|12|13|14|15|16| |:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:| |第一行地址|00H|01H|02H|03H|......|0BH|0CH|0DH|0EH|0FH| |第二行地址|40H|41H|42H|43H|......|4BH|4CH|4DH|4EH|4FH| 按照上面**指令8**格式所示,由于地址为7位,在写入地址时,第8位D7恒为1。当我们想在指定位置写入内容时,要先指定地址,如在第一行第一位写入,地址位是00H,再加上DB7的1,即80H(0010000000),第二行第一位是40H,再加上DB7的1,即C0H(0011000000),依次类推。 ## 四、实验步骤 **第1步:**连接电路。连接电源打开树莓派,显示屏就会亮,同时在第一行显示一排黑方块。如果看不到黑方块或黑方块不明显,请调节可调电阻,直到黑方块清晰显示。如果调节可调电阻还看不到方块,则可能你的连接有问题了,请检查连接,包括检查显示屏的引脚有没有虚焊。 | 树莓派 | T型转接板 | LCD1602 | |:-:|:-:|:-:| |SCL|SCL|SCL| |SDA|SDA|SDA| |5V|5V|VCC| |GND|GND|GND| ![LCD1602实验电路图](https://cf03.ickimg.com/bbsimages/202005/ffe1509cd61377e3c076718a9e15c26b.jpg) ![LCD1602实验实物接线图](https://cf03.ickimg.com/bbsimages/202005/3b1e2ff97577619a01822c6a19bd2f1e.jpg) **第2步:**PCF8591模块采用的是I2C(IIC)总线进行通信的,但是在树莓派的镜像中默认是关闭的,在使用该传感器的时候,我们必须首先允许IIC总线通信。 ![打开I2C总线通信](https://cf03.ickimg.com/bbsimages/202005/75aee36527a36032f7213144d23558c1.png) **第3步:**查询LCD1602的地址。得出地址为0x27。 ```Python pi@raspberrypi:~ $ ls /dev/i2c-* /dev/i2c-1 pi@raspberrypi:~ $ 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: -- -- -- -- -- -- -- -- ``` **第4步:**编写驱动程序。这里先编写一个LCD1602.py文件,后面再编写一个python程序引入这个库文件,调用这个文件中的函数实现更复杂的功能。 LCD1602.py文件就相当于是LCD1602模块的驱动程序,单独编写是为了便于重用。 该程序也可以单独运行,会在第一行显示“Hello”,在第二行显示“world!”。 ```Python #!/usr/bin/env python import time import smbus #SMBus (System Management Bus,系统管理总线) 在程序中导入“smbus”模块 BUS = smbus.SMBus(1) #创建一个smbus实例 # 0 代表 /dev/i2c-0, 1 代表 /dev/i2c-1 ,具体看使用的树莓派那个I2C来决定 def write_word(addr, data): global BLEN #该变量为1表示打开LCD背光,若是0则关闭背光 temp = data if BLEN == 1: temp |= 0x08 #0x08=0000 1000,表开背光 #buf |= 0x08等价于buf = buf | 0x08(按位或) else: temp &= 0xF7 #0xF7=1111 0111,表关闭背光 #buf &= 0xF7等价于buf = buf & 0xF7(按位与) BUS.write_byte(addr ,temp) #这里为什么又一次写入8位?????? #write_byte(int addr, char val)发送一个字节到设备 def send_command(comm): # Send bit7-4 firstly buf = comm & 0xF0 #与运算,取高四位数值 #由于4位总线的接线是接到P0口的高四位,传送高四位不用改 buf |= 0x04 #buf |= 0x04等价于buf = buf | 0x04(按位或)0x04=0000 0100 # RS = 0, RW = 0, EN = 1 #为什么这样写入代表RS = 0, RW = 0, EN = 1,低4位在这里有何意义???????? write_word(LCD_ADDR ,buf) #为什么这里又是8位写入????? time.sl
eep(0.002) buf &= 0xFB #buf &= 0xFB等价于buf = buf & 0xFB(按位与)0xFB=1111 1011 # Make EN = 0,EN从1——>0,下降沿,进行写操作 #为什么这样写入代表Make EN = 0???????? write_word(LCD_ADDR ,buf) # Send bit3-0 secondly buf = (comm & 0x0F) << 4 #与运算,取低四位数值, #由于4位总线的接线是接到P0口的高四位,所以要再左移4位 buf |= 0x04 # RS = 0, RW = 0, EN = 1 写入命令 write_word(LCD_ADDR ,buf) time.sl
eep(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.sl
eep(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.sl
eep(0.002) buf &= 0xFB # Make EN = 0 write_word(LCD_ADDR ,buf) def init(addr, bl): #LCD1602初始化 global LCD_ADDR #该变量为设备地址 global BLEN #该变量为1表示打开LCD背光,若是0则关闭背光 LCD_ADDR = addr BLEN = bl try: send_command(0x33) # 必须先初始化为8行模式 110011 Initialise time.sl
eep(0.005) send_command(0x32) # 然后初始化为4行模式 110010 Initialise time.sl
eep(0.005) send_command(0x28) # 4位总线,双行显示,显示5×8的点阵字符。 time.sl
eep(0.005) send_command(0x0C) # 打开显示屏,不显示光标,光标所在位置的字符不闪烁 time.sl
eep(0.005) send_command(0x01) # 清屏幕指令,将以前的显示内容清除 time.sl
eep(0.005) send_command(0x06) # 设置光标和显示模式,写入新数据后光标右移,显示不移动 BUS.write_byte(LCD_ADDR, 0x08) #这里这样写入0x08是什么意思?????? except: return False else: return True def clear(): send_command(0x01) # 清屏 def write(x, y, str): if x < 0: #LCD1602只有16列,2行显示,小于第0列的数据要做修正 x = 0 if x > 15: #LCD1602只有16列,2行显示,大于第15列的数据要做修正 x = 15 if y <0: #LCD1602只有16列,2行显示,小于第0行的数据要做修正 y = 0 if y > 1: #LCD1602只有16列,2行显示,大于第1行的数据要做修正 y = 1 # 移动光标 addr = 0x80 + 0x40 * y + x #第一行第一位的地址为0x00,加上D7恒为1,所以第一行第一位的地址为0x80 #第二行第一位是0x40,加上D7恒为1,所以第二行第一位的地址为0x80加上0x40,最后为0xC0 send_command(addr) #设置显示位置 for chr in str: send_data(ord(chr)) #发送显示内容 #ord()函数以一个字符(长度为1的字符串)作为参数, #返回对应的 ASCII 数值,或者 Unicode 数值 if __name__ == '__main__': init(0x27, 1) #在树莓派终端上使用命令'sudo i2cdetect -y 1'查询设备地址为0x27 # 第二个参数1表示打开LCD背光,若是0则关闭背光 write(4, 0, 'Hello') #4,0参数指显示的起始位置为第4列,第0行 write(7, 1, 'world!') #7,1参数指显示的起始位置为第7列,第1行 #‘Hello’为要显示的字符串 ``` **第5步:**编写控制程序。先是静态显示内容:第一行显示“Greetings!!”,第二行显示“Welcome here!”,持续2秒。之后动态滚动显示“Thank you for buying Raspberry! ^_^”。 ```Python #!/usr/bin/env python import LCD1602 import time def setup(): LCD1602.init(0x27, 1) # init(slave address, background light) LCD1602.write(0, 0, 'Greetings!!') LCD1602.write(1, 1, 'Welcome here!') time.sl
eep(2) def loop(): space = ' ' greetings = 'Thank you for buying Raspberry! ^_^' greetings = space + greetings while True: tmp = greetings for i in range(0, len(greetings)): LCD1602.write(0, 0, tmp) #当要显示的字符串过长时,会自动在LCD的第二行显示 tmp = tmp[1:] #每次循环去掉字符串首位字符,实现字幕向左移动的效果 time.sl
eep(0.8) LCD1602.clear() def destroy(): pass if __name__ == "__main__": try: setup() while True: loop() except KeyboardInterrupt: destroy() ``` ![](https://cf03.ickimg.com/bbsimages/202005/7290a304937940b94fa077e6091bd623.gif)
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
张国平
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交