一起玩转树莓派(11)——使用LCD屏(二)

本文涉及的产品
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 1个月
数据传输服务 DTS,同步至SelectDB 1个月
简介: 一起玩转树莓派(11)——使用LCD屏

二、带I2C模块的LCD 1602


前面我们说过,LCD1602有16个引脚。原则上我们已经可以使用树莓派来控制显示屏的显示了,但是16个引脚全部连接到树莓派会使接线十分的复杂,而且程序代码的编写也非常繁琐,要对太多的GPIO引脚进行操作,十分不便。本次实验,我们采用的是带I2C模块的LCD元件,I2C模块本身将一些独立的功能进行了封装,通过I2C模块,我们可以以8位数据为标准来传输任何我们想要执行的指令或让LCD显示的字符,非常方便。


image.png


如上图所示,有了IC2模块的LCD1602元件,只需要4个引脚即可实现显示功能。下面我们来分析下如何使用此I2C模块。


首先关于I2C通信的相关内容,之前博客已经有详细的介绍,这里不再赘述。我们先来介绍下为何通过4个引脚通过I2C总线传输8位的数据集合实现所有功能。


LCD引脚1与引脚2:用I2C模块的电源引脚和接地引脚代替。


LCD引脚15和引脚16:LCD的这两个引脚功能为控制背光,此逻辑被封装进了I2C模块中,I2C模块每次写入的8位数据中的第4位用来控制背光。


LCD的引脚3:LCD的此引脚用来设置显示的对比度,在I2C模块中,通过一个可调节的电阻来实现此功能,在后面的实验中如果发现屏幕显示不清,可以尝试调节此电阻器。


LCD的引脚4,引脚5和引脚6:这几个功能引脚也被封装进了I2C模块中,I2C模块每次写入的8位数据中的第1位,的2位和第3位分别用来控制这些引脚。


LCD剩下的数据引脚的数据由I2C传输的8位数据中的高4位来对应,在LCD的8位数据模式下,I2C分两次传输一次完整的数据,前传输的4位为LCD所需数据的低4位,后传输的数据为LCD所需数据的高4位。在LCD的4位数据模式下,因为LCD需要获取到完整的8位数据,因此也需要通过两次数据传输,只是此时先传输的数据为LCD所需数据的高4位,后传输的数据为LCD所需数据的低4位,这点需要特别注意。


下面总结了I2C在传输数据时每一位的意义:


第8位 第7位 第6位 第5位 第4位 第3位 第2位 第1位

数据/指令 数据/指令 数据/指令 数据/指令 背光控制位 Enable控制位 RW控制位 RS控制位

三、编码实验


   使用I2C模块封装的LCD1602只有4个引脚,接线非常简单,如下:


LCD 树莓派

GND GND

VCC +5V

SDA 树莓派SDA功能引脚

SCL 树莓派SCL功能引脚

将LCD1602与树莓派连接完成后,在树莓派的终端执行如下指令查看I2C设备:


sudo i2cdetect -y 1

输出入下图所示:


image.png


可以看到,目前我们只连接了一个I2C设备,设备号为27。


   由于背光的控制位相对独立,我们封装单独的函数来处理,如下:


# 是否开启背光 由PCF8574T的低4位中的第4位决定

BLEN = 1

# 补充背光控制位

def addBlenControl(data):

   global BLEN

   tmpData = data

   if BLEN:

       # 将第4位背光控制位强制设置1

       tmpData = data | 0b00001000

   else:

       # 将第4位背光控制位强制设置为0

       tmpData = data & 0b11110111

   return tmpData    

同理,可以将Enable位的控制,RS位的控制都封装成函数:


# 补充Enable控制位

def addEnableControl(data, high):

   tempData = data

   # 第3位控制Enable

   if high:

       tempData |= 0b00000100

   else:

       tempData &= 0b11111011

   return tempData


# 补充RS控制位

def addRSControl(data, high):

   tempData = data

   # 第1位控制RS

   if high:

       tempData |= 0b00000001

   else:

       tempData &= 0b11111110

   return tempData

在向I2C发送数据前,根据配置的背光设置来决定背光控制位的值:


# 通过I2C总线写入数据

def writeI2C(addr, data):

   # 添加背光控制

   temp = addBlenControl(data)

   # 写数据到I2C总线

   BUS.write_byte(addr ,temp)

准备好了这些工具函数,我们只需要根据LCD1602的指令手册来设置具体的功能,发送要展示的数据即可,完整的代码如下:


#coding:utf-8

import time

import smbus

BUS = smbus.SMBus(1)

# LCD屏幕的硬件地址

LCD_ADDR = 0x27

# 是否开启背光 由PCF8574T的低4位中的第4位决定

BLEN = 1


# 补充背光控制位

def addBlenControl(data):

   global BLEN

   tmpData = data

   if BLEN:

       # 将第4位背光控制位强制设置1

       tmpData = data | 0b00001000

   else:

       # 将第4位背光控制位强制设置为0

       tmpData = data & 0b11110111

   return tmpData    


