跳转至

09 u8g2

作者:沈园园 | 最后修改:2026-04-09

一、概述

u8g2 图形处理库是 LuatOS 的显示屏驱动库,支持多种 OLED 和 LCD 单色屏幕,提供丰富的图形绘制功能;

u8g2 库提供了如下几大类功能:

1、显示屏初始化配置:支持I2C、SPI接口的显示屏初始化;

2、基本图形绘制:点、线、圆、矩形等基本图形的绘制;

3、文本显示:支持中英文字体显示,支持UTF-8编码;

4、位图显示:支持XBM格式位图显示;

5、二维码生成:支持二维码生成和显示;

6、高级绘图功能:按钮、椭圆、三角形等复杂图形绘制;

在 LuatOS 中,u8g2 库和 lcd 库都是用于显示驱动的库,而且有些接口和用法类似,但 2 个库还是有本质的差异。

u8g2 专注于单色显示屏驱动,提供了丰富的图形绘制功能,如按钮,圆弧,阴影等等,做 UI 设计相对更简单。同样运行后资源的开销也会比 LCD 核心库更多。

而 lcd 核心库,提供了基本的点、线、矩形、圆形、文字、图片显示功能,色彩更丰富,资源开销相对 u8g2 库较小,能够支持的显示屏分辨率也更大。

二、演示功能概述

2.1 核心主程序模块

  1. main.lua - 主程序入口,负责系统初始化和任务调度
  2. ui_main.lua - 用户界面主控模块,管理页面切换和事件分发

2.2 显示页面模块

  1. home_page.lua - 主页模块,提供应用入口和导航功能
  2. component_page.lua - 组件演示模块,展示进度条和基本图形
  3. default_font_page.lua - 内置字体演示模块,展示U8G2内置字体效果

2.3 驱动模块

  1. hw_default_font_drv.lua - LCD初始化和内置12号英文点阵字体驱动模块
  2. key_drv.lua - 按键驱动模块,管理BOOT键和PWR键

三、按键功能说明

3.1 按键消息

"KEY_EVENT" - 按键事件消息,包含按键类型和状态

  • boot键事件:boot_down(按下)、boot_up(释放)
  • pwr键事件:pwr_down(按下)、pwr_up(释放)

3.2 按键功能定义

  • 主页:boot 键(释放)选择/切换选项,pwr 键(释放)确认
  • 组件演示页面:boot 键(释放)切换选项,pwr 键(释放)确认(返回或进度 +10%)
  • 内置字体页面:boot 键(释放)切换选项(只有一个返回按钮,无实际效果),pwr 键(释放)返回

注意:当前代码中只处理按键的释放事件(boot_up 和 pwr_up),按下事件被忽略。

四、准备硬件环境

1、Air780EPM核心板 × 1

2、st7657 显示屏 × 1 本demo演示使用的屏幕购买链接

3、母对母杜邦线 × 8,杜邦线太长的话,会出现 spi 通信不稳定的现象;

4、TYPE-C 数据线 × 1

5、Air780EPM核心板和 ST7567单色点阵屏的硬件接线方式为

  • Air780EPM核心板通过 TYPE-C USB 口供电(核心板正面开关拨到 ON 一端),此种供电方式下,VBAT 引脚为 3.3V,可以直接给 ST7567单色点阵屏供电;
  • 为了演示方便,所以 Air780EPM核心板上电后直接通过 VBAT 引脚给 ST7567单色点阵屏供电;
  • 客户在设计实际项目时,一般来说,需要通过一个 GPIO 来控制 LDO 给配件板供电,这样可以灵活地控制配件板的供电,可以使项目的整体功耗降到最低;

屏接线

Air780EPM 核心板 st7567
57/U3TXD SCL
28/U2RXD CS
20/GPIO24 RST
29/U2TXD SDA
58/U3RXD DC
22/GPIO1 BL
VBAT VCC
GND GND

五、准备软件环境

5.1 软件环境

在开始实践本示例之前,先筹备一下软件环境:

1、烧录工具:Luatools 下载调试工具

2、本demo开发测试时使用的固件为LuatOS-SoC_V2018_Air780EPM 1号固件,本demo对固件版本没有什么特殊要求,所以你如果要测试本demo时,可以直接使用最新版本的内核固件Air780EPM固件Air780EHM固件;如果发现最新版本的内核固件测试有问题,可以使用我们开发本demo时使用的内核固件版本来对比测试;

