树莓派 python 驱动 lcd tft spi 2.8寸 ili9341 240x320

树莓派 python 驱动 lcd tft spi 2.8寸 ili9341 240x320

1. 驱动效果

娃开车图
在这里插入图片描述

2. 屏幕及接线

屏幕我某宝直接购买的,价钱31.5
在这里插入图片描述
接线图:
在这里插入图片描述

3. python驱动代码

写的不严谨,但是能驱动,作为入门吧。详见注释
代码中,需要先解析图片的每个像素,再spi写入屏幕芯片。解析图片耗时挺长的,见日志输出:

pi@raspberrypi:~ $ python3 ili9341Driver.py
setWindow donw
picReadTimeConsuming = 6.100s , SpiTimeConsuming = 0.128s

具体代码见下:

# coding : UTF-8
import time #用于计算spi刷新整个屏幕所用时长
import RPi.GPIO as GPIO #用于操作引脚
import spidev #树莓派与屏幕的交互协议为SPI,说明见:https://github.com/doceme/py-spidev
from PIL import Image, ImageFont, ImageDraw #用于创建画布,或者读取具体路径下的图片。给图片添加文字。
screenWidth = 320 #屏幕长度
screenHeight = 240 #屏幕宽度
PinDC = 18 #GPIO.BOARD引脚模式,第18号引脚
PinReset = 22  #GPIO.BOARD引脚模式,第22号引脚
PinLED=12 #GPIO.BOARD引脚模式,第12号引脚

def LCDReset(): #重置电平时序
    GPIO.output(PinReset, 1)
    time.sleep(.2)
    GPIO.output(PinReset, 0)
    time.sleep(.2)
    GPIO.output(PinReset, 1)
    time.sleep(.2)
    
def sendCommand(command, *bytes): #发送指令(DC为低电平)和数据(DC为高电平)
    GPIO.output(PinDC, 0)
    spi.writebytes([command])
    if len(bytes) > 0:
        GPIO.output(PinDC, 1)
        spi.writebytes(list(bytes))
        
def sendManyBytes(bytes): #发送屏幕数据
    GPIO.output(PinDC, 1)
    spi.writebytes(bytes)
    
def init(): #屏幕初始化
    GPIO.output(PinLED, 1) #LED.high();
    LCDReset()
    sendCommand(0xEF,0x03,0x80,0x02);
    sendCommand(0xCF,0x00,0XC1,0X30);
    sendCommand(0xED,0x64,0x03,0X12,0X81);
    sendCommand(0xE8,0x85,0x00,0x78);
    sendCommand(0xCB,0x39,0x2C,0x00,0x34,0x02);
    sendCommand(0xF7,0x20);
    sendCommand(0xEA,0x00,0x00);
    sendCommand(0xC0,0x23);   # Power control --VRH[5:0]
    sendCommand(0xC1,0x10);   # Power control # SAP[2:0];BT[3:0]
    sendCommand(0xC5,0x3e,0x28);   # VCM control
    sendCommand(0xC7,0x86);    # VCM control2
    sendCommand(0x36,0x48);    #  Memory Access Control
    sendCommand(0x3A,0x55);
    sendCommand(0xB1,0x00,0x18);
    sendCommand(0xB6,0x08,0x82,0x27);    #  Display Function Control
    sendCommand(0xF2,0x00);             #  3Gamma Function Disable
    sendCommand(0x26,0x01);    # Gamma curve selected
    sendCommand(0xE0,0x0F,0x31,0x2B,0x0C,0x0E,0x08,0x4E,0xF1,0x37,0x07,0x10,0x03,0x0E,0x09,0x00);    # Set Gamma
    sendCommand(0xE1,0x00,0x0E,0x14,0x03,0x11,0x07,0x31,0xC1,0x48,0x08,0x0F,0x0C,0x31,0x36,0x0F);    # Set Gamma
    sendCommand(0x11);   # Exit Sleep
    sendCommand(0x29);    # Display on
    