# 补充Enable控制位

def addEnableControl(data, high):

   tempData = data

   # 第3位控制Enable

   if high:

       tempData |= 0b00000100

   else:

       tempData &= 0b11111011

   return tempData


# 补充RS控制位

def addRSControl(data, high):

   tempData = data

   # 第1位控制RS

   if high:

       tempData |= 0b00000001

   else:

       tempData &= 0b11111110

   return tempData


# 通过I2C总线写入数据

def writeI2C(addr, data):

   # 添加背光控制

   temp = addBlenControl(data)

   # 写数据到I2C总线

   BUS.write_byte(addr ,temp)


# 发送指令到LCD1602

def sendCommand(comm):

   # comm高4位数据传输

   # 低4位先清空

   buf = comm & 0b11110000

   # 先将Enable置为高电平

   buf = addEnableControl(buf, 1)

   # 设置为指令模式

   buf = addRSControl(buf, 0)

   # 写入指令

   writeI2C(LCD_ADDR ,buf)

   time.sleep(0.002)

   # 将Enable置为低电平 使产生低电平跳变来执行指令

   buf = addEnableControl(buf, 0)          

   writeI2C(LCD_ADDR ,buf)

 

   # comm低4位数据传输

   # 高4位先清空 并将低4位的数据移动到高4位

   buf = (comm & 0b00001111) << 4

   # 当次指令的低4位用来 做enable re rew的控制

   # 先将Enable置为高电平

   buf = addEnableControl(buf, 1)

   writeI2C(LCD_ADDR ,buf)

   time.sleep(0.002)

   # 将Enable置为低电平 使产生低电平跳变来执行指令

   buf = addEnableControl(buf, 0)    

   writeI2C(LCD_ADDR ,buf)


# 发送数据到LCD

def sendData(data):

   # data高4位数据传输

   # 低4位先清空

   buf = data & 0b11110000

   # 先将Enable置为高电平

   buf = addEnableControl(buf, 1)

   # 设置为数据模式

   buf = addRSControl(buf, 1)  

   writeI2C(LCD_ADDR ,buf)

   time.sleep(0.002)

   # 将Enable置为低电平 使产生低电平跳变来执行指令

   buf = addEnableControl(buf, 0)  

   writeI2C(LCD_ADDR ,buf)

 

   # data低4位数据传输

   buf = (data & 0b00001111) << 4

   # 先将Enable置为高电平

   buf = addEnableControl(buf, 1)

   # 设置为数据模式

   buf = addRSControl(buf, 1)

   writeI2C(LCD_ADDR ,buf)

   time.sleep(0.002)

   # 将Enable置为低电平 使产生低电平跳变来执行指令

   buf = addEnableControl(buf, 0)  

   writeI2C(LCD_ADDR ,buf)


# 初始化方法

def initLCD():

   # 启动时,LCD1602为8位模式 I2C传输数据时先传输的为低位数据

   # 因此实际上的指令为 0b00100011

   # 为指令6 将LCD1602设置为4位总线模式

   sendCommand(0b00110010)

   time.sleep(0.005)


   # 之后的指令都是4位总线模式

   sendCommand(0b00110010)

   time.sleep(0.005)

   # 指令4 设置屏幕开启,无光标,无闪烁

   sendCommand(0b00001100)

   time.sleep(0.005)

   # 指令1 清屏

   sendCommand(0b00000001)


# 设置屏幕要展示的文案 x,y确定位置

def printLCD(x, y, str):

   # 2行 16 列

   if x < 0:

       x = 0

   if x > 15:

       x = 15

   if y <0:

       y = 0

   if y > 1:

       y = 1

   # 指令7 设置数据要展示的位置

   addr = 0b10000000 + 0b00000100 * y + x

   sendCommand(addr)

   # 开始发送字符数据到LCD1602的数据寄存器

   for chr in str:

       # ord函数可以获取字符的ascil

       sendData(ord(chr))

# 主程序

initLCD()

printLCD(0, 0, 'Hello, world!')

time.sleep(2)

sendCommand(0b00000001)

time.sleep(0.002)

printLCD(0, 0, 'Love China!')

time.sleep(2)

sendCommand(0b00000001)

time.sleep(0.002)

printLCD(0, 0, 'Great Raspberry!')

如上代码所示,所有的指令都采用的二进制的方式,便于对比指令手册进行理解。更多时候我们会采用十六进制数字来编写指令,这样会使代码看的干净很多。上面的示例代码是一个简单的应用程序,运行后可以直接在LCD屏幕上展示3句话:


Hello World!

Love China!

Great Raspberry!

其实此程序也是一个完整的LCD1602驱动,初始化完成后,我们可以通过其提供额sendData方法来实现各种各样的显示需求。效果如下图所示:

image.png

