欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

树莓派GPIO驱动ST7735S主控TFT液晶屏显示图片和文字

程序员文章站 2022-05-30 19:35:54
...

本文使用1.8‘’128*160RGB_TFT ST7735S主控的液晶屏来操作

参考blog:http://blog.mangolovecarrot.net/2017/03/05/raspi-study1102

文中使用同类型液晶屏显示了纯色和制作点阵来显示文字,但是这实在是太麻烦了。

本文主要介绍如何使用PIL库来辅助显示,想要了解更多细节建议先看原文。

PIL库的安装

sudo apt-get install python-pil python3-pil

代码

在原作者的代码上增加了两个函数,用于图片的转换(侵删),关于RGB565请看原文

import RPi.GPIO as GPIO
import time
import math
from PIL import Image

cs = 23  # 片选
rs = 17  # 数据 / 命令 切换
sda = 13  # 数据
scl = 19  # 时钟
reset = 27  # 复位


# 传输byte
def setByteData(data):
    # print ""
    # print "S-----------setByte---------------:", hex(data)
    for bit in range(0, 8):
        # 传入的数字从高位到低位依次判断是否为1,若为1则设置高电平,否则设置低电平
        # 判断的方法是先向左移位,把要判断的位移动到最高位然后跟0x80(1000 0000)相与,
        # 如果结果仍然是0x80(1000 0000)就表示最高位是1,否则最高位就是0
        if ((data << bit) & 0x80 == 0x80):
            setBitData(True)
            # print "1",
        else:
            setBitData(False)
            # print "0",
    # print ""
    # print "E-----------setByte---------------"


def setBitData(data):
    GPIO.output(scl, False)
    GPIO.output(sda, data)
    GPIO.output(scl, True)


def write_command(cmd):
    GPIO.output(cs, False)
    GPIO.output(rs, False)
    setByteData(cmd)
    GPIO.output(cs, True)


def write_data(data):
    GPIO.output(cs, False)
    GPIO.output(rs, True)
    setByteData(data)
    GPIO.output(cs, True)


def write_data_16bit(dataH, dataL):
    write_data(dataH)
    write_data(dataL)


def lcd_reset():
    GPIO.output(reset, False)
    time.sleep(0.1)
    GPIO.output(reset, True)
    time.sleep(0.1)


def lcd_init(width, heigh):
    lcd_reset()

    write_command(0x11)  # Exit Sleep
    time.sleep(0.02)
    write_command(0x26)  # Set Default Gamma
    write_data(0x04)
    write_command(0xB1)  # Set Frame Rate
    write_data(0x0e)
    write_data(0x10)
    write_command(0xC0)  # Set VRH1[4:0] & VC[2:0] for VCI1 & GVDD
    write_data(0x08)
    write_data(0x00)
    write_command(0xC1)  # Set BT[2:0] for AVDD & VCL & VGH & VGL
    write_data(0x05)
    write_command(0xC5)  # Set VMH[6:0] & VML[6:0] for VOMH & VCOML
    write_data(0x38)
    write_data(0x40)

    write_command(0x3a)  # Set Color Format
    write_data(0x05)
    write_command(0x36)  # RGB
    write_data(0xc8)

    write_command(0x2A)  # Set Column Address
    write_data(0x00)
    write_data(0x00)
    write_data(0x00)
    write_data(width - 1)
    write_command(0x2B)  # Set Page Address
    write_data(0x00)
    write_data(0x00)
    write_data(0x00)
    write_data(heigh - 1)

    write_command(0xB4)
    write_data(0x00)

    write_command(0xf2)  # Enable Gamma bit
    write_data(0x01)
    write_command(0xE0)
    write_data(0x3f)  # p1
    write_data(0x22)  # p2
    write_data(0x20)  # p3
    write_data(0x30)  # p4
    write_data(0x29)  # p5
    write_data(0x0c)  # p6
    write_data(0x4e)  # p7
    write_data(0xb7)  # p8
    write_data(0x3c)  # p9
    write_data(0x19)  # p10
    write_data(0x22)  # p11
    write_data(0x1e)  # p12
    write_data(0x02)  # p13
    write_data(0x01)  # p14
    write_data(0x00)  # p15
    write_command(0xE1)
    write_data(0x00)  # p1
    write_data(0x1b)  # p2
    write_data(0x1f)  # p3
    write_data(0x0f)  # p4
    write_data(0x16)  # p5
    write_data(0x13)  # p6
    write_data(0x31)  # p7
    write_data(0x84)  # p8
    write_data(0x43)  # p9
    write_data(0x06)  # p10
    write_data(0x1d)  # p11
    write_data(0x21)  # p12
    write_data(0x3d)  # p13
    write_data(0x3e)  # p14
    write_data(0x3f)  # p15

    write_command(0x29)  # Display On
    write_command(0x2C)


