指甲盖大小的 ESP32S3 SuperMini
指甲盖大小的 ESP32S3 SuperMini
Esp32s3 Supermini是一块仅有指甲盖大小的超级迷你开发板,非常适合开发小东西的。还是我买早了,现在都有自带液晶屏的那种组合一体板了。
- 开启芯片内部的虚拟串口
因为这块板子为了追求小体积,所以直接把常规的串口芯片给省略了,而是改用芯片内部自带的虚拟串口,因此我们在操作之前要先把虚拟串口的功能激活起来。否则很可能会造成程序虚假写入的现象,就是表面上看我们已经把程序成功写入到芯片了,但是程序没有跑起来(根本就没有成功写入到芯片内部)
我们在Arduino IDE 中编写一个串口打印消息和闪烁板载LED等的程序(这个板载LED灯是TypeC插口旁边红色的LED,连接的是芯片的第48号端口)
我们选择芯片类型为“ESP32S3 Dev Momule”,注意芯片三叔的选择设置,一定要把“USB CDC On Boot”设置为“Enable”激活状态。然后把程序烧写到开发板中,就可以看到串口回传的打印消息、LED灯不断闪烁了。

二.写入micropython固件
从micropython.org官网中下载固件,注意下载ESP32S3下面的4M存储的固件就可以,下载完成后,就可以用乐鑫的烧写软件 flash_download_tools.exe软件,把固件烧写到芯片中了。
把固件烧写到芯片后,需要拔出芯片,再重新插入,打开thonny(注意了,需要最新版本的,从官网上下载,否则可能无法识别插入的设备),这样我们就能在设备中看到这块esp32s3 supermini了。

三.Python编程
为了开发效果,我给ESP32S3 Supermini配上一块迷你液晶屏,这款液晶屏是SD1306驱动的64x16的,系统自带的英文字库大小是8x8大小的,所以这款屏幕每行可以显示8个英文字符,一共显示2行。
我们把开发板插入到电脑中,打开Thonny编辑软件,就可以编写这个屏幕的显示驱动程序了。

迷你液晶屏驱动文件源代码: main.py
from machine import I2C, Pin
from ssd1306mini import SSD1306_I2C
import time
def main():
i2c = I2C(1, scl=Pin(9), sda=Pin(8))
oled = SSD1306_I2C(i2c, 0x3c, 64, 16)
oled.show()
time.sleep(2)
oled.fill()
oled.text("Hello", 0, 0)
oled.text("World", 0, 8)
oled.show()
if __name__ == "__main__":
main()
四.迷你液晶屏的显示避坑
这个ssd1306mini.py液晶屏驱动库文件是我自己改编的。这款液晶屏的驱动过程是有一个很大的坑:
这块液晶屏是64x16,但是在芯片的内部,其实用的是128x16的驱动完全一致,软件部分完全一样的。不同的其实是硬件部分,工厂在生产这款液晶屏时,把原来的128个列的控制引脚,取中间的64个列连接到屏幕中,而把两旁的64个列的控制引脚直接忽略了。
因此我们在写这个迷你屏的驱动库是,完全可以参考128x16的标准库来进行修改,这样很快就能写出自己的驱动库文件了

迷你屏的驱动库文件 ssd1306mini.py 的源代码:
## ssd1306mini.py #######################################################
# MicroPython SSD1306 64x16 (128x16)
# ssd1306 64x16的屏幕内部实际上是128x16(仅把其中间的64个控制连接到屏幕上,两边的控制直接忽略)
import time
import framebuf
class SSD1306_I2C():
def __init__(self, i2c, addr=0x3c, width=128, height=16, external_vcc=False):
if width==64:
self.width=128 #强制把64x16更改为128x16
else:
self.width=128
self.height = 16
self.external_vcc = external_vcc
self.i2c = i2c
self.addr = addr
self.buffer = bytearray() # 创建空数据,然后往里面填上256个数据 相当于创建一个有初始值的长度256的字节数组
# 第0页 前面的0——127个数据 真正显示在屏幕上的是中间的 32——95 数据,两边的数据补 0
self.buffer.extend(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
self.buffer.extend(b'\x01\x01\x01\x01\x01\x01\x01\x01\x11\x11\x11\x11\x11\x11\x11\x11\x03\x03\x03\x03\x03\x03\x03\x03\x33\x33\x33\x33\x33\x33\x33\x33\x07\x07\x07\x07\x07\x07\x07\x07\x77\x77\x77\x77\x77\x77\x77\x77\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\xff\xff\xff\xff')
self.buffer.extend(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
# 第1页 后面的128——255个数据 真正显示在屏幕上的是中间的 160——223 数据,两边的数据补 0
self.buffer.extend(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
self.buffer.extend(b'\x01\x01\x01\x01\x01\x01\x01\x01\x11\x11\x11\x11\x11\x11\x11\x11\x03\x03\x03\x03\x03\x03\x03\x03\x33\x33\x33\x33\x33\x33\x33\x33\x07\x07\x07\x07\x07\x07\x07\x07\x77\x77\x77\x77\x77\x77\x77\x77\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\xff\xff\xff\xff')
self.buffer.extend(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
self.framebuf = framebuf.FrameBuffer(self.buffer, 128, 16, framebuf.MONO_VLSB) # 再创建一个128 x 16 的帧缓冲区
self.init_display()
def init_display(self):
for cmd in [
0xAE, # 关闭显示
0x20, 0x00, # 页寻址模式
0xB0, # 设置页起始地址
0xC8, # COM扫描方向
0x00, # 设置低列地址
0x10, # 设置高列地址
0x40, # 设置显示开始行
0x81, 0xFF, # 设置对比度
0xA1, # 段重映射
0xA8, 0x0F, # 设置多路复用率(16-1)
0xD3, 0x00, # 设置显示偏移
0xD5, 0xF0, # 设置显示时钟分频
0xD9, 0x22, # 设置预充电周期
0xDA, 0x02, # 设置COM引脚硬件配置
0xDB, 0x49, # 设置VCOMH
0x8D, 0x14, # 电荷泵设置
0xA4, # 全局显示开启
0xA6, # 正常显示
0xAF # 开启显示
]:
self.write_cmd(cmd)
#self.fill(0)
self.show()
def show(self):
self.write_cmd(0xB0) # 第0页
self.write_cmd(0x10)
self.write_cmd(0x01)
self.write_data(self.buffer[0:96])
self.write_cmd(0xB1) # 第1页
self.write_cmd(0x10)
self.write_cmd(0x01)
self.write_data(self.buffer[128:224])
def write_cmd(self, cmd):
self.i2c.writeto(self.addr, bytearray([0x80, cmd]))
def write_data(self, data):
self.i2c.writeto(self.addr, b'\x40' + data)
def fill(self, col=0):
self.framebuf.fill(col)
def pixel(self, x, y, col):
self.framebuf.pixel(x, y, col)
def scroll(self, dx, dy): # 整个屏幕移动
self.framebuf.scroll(dx, dy)
def text(self, string, x, y, col=1):
self.framebuf.text(string, x+32, y, col)
更多推荐

所有评论(0)