ESP8266+MicroPython development: ESP8266 uses hardware SPI to drive TFT screen (ST7735)

Because the last time the simulated SPI driving the TFT screen was too slow, so this time I used the hardware SPI to drive it. However, when I directly replaced the corresponding SPI interface, I found that the TFT screen driver did not improve because of this, and it was still very full. Then I can only start from the basic functions of coloring corresponding to the flower point and displaying strings. This time I updated most of the functions, so that the speed of biu can be increased in one click.

ESP8266 uses hardware SPI to drive TFT screen

Effect comparison

Software simulation is too slow to cut off
insert image description here

hardware SPI

Regarding this hardware SPI, it is also emphasized in Mircopython that there are two, one of which is used for flash, and users cannot use it, so they can only use the other one. Of course, it is also possible to use software SPI. When using
software SPI, all the IO ports in ESP8266 can be used. First, pay attention to this function, which needs to pass in the bytes type, and then they can be packaged together continuously. The second is to pay attention to the phase and polarity of the SPI initialization, which is judged according to the timing diagram in the chip data sheet.
insert image description here
insert image description here
spi.write

the code

Only the changed code of this part of LCD.py is given here, and others refer to the first article.

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)##显示打开

Project Files

Project Files

Guess you like

Origin blog.csdn.net/darlingqx/article/details/128697286