3、脚本文件:

  • Air780EPM脚本文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air780EPM/demo/ui/u8g2
  • Air780EHM脚本文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air780EHM_Air780EHV_Air780EGH/demo/ui/u8g2

4、lib脚本文件:使用Luatools烧录时,勾选 添加默认lib 选项,使用默认lib脚本文件

准备好软件环境之后,接下来查看如何烧录项目文件到Air780EPM核心板,将本篇文章中演示使用的项目文件烧录到Air780EPM/Air780EHM核心板中。

5.2 API 介绍

u8g2 图形处理库:https://docs.openluat.com/osapi/core/u8g2/

六、程序结构

ui/u8g2
│── main.lua
│── ui                    
    │── component_page.lua 
    │── default_font_page.lua
    │── home_page.lua
    │── ui_main.lua                               
│── hw_drv 
    │── hw_default_font_drv.lua 
    │── key_drv.lua
│── readme.md

6.1 文件说明

1、main.lua:整个项目的入口点。它负责初始化系统环境

2、ui

  • component_page.lua:组件演示模块,展示进度条和基本图形
  • default_font_page.lua:内置字体演示模块,展示U8G2内置字体效果
  • home_page.lua:主页模块,提供应用入口和导航功能
  • ui_main.lua:用户界面主控模块,管理页面切换和事件分发

3、hw_drv

  • hw_default_font_drv.lua:LCD初始化和内置12号英文点阵字体驱动模块
  • key_drv.lua:按键驱动模块,管理BOOT键和PWR键

七、代码详解

7.1 main.lua

主程序文件 main.lua 是整个项目的入口点。它负责初始化系统环境。

7.2 component_page.lua

本文件为组件演示页面模块,核心业务逻辑为:

1、展示U8G2图形组件的绘制能力;

2、显示进度条和基本图形(圆形、矩形、三角形等);

3、提供进度调整功能和返回首页功能;

4、支持BOOT键和PWR键的导航操作;

local component_page = {}

-- 进度条当前值(0-100)
local progress_value = 30

-- 当前选中按钮的索引(1:返回, 2:+10%)
local selected_index = 1

--[[
@api draw()
@summary 绘制组件演示页面内容
@return 无返回值
@usage
-- 在UI主循环中调用
component_page.draw()
]]
function component_page.draw()
    -- 标题
    u8g2.DrawUTF8("Component Page", 15, 10)

    -- 进度条区域
    u8g2.DrawUTF8("PROG", 0, 25)

    -- 进度条背景(更大)
    u8g2.DrawFrame(45, 15, 50, 12)

    -- 进度条前景
    local fill_width = math.floor(50 * progress_value / 100)
    u8g2.DrawBox(44, 15, fill_width, 12)

    -- 进度文本
    u8g2.DrawUTF8(progress_value .. "%", 100,25)

    -- 图形演示区域
    u8g2.DrawUTF8("GRPX", 0, 40)

    -- 绘制基本图形(增加间距)
    u8g2.DrawCircle(42, 36, 5, u8g2.DRAW_ALL)
    u8g2.DrawDisc(60, 36, 5, u8g2.DRAW_ALL)
    u8g2.DrawFrame(75, 31, 10, 10)
    u8g2.DrawBox(90, 31, 10, 10)
    u8g2.DrawTriangle(105, 40, 110, 30, 115, 40)

    -- 按钮区域(布局更宽松)
    if selected_index == 1 then
        -- 返回按钮:选中状态
        u8g2.DrawButtonUTF8("Back", 20, 58, u8g2.BTN_INV + u8g2.BTN_BW1, 0, 2, 0)
    else
        -- 返回按钮:未选中状态
        u8g2.DrawButtonUTF8("Back", 20, 58, u8g2.BTN_BW1, 0, 2, 0)
    end

    if selected_index == 2 then
        -- +10%按钮:选中状态
        u8g2.DrawButtonUTF8("+10%", 80, 58, u8g2.BTN_INV + u8g2.BTN_BW1, 0, 2, 0)
    else
        -- +10%按钮:未选中状态
        u8g2.DrawButtonUTF8("+10%", 80, 58, u8g2.BTN_BW1, 0, 2, 0)
    end
end

