【得捷电子Follow me第1期】 5、驱动tft
[复制链接]
本帖最后由 你家吃的 于 2023-6-10 13:14 编辑
- 所需外设:1.8寸tftlcd屏幕,使用st7735s驱动。
如下图所示的小屏幕。
AB78217A669676D389B971DEBD286AD1
大神们写的真好,这么个简简单单的屏幕,玩的花样真好看。
通过大神代码,可证明咱们小屏幕是好使的。
接下来,咱们自己建轮子,学习一下小屏幕的点亮流程。
屏幕排线引脚如下
原理图上引脚接线如下
屏幕对外使用spi串口通信,四线串口。不使用crc校验。
摘一个串口通信时许图
可以看出来,屏幕的spi协议极性为0,相位为0。
- 引脚使用情况如下图:
信号线连接:spi使用芯片的spi0的clk时钟脚(gp2),tx数据输出脚(gp3),cs片选脚(gp5),D16扩展槽里的gp16和gp17,其中gp16作为DC(数据命令),gp17作为reset脚。
- 上电初始化
演示代码如下
from machine import ADC, Pin,SPI
import utime
import time
spi = SPI(0, baudrate=20000000, polarity=0, phase=0, sck=Pin(2), mosi=Pin(3), miso=Pin(4))
dc = machine.Pin(16, Pin.OUT, Pin.PULL_DOWN)
reset = machine.Pin(17, machine.Pin.OUT, machine.Pin.PULL_DOWN)
cs = machine.Pin(5, machine.Pin.OUT, machine.Pin.PULL_DOWN)
#global data
ScreenSize = (128, 160)
# common kit color 5 6 5 16bits
def TFTColor( aR, aG, aB ) :
return ((aR & 0xF8) << 8) | ((aG & 0xFC) << 3) | (aB >> 3)
# Write data to the device int or bytes
def writedata(aData):
dc(1)
cs(0)
spi.write(aData)
cs(1)
#hw reset tft
def Reset():
dc = 0
reset = 1
time.sleep_us(500)
reset = 0
time.sleep_us(500)
reset = 1
time.sleep_us(500)
#init Cmd list
SLPOUT = 0x11
SWRESET = 0x01
FRMCTR1 = 0xB1 #In Normal Mode (Full Colors)
FRMCTR2 = 0xB2 #In Idle Mode (8-colors)
FRMCTR3 = 0xB2 #In Partial Mode + Full Colors
FRMCTR3 = 0xB3
INVCTR = 0xB4
PWCTR1 = 0xC0
PWCTR2 = 0xC1
PWCTR3 = 0xC2
PWCTR4 = 0xC3
PWCTR5 = 0xC4
VMCTR1 = 0xC5
INVOFF = 0x20
MADCTL = 0x36
COLMOD = 0x3A
CASET = 0x2A #调用0x2C 才生效
RASET = 0x2B #调用0x2C 才生效
GMCTRP1 = 0xE0
GMCTRN1 = 0xE1
DISPON = 0x29
NORON = 0x13
RAMWR = 0x2C #Memory Write
#color
BLACK = 0
RED = TFTColor(0xFF, 0x00, 0x00)
BLUE = TFTColor(0x00, 0x00, 0xFF)
#set window
windowLocData = bytearray(4)
colorData = bytearray(2)
#write cmd
def writecommand(cmd) :
dc(0)
cs(0)
spi.write(bytearray([cmd]))
cs(1)
def init():
writecommand(SWRESET)
time.sleep_us(150)
writecommand(SLPOUT)
time.sleep_us(500)#back to led narmal
data3 = bytearray([0x01, 0x2C, 0x2D])
writecommand(FRMCTR1) #In Normal Mode :Frame Rate Control 面板的刷新速度
writedata(data3)
writecommand(FRMCTR2) #In Idle Mode
writedata(data3)
data6 = bytearray([0x01, 0x2c, 0x2d, 0x01, 0x2c, 0x2d])
writecommand(FRMCTR3)
writedata(data6)
time.sleep_us(10)
#reverse set
data1 = bytearray(1)
writecommand(INVCTR) #设置像素反转模式
data1[0] = 0x07
writedata(data1)
#power set
writecommand(PWCTR1)
data3[0] = 0xA2
data3[1] = 0x02
data3[2] = 0x84
writedata(data3)
writecommand(PWCTR2)
data1[0] = 0xC5
writedata(data1)
data2 = bytearray(2)
writecommand(PWCTR3)
data2[0] = 0x0A
data2[1] = 0x00
writedata(data2)
writecommand(PWCTR4)
data2[0] = 0x8A
data2[1] = 0x2A
writedata(data2)
writecommand(PWCTR5)
data2[0] = 0x8A
data2[1] = 0xEE
writedata(data2)
writecommand(VMCTR1) #COM Voltage Control
data1[0] = 0x0E
writedata(data1)
writecommand(INVOFF) #Display Inversion Off (Normal)
writecommand(MADCTL) #设置rgb颜色显示相关 Memory Data Access Control
data1[0] = 0xC0 # 第四位设置 rgb或者bgr显示顺序
writedata(data1)
writecommand(COLMOD) #Interface Pixel Format 5-6-5 262k color
data1[0] = 0x05 #101 5 16-bit/pixel 12(444) 16(565) 18(666)
writedata(data1)
writecommand(CASET) #Column address set.
windowLocData[0] = 0x00
windowLocData[1] = 0x00
windowLocData[2] = 0x00
windowLocData[3] = ScreenSize[0]
writedata(windowLocData)
writecommand(RASET) #Row address set.
windowLocData[3] = ScreenSize[1]
writedata(windowLocData)
dataGMCTRP = bytearray([0x0f, 0x1a, 0x0f, 0x18, 0x2f, 0x28, 0x20, 0x22, 0x1f,
0x1b, 0x23, 0x37, 0x00, 0x07, 0x02, 0x10])
writecommand(GMCTRP1) # Gamma 校准????????? ‘+’polarity
writedata(dataGMCTRP)
dataGMCTRN = bytearray([0x0f, 0x1b, 0x0f, 0x17, 0x33, 0x2c, 0x29, 0x2e, 0x30,
0x30, 0x39, 0x3f, 0x00, 0x07, 0x03, 0x10])
writecommand(GMCTRN1) # Gamma 校准????????? ‘-’polarity
writedata(dataGMCTRN)
time.sleep_us(10)
writecommand(DISPON) #Display On
time.sleep_us(100)
writecommand(NORON) #Normal display on.
time.sleep_us(10)
cs(1)
#Draw a filled rectangle. aStart is the smallest coordinate corne and aSize is a tuple indicating width, height.
def clamp( aValue, aMin, aMax ) :
return max(aMin, min(aMax, aValue))
def setwindowloc(aPos0, aPos1) :
writecommand(CASET)
windowLocData[0] = 0
windowLocData[1] = int(aPos0[0])
windowLocData[2] = 0
windowLocData[3] = int(aPos1[0])
writedata(windowLocData)
writecommand(RASET)
windowLocData[0] = 0
windowLocData[1] = int(aPos0[1])
windowLocData[2] = 0
windowLocData[3] = int(aPos1[1])
writedata(windowLocData)
writecommand(RAMWR)
def setColor(aColor ) :
colorData[0] = aColor >> 8
colorData[1] = aColor
def draw(aPixels ) :
dc(1)
cs(0)
buf1 = bytes(colorData) * 32
for i in range(aPixels//32):
spi.write(buf1)
rest = (int(aPixels) % 32)
if rest > 0:
buf2 = bytes(colorData) * rest
spi.write(buf2)
cs(1)
#aColor 16bits
def fillrect(aStart, aSize, aColor ) :
start = (clamp(aStart[0], 0, ScreenSize[0]), clamp(aStart[1], 0, ScreenSize[1])) #开始的坐标点
end = (clamp(start[0] + aSize[0] - 1, 0, ScreenSize[0]), clamp(start[1] + aSize[1] - 1, 0,ScreenSize[1]))
if (end[0] < start[0]):
tmp = end[0]
end = (start[0], end[1])
start = (tmp, start[1])
if (end[1] < start[1]):
tmp = end[1]
end = (end[0], start[1])
start = (start[0], tmp)
setwindowloc(start, end)
numPixels = (end[0] - start[0] + 1) * (end[1] - start[1] + 1)
setColor(aColor)
draw(numPixels)
# Fill screen with the given color
def fill(aColor = BLACK ) :
fillrect((0, 0), ScreenSize, aColor)
def dramPoint(Pt,Color):
setColor(Color)
start = (Pt[0],Pt[1])
end = (Pt[0]+1,Pt[1]+1)
setwindowloc(start,end)
pixs = 2*2
dc(1)
cs(0)
bufPt = bytes(colorData)*pixs
spi.write(bufPt)
cs(1)
#Ops
print('start show magic')
writecommand(SWRESET)
time.sleep_us(150)
init()
#fill(BLACK)
dramPoint((50,60),RED)
#fill(RED)
学习的过程就是个查阅手册抄人家代码的过程。
手册上有许多的特性,比如反转,循环等命令,本人太菜,没去感受。
代码里仅是初始化,和自己实现了的一个点亮一个像素点的接口。
效果
后续有时间继续补充tft屏幕的点亮更多细节
语法:
bytearray-可变的字节序列
bytes-不可变的字节序列
创建数组结构 dataArr = bytearray([1,2,3,4,5,6])
修改值 dataArr[3] = 3
名词释义:
TB: transmission byte
RA :Row Address
CA : Column Address
SA:Scan Address
FPA: Front Porch BPA: Back Porch
FRMCTR1(0xb1):Frame Rate Control1,Set the frame frequency of the full colors normal mode.Frame rate=fosc/((RTNA x 2 + 40) x (LINE + FPA + BPA +2)),fosc = 850kHz
FRMCTR2(0xb2):Frame Rate Control2,Set the frame frequency of the Idle mode,Frame rate=fosc/((RTNA x 2 + 40) x (LINE + FPB + BPB +2)),fosc = 850kHz
FRMCTR3(0xb3):Frame Rate Control3,1-3 are used in dot inversion mode。4-6 parameter to 6 parameter are used in column inversion mode
MADCTL(36h): Memory Data Access Control,(my,行地址顺序)(mx,列地址顺序)(mv 行列脚换顺序)(ml 垂直刷新顺序,0,从上到下,1,从下到上)(mh 水平刷新顺序,0 从左到右,1从右到左)
|