ESP8266+MicroPython开发:ESP8266使用硬件SPI驱动TFT屏幕(ST7735)

由于上次模拟SPI驱动TFT屏幕太慢,所以,本次采用硬件SPI来进行驱动,但是,当我直接把对应SPI接口更换时,发现TFT屏幕驱动并没有因此得到好转,依然是非常的满,然后只能从对应花点铺色,显示字符串这些基础函数进行下手了,这次我把大部分函数都更新了一下,让速度biu的一下就上来了。

ESP8266使用硬件SPI驱动TFT屏幕

效果比较

软件模拟实在太慢剪掉了
在这里插入图片描述

硬件SPI

关于这个硬件SPI,在Mircopython也是强调,有两个,其中一个用于fllash,用户是不能使用,所以只能使用另外一个。
当然用软件SPI也是可以的,软件SPI在ESP8266中所有的IO口的可以使用
在这里插入图片描述
在这里插入图片描述
使用的时候一是注意在spi.write这个函数中,要传入bytes类型,然后又连续的可以一起打包。
二是注意SPI初始化的相位和极性,这个根据芯片数据手册的时序图来进行判断。

代码

这里只给出LCD.py这本部分改变过的代码,其他的参考第一篇文章。

from time import sleep_ms,time_ns
from machine import Pin,SPI
from struct import pack
from CODE import StringCode8_16
 
