树莓派基础实验29I2CLCD1602实

白癜风患者QQ群 http://www.dashoubi.org.cn/e/wap/show.php?classid=2&id=233189

一、介绍

众所周知,虽然液晶显示器和其他显示器大大的丰富了人机交互,但他们有一个共同的弱点。当它们连接到控制器时,需要占用大量的IO口,但是一般的控制器没有那么多的外部端口,也限制了控制器的其他功能。因此,开发具有I2C组件的LCD来解决该问题,LCD是一种只用来显示字母、数字、符号等的点阵型液晶模块。

字符型液晶显示模块是由字符型液晶显示屏LCD、控制驱动主电路HD/KS及其扩展驱动电路HD或与其兼容的IC,少量阻、容元件结构件等装配在PCB板上而成。

I2C总线是由PHLIPS发明的一种串行总线。它是一种高性能的串行总线,具有多主机系统所需的总线控制和高速或低速设备同步功能。I2CLCD上的蓝色电位器用于调整背光,以获得更好的显示效果。I2C使用两个双向极漏开路线,串行数据线(SDA)和串行时钟线(SCL),通过电阻上拉。使用的典型电压为5V或3.3V,但允许使用其他电压的系统。

二、组件

★RaspberryPi3主板*1

★树莓派电源*1

★40P软排线*1

★I2CLCD模块*1

★面包板*1

★跳线若干

三、实验原理

树莓派的GPIO端口数量有限,可通过IO扩展芯片增加GPIO的数量,使得树莓派可以适应更多的应用。本实验中的LCD模块有16个管脚,为节省GPIO端口,就使用了一款通过I2C总线扩展IO的芯片,PCF。单个PCF可扩展8个IO,一个I2C总线最多可挂载8个PCF,所以树莓派最多可扩展64个IO。

本实验中的编程原理比较复杂,所以一定要程序和硬件原理结合起来看才易理解。如果不想深度学习底层原理及驱动程序,掌握LCD的函数使用方法就可以了,但若想灵活运用LCD,最好了解一下。

本文是在网上查阅了很多中外资料,汇集诸多大神的智慧,10几天(当然,每天还是要上班的)才整理汇编而成,但仍有很多不懂和错误之处,特别是程序中有一长串“????”注释的地方,请大神们留言指出!

3.1LCD的存储器

LCD里面存储器有三种:CGROM、CGRAM、DDRAM。DDRAM(DisplayDataRAM)就是显示数据RAM,用来寄存待显示的字符代码。共80个字节,其地址和屏幕的对应关系如下,如图:

DDRAM其实就是我们平时说的PC机的显存,如果说我们想要在屏幕上显示我们想要显示的,直接把需要的字符代码送入现实就可以了,很简单就能够在屏幕上显示我们想要显示的。相同的LCD总共存在80个字节的显存,就是DDRAM。遗憾的是LCD显示不出来这么多的字符,正是因为这样,不是每一个写在DDRAM上的字符都能够在显示器上显示出来,一次只能显示16个字符。正是因为这样,我们在程序中可以利用下面的“光标或显示移动指令”使字符慢慢移动到可见的显示范围内,看到字符的移动效果。

那么如何在液晶上显示字符呢,就是把要写入的字符给DDRAM。举个例子,我现在想在屏幕上显示“A”,我就把我要的字符“A”的字符代码41H写入DDRAM的00H地址处然后得到。那我们应该怎么去写入呢,我们在后面进行进一步的阐述。我们下面将要介绍的是A的字模,如图:

上面的图左侧显示的就是“A”的字模数据,上面的图右侧显示“○”代表0,用“■”代表1。这样我们就能够显示出“A”这个字形。

在LCD模块上固化了字模存储器,就是CGROM和CGRAM,HD内置了个常用字符的字模,存于字符产生器CGROM(CharacterGeneratorROM)中,另外还有8个允许用户自定义的字符产生RAM,称为CGRAM(CharacterGeneratorRAM),留给自定义的位置只有8个地址,也就是最多自定义8个符号或者图形。