def show_single_color(DH, DL, width, heigh):
    for i in range(0, heigh):
        for j in range(0, width):
            write_data_16bit(DH, DL)


def rgb2rgb565(image):
    '''
    将RGB(255,255,255)转换为(31,63,31)
    '''
    rgb565 = []
    w, h = image.size
    for y in range(h):
        for x in range(w):
            r, g, b = image.getpixel((x, y))[:3]
            r = math.ceil(r / 0xFF * 0x1F)
            g = math.ceil(g / 0xFF * 0x3f)
            b = math.ceil(b / 0xFF * 0x1F)
            rgb565.append((r, g, b))

    return rgb565


def show4rgb565(rgb565):
    '''
    将rgb合并后取高低8位用于传输显示
    原文中的RGB565 从高位到低位依次是红、绿、蓝
    但是我所用的屏幕需要蓝、绿、红才能正常显示
    '''
    DH = 0
    DL = 0
    for r, g, b in rgb565:
        h16 = ((b << 6) + g << 5) + r # 蓝、绿、红
        # h16 = ((r << 6) + g << 5) + b # 红、绿、蓝
        DH = (h16 & 0xFF00) >> 8
        DL = h16 & 0x00FF

        write_data_16bit(DH, DL)
    # print(hex(h16),hex(DH), hex(DL))


if __name__ == '__main__':
    try:
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(cs, GPIO.OUT)
        GPIO.setup(rs, GPIO.OUT)
        GPIO.setup(sda, GPIO.OUT)
        GPIO.setup(scl, GPIO.OUT)
        GPIO.setup(reset, GPIO.OUT)

        lcd_init(128, 160) # 屏幕宽、高
        write_command(0x2C)
        image = Image.open('图片路径')
        image = image.resize((128, 160), Image.ANTIALIAS) #修改图片大小 屏幕宽、高
        rgb565 = rgb2rgb565(image)
        show4rgb565(rgb565)

        while True:
            pass

    except KeyboardInterrupt:
        pass

    # 清理GPIO口
    GPIO.cleanup()

连接方式

液晶屏 树莓派
LCD 3.3V(不可以是5V!!)
SCK GPIO19
SDA GPIO13
AO GPIO17
RESET GPIO27
CS GPIO23
GND GND
VCC 3.3V(不可以是5V!!)

运行

将代码复制并修改一个正确的图片路径,并保存到一个文件中,这里文件名为show.py

sudo python show.py

树莓派GPIO驱动ST7735S主控TFT液晶屏显示图片和文字

显示文字

使用PIL的Image、ImageDraw模块能够很快生成带有文字的图片

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

W = 128
H = 160
image = Image.new('RGB', (W, H))
font = ImageFont.load_default() # 加载默认字体
# ImageFont.truetype(font, font_size) 也可以加载本地ttf格式字体 font:文件名 font_size:字体大小
draw = ImageDraw.Draw(image)
draw.rectangle((0, 0, W, H), outline=0, fill=0)
line = 'hello PIL'
draw.text((0, 0), line, font=font, fill=255)

这段代码生成了一个带有hello PIL文字的image对象,像显示图片的方式使用该image就可以了

默认字体
树莓派GPIO驱动ST7735S主控TFT液晶屏显示图片和文字

自定义字体
树莓派GPIO驱动ST7735S主控TFT液晶屏显示图片和文字

自动换行

通过计算文字大小和屏幕大小,进行自动换行,需要注意的是font_obj是一个字体对象,例如

ImageFont.truetype(font, font_size)返回的对象

    def auto_text(text, W, H, font_obj=None):

        if not font_obj:
            font_obj = ImageFont.load_default()
       
        image = Image.new('RGB', (W, H))
        draw = ImageDraw.Draw(image)
        draw.rectangle((0, 0, W, H), outline=0, fill=0)
        line = ''
        top = 0
        max_h = max([font_obj.getsize(c)[1] for c in text])
        for i in range(len(text)):

            t = line + text[i]
            if font_obj.getsize(t)[0] > W:
                draw.text((0, top), line, font=font_obj, fill=255)
                line = text[i]
                top += max_h
                if top >= H:
                    break
            else:
                line = t
        else:
            draw.text((0, top), line, font=font_obj, fill=255)
            
        return image
相关标签: python 电脑硬件