M5Stack/ESP32学习笔记(14)—— StickC的显示屏

      把M5Stack的UIFlow刷成了没有UIFlow的MicroPython以后,我又尝试了把手上的StickC刷成MicroPython。

      StickC使用了一颗型号为ESP32-PICO-D4 (revision 1)的芯片,4M的Flash ROM,没有PSRAM。TFT LCD驱动芯片为ST7735S。留意到了m5stack团队改的Lobo MicroPython似乎是把ST7735的驱动模块给去掉了,所以我使用了原版Lobo MicroPython。

编译过程,同M5Stack类似,但是需要注意:

  • menuconfig的时候需要把ROM大小改为4M
  • 不要打开SPIRAM的支持选项
  • 串口烧写速率不要使用921600,改为115200
  • Use Display module - Enable support for SPI TFT displays 要打开
  • ./BUILD.sh flash之前先./BUILD.sh erase

烧写成功后,用./BUILD.sh monitor就可以观察启动过程了。
注意,刷了Lobo MicroPython后,开关键的复位功能无效了,不过按6秒关机的功能还在。

本来以为Lobo MicroPython自带ST7735的驱动,点亮TFT LCD应该无压力,可惜我想错了。

首先发现StickC的TFT LCD的电源和背光并不是直接接到电源或者由GPIO控制的,而是由AXP192输出和控制的。所以,首先要对AXP192操作,打开TFT LCD的电源和背光。

import machine
i2c=machine.I2C(0,sda=21,scl=22)
i2c.writeto(0x34,'\x10\xff')  # OLED_VPP Enable
i2c.writeto(0x34,'\x28\xff')  # Enable LDO2&LDO3, LED&TFT 3.3V
i2c.writeto(0x34,'\x12\x4d')  # Enable DC-DC1, OLED_VDD, 5B V_EXT

在REPL执行下列命令后,(注意:miso其实可以随意指定)

import display
tft = display.TFT()
tft.init(tft.ST7735, width=80, height=160, speed=10000000, rst_pin=18, miso=19, mosi=15, clk=13, cs=5, dc=23 , bgr=0x08)

没显示。

又试了下面两个

import display
tft = display.TFT()
tft.init(tft.ST7735R, width=80, height=160, speed=10000000, rst_pin=18, miso=19, mosi=15, clk=13, cs=5, dc=23 , bgr=0x08)
import display
tft = display.TFT()
tft.init(tft.ST7735B, width=80, height=160, speed=10000000, rst_pin=18, miso=19, mosi=15, clk=13, cs=5, dc=23 , bgr=0x08)

倒是有显示了,但是有一半花屏,颜色也不对。

好吧,比较麻烦了。 花了很多时间看了ST7735S的资料,又研究了M5StickC的Arduino库,得出如下解决方法。

# Init. AXP192 for TFT LCD
import machine
i2c=machine.I2C(0,sda=21,scl=22)
i2c.writeto(0x34,'\x10\xff')  # OLED_VPP Enable
i2c.writeto(0x34,'\x28\xff')  # Enable LDO2&LDO3, LED&TFT 3.3V
i2c.writeto(0x34,'\x12\x4d')  # Enable DC-DC1, OLED_VDD, 5B V_EXT

# Init. ST7735S
from ustruct import pack
import display
import time

tft = display.TFT()
tft.init(tft.GENERIC, width=80+26, height=160+1, speed=10000000, rst_pin=18, miso=19, mosi=15, clk=13, cs=5, dc=23 , bgr=0x08, color_bits=16)

# ST7735 specific commands used in init.
# be better to use const instead of these
ST7735_NOP     =0x00
ST7735_SWRESET =0x01
ST7735_RDDID   =0x04
ST7735_RDDST   =0x09

ST7735_SLPIN   =0x10
ST7735_SLPOUT  =0x11
ST7735_PTLON   =0x12
ST7735_NORON   =0x13

ST7735_INVOFF  =0x20
ST7735_INVON   =0x21
ST7735_DISPOFF =0x28
ST7735_DISPON  =0x29
ST7735_CASET   =0x2A
ST7735_RASET   =0x2B # PASET
ST7735_RAMWR   =0x2C
ST7735_RAMRD   =0x2E

ST7735_PTLAR   =0x30
#Add
ST7735_VSCRDEF =0x33
ST7735_COLMOD  =0x3A
ST7735_MADCTL  =0x36
ST7735_VSCRSADD =0x37