--[[
@api handle_key(key_type)
@summary 处理按键事件,实现进度调整和页面导航
@param string key_type 按键类型,可选值:
  - "confirm":确认键,执行当前选中按钮的功能
  - "next":切换到下一个按钮
  - "prev":切换到上一个按钮
@return bool 是否已处理该按键,true表示已处理
@usage
-- 在UI主循环中调用
local handled = component_page.handle_key("confirm")
]]
function component_page.handle_key(key_type)
    log.info("component_page.handle_key", "key_type:", key_type)

    if key_type == "confirm" then
        -- 确认键:执行当前选中按钮的功能
        if selected_index == 1 then
            -- 返回按钮:返回首页
            switch_page("home")
        elseif selected_index == 2 then
            -- +10%按钮:增加进度值,最大不超过100%
            progress_value = math.min(100, progress_value + 10)
        end
        return true
    elseif key_type == "next" then
        -- 切换到下一个按钮
        selected_index = selected_index % 2 + 1
        return true
    elseif key_type == "prev" then
        -- 切换到上一个按钮
        selected_index = (selected_index - 2) % 2 + 1
        return true
    end

    return false
end

--[[
@api on_enter()
@summary 页面进入时的初始化操作,重置选中项和进度值
@return 无返回值
@usage
-- 在页面切换时自动调用
component_page.on_enter()
]]
function component_page.on_enter()
    -- 页面进入时初始化
    selected_index = 1  -- 默认选中返回按钮
end

--[[
@api on_leave()
@summary 页面离开时的清理操作
@return 无返回值
@usage
-- 在页面切换时自动调用
component_page.on_leave()
]]
function component_page.on_leave()
    -- 页面离开时的清理操作
    -- 当前无需特殊清理
end

return component_page

7.3 default_font_page.lua

本文件为默认字体演示页面模块,核心业务逻辑为:

1、展示U8G2内置字体的显示效果;

2、显示固定文本内容和当前系统时间;

3、提供返回首页的功能;

4、支持BOOT键和PWR键的导航操作;

local default_font_page = {}

-- 当前选中项的索引(仅有一个返回按钮)
local selected_index = 1

--[[
@api draw()
@summary 绘制默认字体演示页面内容
@return 无返回值
@usage
-- 在UI主循环中调用
default_font_page.draw()
]]
function default_font_page.draw()
    -- 标题
    u8g2.DrawUTF8("Font Page", 37, 10)

    -- 字体演示(居中显示)
    u8g2.DrawUTF8("LuatOS Demo", 30, 27)
    u8g2.DrawUTF8("U8G2 Graphics", 25, 42)
    u8g2.DrawUTF8(os.date("%Y-%m-%d %H:%M:%S"), 15, 58)

    -- 按钮区域
    if selected_index == 1 then
        -- 返回按钮:选中状态
        u8g2.DrawButtonUTF8("Back", 5, 10, u8g2.BTN_INV + u8g2.BTN_BW1, 0, 2, 0)
    else
        -- 返回按钮:未选中状态
        u8g2.DrawButtonUTF8("Back", 5, 10, u8g2.BTN_BW1, 0, 2, 0)
    end
end

--[[
@api handle_key(key_type)
@summary 处理按键事件,实现页面导航
@param string key_type 按键类型,可选值:
  - "confirm":确认键,返回首页
  - "next":切换选中状态(仅有一个按钮,无实际效果)
  - "prev":切换选中状态(仅有一个按钮,无实际效果)
@return bool 是否已处理该按键,true表示已处理
@usage
-- 在UI主循环中调用
local handled = default_font_page.handle_key("confirm")
]]
function default_font_page.handle_key(key_type)
    log.info("default_font_page.handle_key", "key_type:", key_type)

    if key_type == "confirm" then
        -- 确认键:返回首页
        switch_page("home")
        return true
    elseif key_type == "next" or key_type == "prev" then
        -- 切换选中项(只有一个按钮,所以切换无实际效果)
        -- 但为了保持接口一致性,仍然返回true表示已处理
        return true
    end

    return false
end

--[[
@api on_enter()
@summary 页面进入时的初始化操作,重置选中项和设置帧更新时间
@return 无返回值
@usage
-- 在页面切换时自动调用
default_font_page.on_enter()
]]
function default_font_page.on_enter()
    -- 页面进入时初始化
    selected_index = 1
    -- 设置较短的帧更新时间,使时间显示能够实时更新
    frame_time = 300  -- 300ms
end

--[[
@api on_leave()
@summary 页面离开时的清理操作,恢复默认帧更新时间
@return 无返回值
@usage
-- 在页面切换时自动调用
default_font_page.on_leave()
]]
function default_font_page.on_leave()
    -- 页面离开时的清理操作
    -- 恢复默认的帧更新时间(60秒)
    frame_time = 60 * 1000
end

return default_font_page

7.4 home_page.lua

