由于上次模拟SPI驱动TFT屏幕太慢,所以,本次采用硬件SPI来进行驱动,但是,当我直接把对应SPI接口更换时,发现TFT屏幕驱动并没有因此得到好转,依然是非常的满,然后只能从对应花点铺色,显示字符串这些基础函数进行下手了,这次我把大部分函数都更新了一下,让速度biu的一下就上来了。
ESP8266使用硬件SPI驱动TFT屏幕
- 效果比较
- 硬件SPI
- 代码
- 工程文件
效果比较
软件模拟实在太慢剪掉了
硬件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)##显示打开
工程文件
工程文件