class LCD:
    def __init__(self,cs=15,res=12,dc=4,bl=5):
        self.RGB={
    
    'white':[31,63,31],'black':[0,0,0],'red':[31,0,0],'green':[0,63,0],'blue':[0,0,31]
                  ,'yellow':[20,63,0]}
        self.spi=SPI(1, baudrate=80000000, polarity=0, phase=0)
        self.CS=Pin(cs,Pin.OUT)
        self.RES=Pin(res,Pin.OUT)
        self.DC=Pin(dc,Pin.OUT)          
        self.BL=Pin(bl,Pin.OUT)
        self.color=b''
        self.background=b''
        
    def LCD_Send8Data(self,Data=int):
        self.CS.off()
        self.spi.write(pack('B',Data))
        self.CS.on()

    def LCD_Send16Data(self,Data=int):
        self.CS.off()
        self.spi.write(pack('B',Data//255))
        self.spi.write(pack('B',Data%255))
        self.CS.on()
     
    #作用:命令传输
    #参数:
    #Com:传入的命令
    def LCD_SendComm(self,Com):
        self.DC.off()
        self.CS.off()
        self.spi.write(pack('B',Com))
        self.CS.on()
        self.DC.on()
        
    #作用:设置XY范围
    #参数:
    #xs:x的起始范围
    #xe:x的终止范围
    #ys:y的起始范围
    #ye:y的终止范围
    def LCD_SetXY(self,xs,xe,ys,ye):
        self.DC.off()
        self.CS.off()
        self.spi.write(b'*')
        self.CS.on()
        self.DC.on()
        self.CS.off()
        self.spi.write(xs.to_bytes(2,'big'))
        self.spi.write(xe.to_bytes(2,'big'))
        self.CS.on()
        self.DC.off()
        self.CS.off()
        self.spi.write(b'+')
        self.CS.on()
        self.DC.on()
        self.CS.off()
        self.spi.write(ys.to_bytes(2,'big'))
        self.spi.write(ye.to_bytes(2,'big'))
        self.CS.on()
        self.DC.off()
        self.CS.off()
        self.spi.write(b',')
        self.CS.on()
        self.DC.on()

        
    '''
    0  0  0       黑色
    31 63 31      白色
    31 0  0       红色
    0  63 0       绿色
    0  0  31      蓝色
    '''
    #作用:指定范围颜色填充颜色
    #参数:
    #xs:x的起始范围
    #xe:x的终止范围
    #ys:y的起始范围
    #ye:y的终止范围
    #color: 颜色字符串
    #RGB:颜色数组
    def LCD_FullColor(self,xs,xe,ys,ye,color='',RGB=[]):
        if self.RGB.get(color):
            RGB=self.RGB.get(color)
            color=RGB[2]+RGB[1]*32+RGB[0]*2048
            color=color.to_bytes(2,'big')
        else:
            raise ValueError("颜色不在范围内")
        self.LCD_SetXY(xs,xe,ys,ye)
        self.CS.off()
        for i in range(ys,ye+1):
            for i in range(xs,xe+1):
                self.spi.write(color)
        self.CS.on()

    #作用:画一个颜色点
    #参数:
    #x:x的坐标
    #y:y的坐标
    #color: 颜色字符串
    #RGB:颜色数组
    def LCD_DrawPoint(self,x,y,color):
        self.LCD_SetXY(x,x+1,y,y+1)
        self.CS.off()
        self.spi.write(color)
        self.CS.on()

    #作用:指定范围颜色填充颜色
    #参数:
    #xs:x的起始坐标
    #ys:y的起始坐标
    #strcolor: 字体颜色字符串
    #RGB:字体颜色数组
    #background:背景色字符串
    def LCD_WriteString(self,x,y,string=str,strcolor='',background=''):
        color=self.LCD_ChangeColor(strcolor)
        background=self.LCD_ChangeColor(background) 
        for i in range(len(string)):
            self.LCD_SetXY(x+(8*i),x+(8*(i+1))-1,y,y+16)
            self.CS.off()
            line=StringCode8_16.get(string[i])
            for j in range(16):
                var=line[j]
                for k in range(8):
                    if var&0x01==0x01:
                        self.spi.write(color)
                    elif background != b'':
                        self.spi.write(background)
                    var >>=1
            self.CS.on()    
    
    #作用:计算颜色转化为bytes类型
    #参数:
    #color:颜色
    def LCD_ChangeColor(self,color='',background=''):
        if self.RGB.get(color):
            RGB=self.RGB.get(color)
            color=RGB[2]+RGB[1]*32+RGB[0]*2048
            color=color.to_bytes(2,'big')
        return color
        
    '''
    (xs,ys)------(xe,ys)
    |             |
    |             |
    |             |
    |             |
    |             |
    (xs,ye)------ (xe,ye)
    '''
    #作用:画矩形
    #参数:
    #xs:左上点x坐标
    #ys:左上点y坐标
    #xe:右上点x坐标
    #ye:右上点y坐标
    #size:大小
    #color: 颜色字符串
    #RGB:颜色数组
    def LCD_DrawRect(self,xs,ys,xe,ye,color=''):
        color=self.LCD_ChangeColor(color)
        self.LCD_DrawLine(xs,ys,xe,ys,color)
        self.LCD_DrawLine(xe,ys,xe,ye,color)
        self.LCD_DrawLine(xe,ye,xs,ye,color)
        self.LCD_DrawLine(xs,ye,xs,ys,color)
        

    #作用:交换x1,x2位置
    #参数:    
    #x1:数一
    #x2:数二
    def Change_num(self,x1,x2):
        if x1>x2:
            return x2,x1
        else:
            return x1,x2

    #作用:画直线
    #参数:
    #xs:起始点x坐标
    #ys:起始点y坐标
    #xe:结束点x坐标
    #ye:结束点y坐标
    #size:大小
    #color: 颜色字符串
    #RGB:颜色数组
    def LCD_DrawLine(self,xs,ys,xe,ye,color=''):
        xs,xe=self.Change_num(xs,xe)
        ys,ye=self.Change_num(ys,ye)
        color=self.LCD_ChangeColor(color)
        if xs==xe:
            for j in range(ys,ye):
                self.LCD_DrawPoint(xs,j,color)
        elif ys==ye:
            for i in range(xs,xe):
                self.LCD_DrawPoint(i,ys,color)
        else:
            tan=(ye-ys)/(xe-xs)
            for i in range(xs,xe):
                self.LCD_DrawPoint(i,ys+int(i*tan),color)

    #作用:显示RGB图片
    #参数:
    #x:起始点x坐标
    #y:起始点y坐标
    #w:图片宽
    #h:图片高
    #img: 要显示的图片
    def LCD_ShowRGBImage(self,x,y,w,h,img):
        self.LCD_SetXY(x,y,x+w,y+h)
        k=0
        self.CS.off()
        for i in range(h):
            for j in range(w):
                k+=1
                self.spi.write(img[2*k].to_bytes(1,'big'))
                self.spi.write(img[2*k+1].to_bytes(1,'big'))
        self.CS.on()

    #作用:显示点阵图片
    #参数:
    #x:起始点x坐标
    #y:起始点y坐标
    #w:图片宽
    #h:图片高
    #img: 要显示的图片
    def LCD_ShowPointImage(self,x,y,w,h,img,color='',background=''):
        color=self.LCD_ChangeColor(color)
        background=self.LCD_ChangeColor(background) 
        self.LCD_SetXY(x,x+w+3,y,y+h)
        i=0
        self.CS.off()
        lenth=len(img)
        while i<lenth:
            var=img[i]
            for j in range(8):
                if var&0x80==0x80:
                    self.spi.write(color)
                elif self.background != b'':
                    self.spi.write(background)
                var <<=1            
            i+=1
        self.CS.on()

    #作用:初始化
    #参数:
    #inversion:颜色反转
    def LCD_init(self,mode=0,inversion=False):
        self.CS.off()
        self.RES.on()
        sleep_ms(50)
        self.RES.off()
        sleep_ms(50)
        self.RES.on()
        sleep_ms(150)
        self.CS.on()
        self.LCD_SendComm(0X01)
        sleep_ms(130)
        
        self.BL.on()#打开背光
        self.LCD_SendComm(0X11)##退出睡眠模式
        self.LCD_SendComm(0x13)#普通模式全屏显示
        if inversion:
            self.LCD_SendComm(0x21)#颜色反转
        else:
            self.LCD_SendComm(0x20)#颜色不反转
        self.LCD_SendComm(0x38)#怠速模式关闭
        self.LCD_SendComm(0x3a)#改变颜色模式
        self.LCD_Send8Data(5)#16位颜色
        self.LCD_SendComm(0x34)
        self.LCD_SendComm(0xb4)
        self.LCD_Send8Data(0x00)
        self.LCD_SendComm(0x36)
        if mode==0 :
            self.LCD_Send8Data(0x00);
        elif mode==1:
            self.LCD_Send8Data(0xC0);
        elif mode==2:
            self.LCD_Send8Data(0x70);
        else :
            self.LCD_Send8Data(0xA0);         
        self.LCD_SendComm(0x29)##显示打开

工程文件

工程文件

猜你喜欢

转载自blog.csdn.net/darlingqx/article/details/128697286