本文件为主页显示模块,核心业务逻辑为:

1、显示主菜单,包含两个选项:组件演示、内置字体;

2、处理BOOT键和PWR键的导航和确认操作;

3、管理当前选中项状态;

local home_page = {}

-- 菜单项
local menu_items = {
    {name = "component", text = "1.Component Demo", x = 10, y = 22},
    {name = "default_font", text = "2.Built-in Font", x = 10, y = 40}
}

local selected_index = 1

--[[
@api draw()
@summary 绘制主页内容
@return 无返回值
@usage
-- 在UI主循环中调用
home_page.draw()
]]
function home_page.draw()

    -- 绘制按键提示
    u8g2.DrawUTF8("BOOT:Select", 0, 10)
    u8g2.DrawUTF8("PWR:Confirm", 0, 58)

    -- 绘制菜单项
    for i, item in ipairs(menu_items) do
        if i == selected_index then
            -- 选中状态
            u8g2.DrawButtonUTF8(item.text, item.x, item.y, 
                u8g2.BTN_INV + u8g2.BTN_BW1, 110, 2, 0)
        else
            -- 未选中状态
            u8g2.DrawButtonUTF8(item.text, item.x, item.y, 
                u8g2.BTN_BW1, 110, 2, 0)
        end
    end
end

--[[
@api handle_key(key_type)
@summary 处理按键事件
@param string key_type 按键类型,可选值:"confirm""next""prev"
@return bool 是否已处理该按键
@usage
-- 在UI主循环中调用
home_page.handle_key("confirm")
]]
function home_page.handle_key(key_type)
    log.info("home_page.handle_key", "key_type:", key_type, "selected_index:", selected_index)

    if key_type == "confirm" then
        -- 确认键:切换到选中的页面
        local item = menu_items[selected_index]
        switch_page(item.name)
        return true
    elseif key_type == "next" then
        -- 向下选择
        selected_index = selected_index % #menu_items + 1
        return true
    elseif key_type == "prev" then
        -- 向上选择
        selected_index = (selected_index - 2) % #menu_items + 1
        return true
    end

    return false
end

--[[
@api on_enter()
@summary 页面进入时的初始化操作
@return 无返回值
@usage
-- 在页面切换时自动调用
home_page.on_enter()
]]
function home_page.on_enter()
    selected_index = 1  -- 重置选中项
end

--[[
@api on_leave()
@summary 页面离开时的清理操作
@return 无返回值
@usage
-- 在页面切换时自动调用
home_page.on_leave()
]]
function home_page.on_leave()
    -- 页面离开时的清理操作
end

return home_page

7.5 ui_main.lua

本文件为U8G2图形界面的主控模块,核心业务逻辑为:

1、管理三个页面:主页、组件演示页、内置字体页;

2、处理按键事件并分发给当前页面;

3、控制页面切换逻辑,调用页面的进入/离开回调函数;

4、实现主渲染循环,定期更新屏幕显示;

-- 加载页面
local home_page = require("home_page")
local component_page = require("component_page")
local default_font_page = require("default_font_page")

-- 超时更新画面时间,默认60秒
frame_time = 60 * 1000

-- 页面管理
local PAGE_NAMES = {
    HOME = "home",
    COMPONENT = "component",
    DEFAULT_FONT = "default_font"
}

-- 当前页面
local current_page = PAGE_NAMES.HOME

--[[
@api handle_key_event(key_event)
@summary 处理按键事件
@param string key_event 按键事件类型,可选值:"boot_up""boot_down""pwr_up""pwr_down"
@return bool 是否已处理该按键事件
@usage
-- 在主循环中调用
handle_key_event("boot_up")
]]
-- 按键处理函数
local function handle_key_event(key_event)
    log.info("Key event", "event:", key_event, "Current page:", current_page)

    -- 按键抬起生效
    if key_event == "boot_up" then
        -- BOOT键抬起:切换到下一个选项
        if current_page == PAGE_NAMES.HOME then
            return home_page.handle_key("next")
        elseif current_page == PAGE_NAMES.COMPONENT then
            return component_page.handle_key("next")
        elseif current_page == PAGE_NAMES.DEFAULT_FONT then
            return default_font_page.handle_key("next")
        end
        return false
    elseif key_event == "pwr_up" then
        -- PWR键抬起:确认/返回
        if current_page == PAGE_NAMES.HOME then
            return home_page.handle_key("confirm")
        elseif current_page == PAGE_NAMES.COMPONENT then
            return component_page.handle_key("confirm")
        elseif current_page == PAGE_NAMES.DEFAULT_FONT then
            return default_font_page.handle_key("confirm")
        end
    end
    return false