下图(字模表)说明了CGROM和CGRAM与字符的对应关系。从ROM和RAM的名称我们也可以知道,ROM是早已固化在LCD模块中的,只能读取;但是RAM即可以读又可以写。

若是只要求在屏幕上显示CGROM中已经拥有的字符,那就仅仅需要在DDRAM中写入它的字符代码就可以了;若是想显示的是CGROM中不存在的字符,例如美元的符号,那就只能先在CGRAM中规定,下一步再在DDRAM中写入我们之前自己定义的字符就可以。

上面这个图说明的是5×8点阵和5×10点阵字符的字形和光标的位置。这里我们采用的是5×8点阵,那么定义这样一个字符需要8个字节,每个字节的前3个位没有被使用。

上面这个图说明的是设置CGRAM地址指令。从这个指令的格式中我们可以看出,它共有aaaaaa这6位,一共可以表示64个地址,即64个字节。一个5×8点阵字符共占用8个字节,那么这64个字节一共可以自定义8个字符。也就是说,上面这个图的6位地址中的DB5DB4DB3用来表示8个自定义的字符,DB2DB1DB0用来表示每个字符的8个字节。这DB5DB4DB3所表示的8个自定义字符(0—7)就是要写入DDRAM中的字符代码。

3.2管脚

加装了I2C转接版的LCD,能够同时显示16x02即32个字符。(16列2行)字符型LCD通常有16条引脚线的LCD:

3.3LCD的基本操作及时序

本系列模块内部具有两个8位寄存器:指令寄存器(IR)和数据寄存器(DR)。用户可以通过RS和R/W输入信号的组合选择指定的寄存器,进行相应的操作。下表中列出了组合选择方式:

LCD的基本操作: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高电平有效。

读操作时序图:

写操作时序图:

时序时间参数:

3.4LCD的指令说明

液晶模块内部的控制器共有11条控制指令:

液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。

指令1:清显示,指令码01H,光标复位到地址00H位置。说明:清除屏幕显示内容。光标返回屏幕左上角。执行这个指令时需要一定时间。指令2:光标复位,光标返回到地址00H。说明:光标返回屏幕左上角,它不改变屏幕显示内容。指令3:光标和显示模式设置

I/D=1:写入新数据后光标右移。I/D=0:写入新数据后光标左移。S=1:显示移动。S=0:显示不移动。说明:这里的设置是0x06。

指令4:显示开关控制。

D=1:显示开,D=0:显示关。C=1:光标显示,C=0:光标不显示。B=1:光标闪烁,B=0:光标不闪烁。说明:这里的设置是显示开,不显示光标,光标不闪烁,设置字为0x0c。

指令5:光标或显示移位

说明:在需要进行整屏移动时,这个指令非常有用,可以实现屏幕的滚动显示效果。初始化时不使用这个指令。

指令6:

功能设置命令

×:不关心,也就是说这个位是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。LCD只能用并行方式驱动,不能用串行方式驱动。而并行方式又可以选择8位数据接口或4位数据接口。这里我们选择4位数据接口(D3—D0)。我们的设置是4位数据接口,两行显示,5×8点阵,即0b也就是0x28。(注意:NF是10或11的效果是一样的,都是两行5×8点阵。因为它不能以两行5×10点阵方式进行显示,换句话说,这里用0x28或0x2c是一样的)。

指令7:字符发生器CGRAM地址设置。

指令8:DDRAM地址设置。

说明:这个指令用于设置DDRAM地址。在对DDRAM进行读写之前,首先要设置DDRAM地址,然后才能进行读写。前面我们说过,DDRAM就是LCD的显示存储器。我们要在它上面进行显示,就要把要显示的字符写入DDRAM。同样,我们想知道DDRAM某个地址上有什么字符,也要先设置DDRAM地址,然后将它读出到单片机。

指令9:读忙信号和光标地址

BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据。如果为低电平表示不忙。说明:这个指令用来读取LCD状态。对于单片机来说,LCD属于慢速设备。当单片机向其发送一个指令后,它将去执行这个指令。这时如果单片机再次发送下一条指令,由于LCD速度较慢,前一条指令还未执行完毕,它将不接受这新的指令,导致新的指令丢失。因此这条读忙指令可以用来判断LCD是否忙,能否接收单片机发来的指令。当BF=1,表示LCD正忙,不能接受单片机的指令;当BF=0,表示LCD空闲,可以接收单片机的指令。RS=0,表示是指令;RW=1,表示是读取。这条指令还有一个副产品:即可以得到地址记数器AC的值(addresscounter)。LCD维护了一个地址计数器AC,用来记录下一次读写CGRAM或DDRAM的位置。需要强调的是:这条指令我一次也没有执行成功。很多网友似乎也是这样。好在我们有另外的办法,也就是延时。通过查看每条指令的执行时间,再经过一些试验,可以确定指令的延时。这样就可以在上一条指令执行完毕后再执行下一条指令了。指令10:写数据。

说明:RS=1,数据;RW=0,写。指令执行时,要在DB7—DB0上先设置好要写入的数据,然后执行写命令。

指令11:读数据。

说明:RS=1,数据;RW=1,读。先设置好CGRAM或DDRAM的地址,然后执行读取命令。数据就被读入后DB7—DB0。

3.5初始化

如果电路电源能满足内部RESET电路的如下要求,初始化可自动完成:

如果电路电源不能满足内部RESET电路的要求的话,需要用初始化程序来实现初始化,有8位总线和4位总线两种模式。

8位数据传输模式:

本次实验中使用4位数据传输模式:

3.6DDRAM地址

字符液晶显示可分为上下两部分各16位进行显示,处于不同行时的字符显示地址如下:

按照上面指令8格式所示,由于地址为7位,在写入地址时,第8位D7恒为1。当我们想在指定位置写入内容时,要先指定地址,如在第一行第一位写入,地址位是00H,再加上DB7的1,即80H(),第二行第一位是40H,再加上DB7的1,即C0H(),依次类推。

四、实验步骤

第1步:连接电路。连接电源打开树莓派,显示屏就会亮,同时在第一行显示一排黑方块。如果看不到黑方块或黑方块不明显,请调节可调电阻,直到黑方块清晰显示。如果调节可调电阻还看不到方块,则可能你的连接有问题了,请检查连接,包括检查显示屏的引脚有没有虚焊。

第2步:

PCF模块采用的是I2C(IIC)总线进行通信的,但是在树莓派的镜像中默认是关闭的,在使用该传感器的时候,我们必须首先允许IIC总线通信。

第3步:查询LCD的地址。得出地址为0x27。

pi

raspberrypi:~ls/dev/i2c-*/dev/i2c-1pi

raspberrypi:~sudoi2cdetect-yabcdef00:--------------------------10:--------------------------------20:--------------27----------------30:--------------------------------40:--------------------------------50:--------------------------------60:--------------------------------70:----------------

第4步:编写驱动程序。这里先编写一个LCD.py文件,后面再编写一个python程序引入这个库文件,调用这个文件中的函数实现更复杂的功能。LCD.py文件就相当于是LCD模块的驱动程序,单独编写是为了便于重用。该程序也可以单独运行,会在第一行显示“Hello”,在第二行显示“world!”。

#!/usr/bin/envpythonimporttimeimportsmbus#SMBus(SystemManagementBus,系统管理总线)在程序中导入“smbus”模块BUS=smbus.SMBus(1)#创建一个smbus实例#0代表/dev/i2c-0,1代表/dev/i2c-1,具体看使用的树莓派那个I2C来决定defwrite_word(addr,data):globalBLEN#该变量为1表示打开LCD背光,若是0则关闭背光temp=dataifBLEN==1:temp

=0x08#0x08=,表开背光#buf

=0x08等价于buf=buf

0x08(按位或)else:temp=0xF7#0xF7=,表关闭背光#buf=0xF7等价于buf=buf0xF7(按位与)BUS.write_byte(addr,temp)#这里为什么又一次写入8位??????#write_byte(intaddr,charval)发送一个字节到设备defsend_


转载请注明:http://www.aierlanlan.com/grrz/3259.html

  • 上一篇文章:
  •   
  • 下一篇文章: 没有了