本帖最后由 Lily李 于 2025-10-3 09:07 编辑
申请原创
@21小跑堂
在FireBeetle 2 ESP32 P4 开发板上缺少必要的显示器件,为它配上一款占用资源少的OLED屏是一个合理的选择。 为此,可选取I2C接口的OLED屏为驱动目标。驱动方式有2中,即以硬件方式和软件模拟方式,从通用性的角度出发,这里选取的是软件模拟方式。 显示屏与开发板的连接关系为: SDA----GPIO7 SCL----GPIO8 为此,在选取python编程的情况下,其相应的设计前提是导入 Pin 、time及utime。 from machine import Pin import time import utime
此外,为了显示信息的需要还需配置相应的字库支持,其结构如下:
F8X16=[ 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,#0 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,#1 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,#2 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,#3 ...
为了,模拟I2C发送控制信号,所使用的引脚被配置为输出模式: sda_pin = Pin(7, Pin.OUT) scl_pin = Pin(8, Pin.OUT)
模拟I2C处理的相关辅助函数为: - def IIC_Start():
- scl_pin.on()
- utime.sleep_us(1)
- sda_pin.on()
- utime.sleep_us(1)
- sda_pin.off()
- utime.sleep_us(1)
- scl_pin.off()
- utime.sleep_us(1)
-
- def IIC_Stop():
- scl_pin.on()
- utime.sleep_us(1)
- sda_pin.off()
- utime.sleep_us(1)
- sda_pin.on()
- utime.sleep_us(1)
-
- def IIC_Wait_Ack():
- scl_pin.on()
- utime.sleep_us(1)
- scl_pin.off()
- utime.sleep_us(1)
模拟I2C发送字节数据的函数为: - def Write_IIC_Byte(IIC_Byte):
- da=IIC_Byte
- scl_pin.off()
- for i in range(8):
- if (da&0x80):
- sda_pin.on()
- else:
- sda_pin.off()
- utime.sleep_us(1)
- da=da<<1
- scl_pin.on()
- utime.sleep_us(1)
- scl_pin.off()
- utime.sleep_us(1)
发送指令的函数为: - def Write_IIC_Command(IIC_Command):
- IIC_Start()
- Write_IIC_Byte(0x78)
- IIC_Wait_Ack()
- Write_IIC_Byte(0x00)
- IIC_Wait_Ack()
- Write_IIC_Byte(IIC_Command)
- IIC_Wait_Ack()
- IIC_Stop()
发送数据的函数为: - def Write_IIC_Data(IIC_Data):
- IIC_Start()
- Write_IIC_Byte(0x78)
- IIC_Wait_Ack()
- Write_IIC_Byte(0x40)
- IIC_Wait_Ack()
- Write_IIC_Byte(IIC_Data)
- IIC_Wait_Ack()
- IIC_Stop()
选取发送指令或数据的函数为: - def OLED_WR_Byte(dat , cmd):
- if (cmd):
- Write_IIC_Data(dat)
- else:
- Write_IIC_Command(dat)
设置显示位置的函数为: - def OLED_Set_Pos(x, y):
- OLED_WR_Byte(0xb0+y,OLED_CMD)
- OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD)
- OLED_WR_Byte((x&0x0f),OLED_CMD)
实现清除屏幕显示的函数为: - def OLED_Clear():
- for i in range(8):
- OLED_WR_Byte (0xb0+i,OLED_CMD)
- OLED_WR_Byte (0x00,OLED_CMD)
- OLED_WR_Byte (0x10,OLED_CMD)
- for n in range(128):
- OLED_WR_Byte(0,OLED_DATA) #OLED_WR_Byte(0xf0,OLED_DATA)
实现OLED显示屏初始化的函数为: - def OLED_Init():
- Write_IIC_Command(0xAE)
- Write_IIC_Command(0x40)
- Write_IIC_Command(0xb0)
- Write_IIC_Command(0xc8)
- Write_IIC_Command(0x81)
- Write_IIC_Command(0xff)
- Write_IIC_Command(0xa1)
- Write_IIC_Command(0xa6)
- Write_IIC_Command(0xa8)
- Write_IIC_Command(0x1F)
- Write_IIC_Command(0xd3)
- Write_IIC_Command(0x00)
- Write_IIC_Command(0xd5)
- Write_IIC_Command(0xf0)
- Write_IIC_Command(0xd9)
- Write_IIC_Command(0x22)
- Write_IIC_Command(0xda)
- Write_IIC_Command(0x02)
- Write_IIC_Command(0x8d)
- Write_IIC_Command(0x14)
- Write_IIC_Command(0xdb)
- Write_IIC_Command(0x49)
- Write_IIC_Command(0xaf)
实现字符显示的函数为: - def OLED_ShowChar(x,y,chr,Char_Size):
- c=chr
- OLED_Set_Pos(x,y)
- for i in range(8):
- OLED_WR_Byte(F8X16[c*16+i],OLED_DATA)
- OLED_Set_Pos(x,y+1)
- for i in range(8):
- OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA)
实现驱动测试的主程序为: - if(__name__=='__main__'):
- OLED_Init()
- OLED_Clear()
- OLED_ShowChar(0,0,0,16)
- OLED_ShowChar(8,0,1,16)
- OLED_ShowChar(16,0,2,16)
- OLED_ShowChar(0,2,17,16)
- OLED_ShowChar(8,2,18,16)
- OLED_ShowChar(16,2,19,16)
- time.sleep(1000)
经程序运行,其测试效果如图1所示,这样就达到了驱动OLED屏的目标。 图1 测试效果
为丰富显示内容及色彩,还可使用SPI接口的TFT显示屏。
以SPI方式驱动TFT显示屏,需要使用的部分引脚资源图2所示。 图2 引脚资源分配 TFT显示屏与开发板的连接关系为: TFT_CS----GPIO49 TFT_RS----GPIO50 TFT_DC----GPIO52 TFT_MOSI----GPIO29 TFT_SCLK----GPIO28 TFT_BL----GPIO51
为采用硬件驱动方式,要导入SPI、Pin、TFT及字库等,即: from machine import SPI,Pin from ST7735 import TFT from font import sysfont, seriffont, terminalfont import time import math 对相关引脚的设置为: TFT_CLK = const(28) TFT_MOSI = const(29) TFT_DC = const(52) TFT_RST = const(50) TFT_CS = const(49) 在使用显示屏驱动函数的情况下,对显示屏初始化处理为: spi = SPI(1, baudrate=8_000_000, polarity=0, phase=0, bits=8, sck=Pin(TFT_CLK), mosi=Pin(TFT_MOSI), miso=None) tft = TFT(spi, TFT_DC, TFT_RST, TFT_CS)
实现驱动测试的程序为: - def test_fps():
- tft.fill(TFT.BLACK) # 清空屏幕
- frame_count = 1 # 测试 50 帧
- start_time = time.ticks_ms() # 记录开始时间
- for _ in range(frame_count):
- testlines(TFT.RED)
- test()
- tftprinttest()
- end_time = time.ticks_ms() # 记录结束时间
- elapsed_time = (end_time - start_time) / 1000 # 计算总时间 (秒)
- fps = frame_count / elapsed_time # 计算 FPS
- print(f"FPS: {fps:.2f}") # 输出帧率
- test_fps()
经程序执行,其测试效果如图3至图5所示。 图3 字体大小测试
图4 绘制效果测试
图5 字体颜色效果
|