end

--[[
@api switch_page(new_page)
@summary 切换当前显示的页面
@param string new_page 要切换到的页面名称,可选值:"home""component""default_font"
@return 无返回值
@usage
-- 在页面处理函数中调用
switch_page("home")
]]
-- 页面切换函数(供其他页面调用)
function switch_page(new_page)
    log.info("switch_page", "From", current_page, "to", new_page)

    -- 调用旧页面的离开函数
    if current_page == PAGE_NAMES.HOME and home_page.on_leave then
        home_page.on_leave()
    elseif current_page == PAGE_NAMES.COMPONENT and component_page.on_leave then
        component_page.on_leave()
    elseif current_page == PAGE_NAMES.DEFAULT_FONT and default_font_page.on_leave then
        default_font_page.on_leave()
    end

    current_page = new_page

    -- 调用新页面的进入函数
    if new_page == PAGE_NAMES.HOME and home_page.on_enter then
        home_page.on_enter()
    elseif new_page == PAGE_NAMES.COMPONENT and component_page.on_enter then
        component_page.on_enter()
    elseif new_page == PAGE_NAMES.DEFAULT_FONT and default_font_page.on_enter then
        default_font_page.on_enter()
    end

    log.info("ui_main", "Switched to page:", current_page)
end

-- 主UI任务
local function ui_main()

    -- 预留1S给开机信息显示
    sys.wait(1000)
    log.info("ui_main", "Start UI main loop")

    -- 初始化主页
    home_page.on_enter()

    -- 主渲染循环
    while true do
        -- 设置默认字体
        u8g2.SetFont(u8g2.font_6x10) -- 使用英文字体
        -- 清空缓冲区
        u8g2.ClearBuffer()

        -- 根据当前页面绘制内容
        if current_page == PAGE_NAMES.HOME then
            home_page.draw()
        elseif current_page == PAGE_NAMES.COMPONENT then
            component_page.draw()
        elseif current_page == PAGE_NAMES.DEFAULT_FONT then
            default_font_page.draw()
        end

        -- 刷新显示
        u8g2.SendBuffer()

        -- 等待按键事件
        local result, key_event = sys.waitUntil("KEY_EVENT", frame_time)
        if result then
            handle_key_event(key_event)
        end
    end
end

-- 启动UI任务
sys.taskInit(ui_main)

7.6 hw_default_font_drv.lua

本文件为LCD初始化和内置字体硬件驱动模块,核心业务逻辑为:

1、初始化ST7567单色点阵屏(128x64分辨率);

2、配置SPI通信参数和显示参数;

3、设置内置字体显示模式;

4、显示开机信息并开启背光;

-- ST7567 SPI引脚配置
local spi_id, spi_res, spi_dc, spi_cs = 1, 24, 14, 12

local function init()
    -- 初始化U8G2显示屏 - ST7567, 128x64
    local result = u8g2.begin(
        {
            ic = "custom",        -- 使用自定义IC
            direction = 0,        -- 显示方向
            mode = "spi_hw_4pin", -- SPI硬件4线模式
            spi_id = spi_id,      -- SPI端口号
            spi_res = spi_res,    -- 复位引脚
            spi_dc = spi_dc,      -- 数据/命令选择引脚
            spi_cs = spi_cs       -- 片选引脚
        },
        {
            width = 128, -- 分辨率宽度,128像素
            height = 64, -- 分辨率高度,64像素

            -- 初始化命令表,根据ST7567芯片手册配置
            initcmd = {
                0xE2,        -- 系统复位
                0x82,        -- 设置偏压比
                0x2F,        -- 电源控制(开启内部电荷泵)
                0x26,        -- 电阻比率设置
                0xF8, 0x00,  -- 设置显示偏移(垂直偏移量为0)
                0x81, 0x09,  -- 设置对比度(0x09为对比度值)
                0x40,        -- 设置显示起始行(第0行)
                0xC8,        -- COM扫描方向(反向)
                0xA4,        -- 正常显示模式
                0xAF,        -- 开启显示
            },
            sleepcmd = 0xAE, -- 休眠命令
            wakecmd = 0xAF,  -- 唤醒命令
        }
    )

    if result == 1 then
        -- SPI接口屏幕才能获取初始化成功后屏幕的长宽,I2C接口无法获取的屏幕初始化成功后的长宽
        local width = u8g2.GetDisplayWidth()
        local height = u8g2.GetDisplayHeight()
        log.info("u8g2", "ST7567 init success" .. width .. "x" .. height)

        -- 设置字体显示模式为透明
        u8g2.SetFontMode(1)

        -- 显示开机信息
        u8g2.ClearBuffer()
        u8g2.DrawUTF8("U8G2 Demo Start", 10, 30)
        u8g2.SendBuffer()

        -- 打开背光,若采用GPIO控制
        gpio.setup(1, 1)
    else
        log.error("u8g2", "Init failed, error code:", result)
    end