def setWindow():
    sendCommand(0x2A);       # Column addr set
    x0 = 0;
    bytes = []
    bytes.append(x0 >> 8)
    bytes.append(x0)
    sendManyBytes(bytes);              # XSTART
    x1 = screenHeight - 1;
    bytes = []
    bytes.append(x1 >> 8)
    bytes.append(x1)
    sendManyBytes(bytes);       # XEND
    sendCommand(0x2B);      # Row addr set
    bytes = []
    bytes.append(0 >> 8)
    bytes.append(0)
    sendManyBytes(bytes);           # YSTART
    y1 =  screenWidth - 1;
    bytes = []
    bytes.append(y1 >> 8)
    bytes.append(y1)
    sendManyBytes(bytes);       # YEND
    sendCommand(0x2C);
    print('setWindow donw')
    
def drawImg16BitColor(img320x240): #入参为320x240像素的image对象
    init()
    setWindow();
    bytes = []
    i = 0;
    GPIO.output(PinDC, 1)
    picReadStartTime = time.time()
    for x in range(0, screenWidth):
        for y in range(screenHeight - 1, -1, -1):
            colorValue = img320x240.getpixel((x, y))
            red = colorValue[0]
            green = colorValue[1]
            blue = colorValue[2]
            red = red >> 3;  # st7735s的红色占5位
            green = green >> 2;  # st7735s的绿色占6位
            blue = blue >> 3;  # st7735s的蓝色占5位
            highBit = 0 | (red << 3) | (green >> 3);  # 每个像素写入个字节,highBit高字节,lowBit低字节
            lowBit = 0 | (green << 5) | blue;
            bytes.append(highBit)
            bytes.append(lowBit)
    picReadTimeConsuming = time.time() - picReadStartTime #解析图像像素时长
    
    startTime = time.time()
    # screenWidth*screenHeight*2 每个像素写入2个字节。
    #以下for循环是为了控制每次传入的数组长度,防止这个报错,:OverflowError: Argument list size exceeds 4096 bytes.
    for j in range(2000, screenWidth * screenHeight * 2, 2000):  
        sendManyBytes(bytes[i:j])
        i = i + 2000
    sendManyBytes(bytes[i:screenWidth * screenHeight * 2])
    SpiTimeConsuming = time.time() - startTime #Spi写入像素数据时长
    print("picReadTimeConsuming = %.3fs , SpiTimeConsuming = %.3fs" % (picReadTimeConsuming, SpiTimeConsuming))

GPIO.setmode(GPIO.BOARD) #设置GPIO.BOARD引脚模式
GPIO.setwarnings(False)
GPIO.setup(PinDC, GPIO.OUT)
GPIO.setup(PinReset, GPIO.OUT)
GPIO.setup(PinLED, GPIO.OUT)
spi = spidev.SpiDev() #https://github.com/doceme/py-spidev
spi.open(0, 0) 
spi.max_speed_hz = 24000000 #通信时钟最大频率
spi.mode = 0x00 #SPI的模式,9341为模式spi0

image = Image.new('RGB', (screenWidth, screenHeight)) #可以使用代码新建画布

draw = ImageDraw.Draw(image)
setFont = ImageFont.truetype("/usr/share/fonts/myfont/MSYHBD.TTF", 32) #字体地址,请参考我这篇内容:https://blog.csdn.net/chenqide163/article/details/106933858
draw.text((35, 0), "离思", font=setFont, fill="#FFA500", direction=None)
setFont = ImageFont.truetype("/usr/share/fonts/myfont/MSYHBD.TTF", 16)
draw.text((105, 15), "元稹", font=setFont, fill="#00FFFF", direction=None)
setFont = ImageFont.truetype("/usr/share/fonts/myfont/MSYHBD.TTF", 20)
draw.text((0, 35), "曾经沧海难为水,", font=setFont, fill="#FFFF00", direction=None)
draw.text((0, 60), "除却巫山不是云。", font=setFont, fill="#FFFF00", direction=None)
draw.text((0, 85), "取次花丛懒回顾,", font=setFont, fill="#FFFF00", direction=None)
draw.text((0, 110), "半缘修道半缘君。", font=setFont, fill="#FFFF00", direction=None)
#也可以从地址读取图片文件,并缩放为320x240
image = Image.open('/home/pi/test.jpg');
image = image.convert('RGBA'); 
image = image.resize((screenWidth, screenHeight))  #也可以从地址读取图片文件,并缩放为160x128

drawImg16BitColor(image)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值