1201|1

19

帖子

3

TA的资源

一粒金砂(中级)

楼主
 

【得捷电子Follow me第1期】 5、驱动tft [复制链接]

  本帖最后由 你家吃的 于 2023-6-10 13:14 编辑
  1. 所需外设:1.8寸tftlcd屏幕,使用st7735s驱动。
屏幕手册: ZJY180S0800TG01.pdf (875.18 KB, 下载次数: 8) 4.硬件SPI驱动中景园电子1.8寸LCD.pdf (397.99 KB, 下载次数: 4) ST7735.pdf (1.97 MB, 下载次数: 1) ST7735S_v1.3.pdf (2.53 MB, 下载次数: 1)
如下图所示的小屏幕。
 
github找一个好用的st7735s演示代码,演示效果如下。相关文件: MicroPython-ST7735-master.zip (63.74 KB, 下载次数: 4)  

AB78217A669676D389B971DEBD286AD1

大神们写的真好,这么个简简单单的屏幕,玩的花样真好看。

通过大神代码,可证明咱们小屏幕是好使的。

接下来,咱们自己建轮子,学习一下小屏幕的点亮流程。



 屏幕排线引脚如下

 

原理图上引脚接线如下

  屏幕对外使用spi串口通信,四线串口。不使用crc校验。

摘一个串口通信时许图

  可以看出来,屏幕的spi协议极性为0,相位为0。

  1. 引脚使用情况如下图:

 信号线连接:spi使用芯片的spi0的clk时钟脚(gp2),tx数据输出脚(gp3),cs片选脚(gp5),D16扩展槽里的gp16和gp17,其中gp16作为DC(数据命令),gp17作为reset脚。

 

  1. 上电初始化

 

 

演示代码如下

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从右到左)

最新回复

SPI驱动,看着显示效果还不错!   详情 回复 发表于 2023-6-12 13:01
点赞 关注
 
 

回复
举报

7244

帖子

2

TA的资源

版主

沙发
 

SPI驱动,看着显示效果还不错!

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表