end

init()

7.7 key_drv.lua

本文件为按键驱动功能模块,核心业务逻辑为:

1、初始化BOOT键和PWR键的GPIO;

2、配置按键事件的中断处理函数;

3、实现按键防抖功能,防止误触发;

4、对外发布按键消息;

-- 按键定义
local key_boot = 0           -- GPIO0按键(BOOT键)
local key_pwr = gpio.PWR_KEY -- 电源按键


-- 按键事件处理函数
local function handle_boot_key(val)
    -- print("key_boot", val)
    if val == 1 then
        sys.publish("KEY_EVENT", "boot_down")
    else
        sys.publish("KEY_EVENT", "boot_up")
    end
end

local function handle_pwr_key(val)
    -- print("key_pwr", val)
    if val == 1 then
        sys.publish("KEY_EVENT", "pwr_up")
    else
        sys.publish("KEY_EVENT", "pwr_down")
    end
end

--[[
初始化按键GPIO
配置BOOT键和PWR键的GPIO中断

@api init()
@summary 配置BOOT键和PWR键的GPIO中断
@return bool 初始化只会返回true
@usage

]]
local function init()
    gpio.setup(key_boot, handle_boot_key, gpio.PULLDOWN, gpio.BOTH)
    gpio.debounce(key_boot, 50, 0) -- 防抖,防止频繁触发

    gpio.setup(key_pwr, handle_pwr_key, gpio.PULLUP, gpio.BOTH)
    gpio.debounce(key_pwr, 50, 0) -- 防抖,防止频繁触发

    log.info("key_drv", "按键初始化完成")
end

init()

八、显示效果展示

8.1 硬件准备

  1. 按照硬件接线表连接所有设备
  2. 确保电源连接正确,通过TYPE-C USB口供电
  3. 检查所有接线无误,避免短路

8.2 软件配置

main.lua中选择加载对应的驱动模块:

-- 加载显示和字体驱动模块
require("hw_default_font_drv")  -- 使用内置12号英文点阵字体

-- 加载按键驱动
require("key_drv")

-- 加载UI主模块
require("ui_main")

8.3 软件烧录

  1. 使用Luatools烧录最新内核固件
  2. 下载并烧录本项目所有脚本文件
  3. 设备自动重启后开始运行

8.4 功能测试

8.4.1 主页面操作

  1. 设备启动后显示主页面,包含两个功能选项
  2. 使用 boot 键(释放)切换选择不同的菜单项
  3. 使用 pwr 键(释放)进入选中的演示页面

8.4.2 组件演示页面

  1. 查看进度条显示(初始 30%)
  2. 查看基本图形绘制效果
  3. 使用 boot 键切换按钮(返回、+10%)
  4. 使用 pwr 键执行当前选中按钮的功能

8.4.3 内置字体演示页面

  1. 查看内置字体显示效果
  2. 查看当前时间显示(每 300ms 更新一次)
  3. 使用 boot 键切换按钮(只有一个返回按钮)
  4. 按 pwr 键返回主页

8.5 预期效果

  • 系统启动:显示开机信息(内置字体进入),然后进入主页面
  • 主页面:正常显示两个菜单项,boot 键切换选项,pwr 键确认
  • 组件演示页面:进度条和图形显示正常,按键功能正常
  • 内置字体页面:字体显示正常,时间更新正常,pwr 键返回
  • 按键响应:所有按键操作响应及时准确,页面切换流畅

九、常见问题

1、显示屏不亮

  • 检查电源接线是否正确
  • 确认 SPI 通信速率是否合适

2、显示内容异常

  • 检查初始化参数和命令是否正确
  • 确认显示屏分辨率设置是否与自己的屏幕相同

3、按键无响应

  • 检查按键 GPIO 引脚配置
  • 确认按键中断处理函数是否正确注册
  • 检查防抖参数是否合适

4、系统卡顿或重启

  • 确认内存使用情况
  • 适当调整屏幕刷新频率