ST7735_FRMCTR1 =0xB1
ST7735_FRMCTR2 =0xB2
ST7735_FRMCTR3 =0xB3
ST7735_INVCTR  =0xB4
ST7735_DISSET5 =0xB6

ST7735_PWCTR1  =0xC0
ST7735_PWCTR2  =0xC1
ST7735_PWCTR3  =0xC2
ST7735_PWCTR4  =0xC3
ST7735_PWCTR5  =0xC4
ST7735_VMCTR1  =0xC5

ST7735_RDID1   =0xDA
ST7735_RDID2   =0xDB
ST7735_RDID3   =0xDC
ST7735_RDID4   =0xDD

ST7735_PWCTR6  =0xFC

ST7735_GMCTRP1 =0xE0
ST7735_GMCTRN1 =0xE1

tft.tft_writecmd(ST7735_SWRESET)
time.sleep(0.20)
tft.tft_writecmd(ST7735_SLPOUT)
time.sleep(0.5)
tft.tft_writecmddata(ST7735_FRMCTR1, pack(">BBB", 0x01, 0x2C, 0x2D))
tft.tft_writecmddata(ST7735_FRMCTR2, pack(">BBB",  0x01, 0x2C, 0x2D))
tft.tft_writecmddata(ST7735_FRMCTR3, pack(">BBBBBB", 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D))
tft.tft_writecmddata(ST7735_INVCTR , pack(">B", 0x07))
tft.tft_writecmddata(ST7735_PWCTR1 , pack(">BBB", 0xA2, 0x02, 0x84))
tft.tft_writecmddata(ST7735_PWCTR2 , pack(">B", 0xC5))
tft.tft_writecmddata(ST7735_PWCTR3 , pack(">BB", 0x0A,  0x00))
tft.tft_writecmddata(ST7735_PWCTR4 , pack(">BB", 0x8A,  0x2A))
tft.tft_writecmddata(ST7735_PWCTR5 , pack(">BB", 0x8A, 0xEE))
tft.tft_writecmddata(ST7735_VMCTR1 , pack(">B", 0x0E))
tft.tft_writecmd(ST7735_INVOFF )
tft.tft_writecmddata(ST7735_MADCTL , pack(">B", 0xC8))
tft.tft_writecmddata(ST7735_COLMOD , pack(">B", 0x05))
tft.tft_writecmddata(ST7735_CASET  , pack(">BBBB", 0x00, 0x02, 0x00, 0x7F+0x02))
tft.tft_writecmddata(ST7735_RASET  , pack(">BBBB", 0x00, 0x01, 0x00, 0x9F+0x01))
tft.tft_writecmd(ST7735_INVON)
tft.tft_writecmd(ST7735_DISPON)

tft.setwin(26,1,26+79,1+159)
tft.clear(0xff0000)
time.sleep(1)
tft.clear(0x00ff00)
time.sleep(1)
tft.clear(0x0000ff)
tft.text(0,0,'Hello, ')
tft.text(5,16,'World!')

OK!显示没问题了。

这里特别要注意的是:

  • AXP192的部分,只是初始化了TFT LCD相关,还有其他电路相关也要初始化的,这里图方便而没有做
  • tft.init使用tft.GENERIC,然后“手动”初始化过程,这个是关键(参考了Arduino库)
  • tft.init需要注意bgr=0x08, color_bits=16,否则会出现颜色不对的问题
  • tft的x和y有offset(也是之前看到半个花屏的原因),init里面的width和height要加,后面也要tft.setwin,方便使用
  • 初始化命令的定义部分,最好使用const()

结论:

StickC没有PSRAM,也只有4M ROM,用Lobo MicroPython似乎没有什么好处,乖乖用M5 UIFlow的MicroPython(又最新版UIFlow v1.3.3,基于MicroPython v1.11)吧,M5Burner用来刷系统也方便。
StickC用Lobo MicroPython太折腾。

【参考资料】

https://github.com/m5stack/M5StickC/blob/master/src/AXP192.cpp
https://github.com/m5stack/M5StickC/blob/master/src/utility/ST7735_Init.h
https://github.com/m5stack/M5StickC
https://github.com/m5stack/M5-Schematic/blob/master/Core/ST7735S_v1.1.pdf
https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo/blob/master/MicroPython_BUILD/components/micropython/esp32/libs/tft/tftspi.h
https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo/wiki/i2c
https://forum.micropython.org/viewtopic.php?t=5677
https://docs.m5stack.com/#/en/api/lcd_m5stickc

你可能感兴趣的:(M5Stack/ESP32学习笔记(14)—— StickC的显示屏)