Lily李 发表于 2025-10-3 08:42

FireBeetle 2 ESP32 P4 开发板的显示屏驱动

本帖最后由 Lily李 于 2025-10-3 09:07 编辑

申请原创
@21小跑堂

在FireBeetle 2 ESP32 P4 开发板上缺少必要的显示器件,为它配上一款占用资源少的OLED屏是一个合理的选择。为此,可选取I2C接口的OLED屏为驱动目标。驱动方式有2中,即以硬件方式和软件模拟方式,从通用性的角度出发,这里选取的是软件模拟方式。显示屏与开发板的连接关系为:SDA----GPIO7SCL----GPIO8为此,在选取python编程的情况下,其相应的设计前提是导入 Pin 、time及utime。from machine import Pinimport timeimport utime
此外,为了显示信息的需要还需配置相应的字库支持,其结构如下:
F8X16=[0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,#00x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,#10x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,#20x00,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,OLED_DATA)
   OLED_Set_Pos(x,y+1)
   for i in range(8):
      OLED_WR_Byte(F8X16,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----GPIO49TFT_RS----GPIO50TFT_DC----GPIO52TFT_MOSI----GPIO29TFT_SCLK----GPIO28TFT_BL----GPIO51
为采用硬件驱动方式,要导入SPI、Pin、TFT及字库等,即:from machine import SPI,Pinfrom ST7735 import TFTfrom font import sysfont, seriffont, terminalfontimport timeimport 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 字体颜色效果
页: [1]
查看完整版本: FireBeetle 2 ESP32 P4 开发板的显示屏驱动