相关实践学习
自建数据库迁移到云数据库
本场景将引导您将网站的自建数据库平滑迁移至云数据库RDS。通过使用RDS,您可以获得稳定、可靠和安全的企业级数据库服务,可以更加专注于发展核心业务,无需过多担心数据库的管理和维护。
Sqoop 企业级大数据迁移方案实战
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
目录
相关文章
|
监控 物联网 API
【.NET+MQTT】.NET6 环境下实现MQTT通信,以及服务端、客户端的双边消息订阅与发布的代码演示
MQTT广泛应用于工业物联网、智能家居、各类智能制造或各类自动化场景等。MQTT是一个基于客户端-服务器的消息发布/订阅传输协议,在很多受限的环境下,比如说机器与机器通信、机器与物联网通信等。好了,科普的废话不多说,下面直接通过.NET环境来实现一套MQTT通信demo,实现服务端与客户端的双边消息发布与订阅的功能和演示。
1925 0
【.NET+MQTT】.NET6 环境下实现MQTT通信,以及服务端、客户端的双边消息订阅与发布的代码演示
|
3月前
|
人工智能 安全 程序员
RAG系统大脑调教指南:模型选择、提示设计与质量控保一本通
本文用轻松幽默的方式解密如何在RAG系统中选择、调教和监督生成模型,让它成为一个既聪明又靠谱的知识助手。从模型选择到提示工程再到质量控制,手把手教你如何避开AI的「胡言乱语」陷阱。
170 11
|
传感器 物联网 定位技术
物联网卡:物联网卡不能使用,几招帮您解决!
物联网卡(IoT SIM卡)是为物联网设备(如智能家居设备、智能城市传感器、车载终端等)提供网络连接的重要组件。然而,在使用过程中,用户可能会遇到物联网卡无法使用的情况。以下是一些物联网卡不能使用的常见原因及其解决方法:
|
9月前
|
JSON API 数据格式
Python 请求微店商品详情数据 API 接口
微店开放平台允许开发者通过API获取商品详情数据。使用Python请求微店商品详情API的主要步骤包括:1. 注册并申请API权限,获得app_key和app_secret;2. 确定API接口地址与请求参数,如商品ID;3. 生成签名确保请求安全合法;4. 使用requests库发送HTTP请求获取数据;5. 处理返回的JSON格式响应数据。开发时需严格遵循微店API文档要求。
|
机器人 Linux 异构计算
实例1:控制树莓派板载LED灯闪烁
本文是一个关于如何使用Python编程控制树莓派板载LED灯闪烁的实验教程,涵盖了树莓派的基本概念、LED控制文件的读写操作、Python `open()` 和 `sleep()` 函数的使用方法,以及具体的实验步骤和代码实现,目的是让读者通过实践熟悉树莓派操作和Linux文件读写。
463 1
实例1:控制树莓派板载LED灯闪烁
|
机器学习/深度学习 人工智能 安全
AI与旅游业:旅行规划的智能助手
在数字化浪潮中,人工智能(AI)正重塑旅游业。本文探讨了AI如何通过个性化推荐、智能预测与预警、语音交互与虚拟助手、增强现实体验及可持续发展,提升旅行规划的效率、安全性和趣味性,推动旅游业创新与变革。
|
物联网 智能硬件
物联网卡:当物联网设备用卡使用在非物联网设备上会被管控吗
当设备物联网卡被检测到在非物联网设备上使用时,可能会遇到一系列的反应或后果,这主要取决于运营商的政策和物联网卡的设计目的。物联网卡通常是为非物联网设备(如智能家居设备、智能城市基础设施、车联网设备等)设计的,其流量套餐、网络连接速度、服务协议以及费用结构都与普通SIM卡有所不同。以下是一些可能发生的情况:
|
监控 数据可视化 应用服务中间件
Python进行数据可视化(Plotly、Dash)
【6月更文挑战第3天】本文介绍了Python中的数据可视化工具Plotly和Dash,它们用于创建交互式图表和Web应用。首先,通过`pip`安装Plotly和Dash库,然后通过案例展示了如何使用它们创建数据可视化应用。第一个案例是一个简单的销售数据可视化,用户可选择年份查看相应销售数据的条形图。第二个案例增加了交互性,允许用户通过下拉菜单选择产品查看销售趋势。接着,讨论了如何添加样式美化和交互性,使应用更吸引人且易于使用。最后,讲解了如何将Dash应用部署到生产环境,包括使用Gunicorn和Nginx,配置HTTPS,集成用户认证,以及日志记录和错误处理。文章强调了监控和性能优化对于生产
|
传感器 存储 Java
一起玩转树莓派(17)——BMP180数字压力传感器应用
BMP180是一款高级的温度气压传感器,通过测量的气压值也可以计算出当前海拔高度。其压力测量范围为300-1100hPa,对应的海拔高度为正9000m-负500m。工作电压在1.8V到3.6V之间。体积小,精度高,采用I2C接口,使用非常方便。BMP180传感器在GPS导航,天气检测,海拔测量和垂直方向速度检测等方面有广泛的应用。本实验,我们尝试使用树莓派的I2C接口来读取BMP180的温度和气压值,并进行海拔高度的计算。
18352 0
|
Python
Python包 - networkx详细拆解
Python包 - networkx详细拆解
323 0