跳转至

01 lcd核心库应用

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

一、概述

AirLCD_1000 是合宙推出的一款SPI接口,3.5寸屏,480*320 的LCD配件板,其中:

1、显示屏的驱动IC是:ST7796;

2、8个插针管脚:LCD_CLK LCD_SDA LCD_RST LCD_RS LCD_CS BKL VCC GND;

  • BKL:背光控制管脚,默认高电平,背光常亮;低电平时背光熄灭;

  • VCC:2.8V-3.3V;

3、适用于Air780系列/Air8000系列;

airui 是基于 LVGL 9.4 版本进行图形层封装的 LuatOS 核心库,把常用组件、事件管理、输入和基础视觉主题封装为更易上手的 Lua 接口,便于在支持 LuatOS 的设备和 PC 上统一开发。

建议使用airui来开发显示界面,airui demo参考:https://gitee.com/openLuat/LuatOS/tree/master/module/Air780EHM_Air780EHV_Air780EGH/demo/ui/airui/single

二、演示功能概述

1、核心主程序模块

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

2、显示页面模块

  • home_page.lua :主页模块,提供应用入口和导航功能
  • lcd_page.lua:LCD图形绘制演示模块
  • customer_font_page.lua:自定义字体演示模块

3、驱动模块

  • lcd_drv.lua:LCD显示驱动模块,基于lcd核心库,lcd_drv和exlcd_drv二选一使用
  • exlcd_drv.lua:LCD显示驱动模块,基于exlcd扩展库,lcd_drv和exlcd_drv二选一使用
  • key_drv.lua:按键驱动模块,管理BOOT键和PWR键
  • customer_font_drv.lua:自定义外部字体驱动功能模块

三、按键消息介绍

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

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

按键功能定义:

  • 主页:boot键(按下)选择/切换选项,pwr键(按下)确认
  • LCD页面:pwr键(按下)返回,boot键无功能
  • 自定义字体页面:pwr键(按下)返回,boot键无功能

四、准备硬件环境

1、Air780EPM核心板 × 1

2、AirLCD_1000 配件板 × 1

3、母对母杜邦线 × 14

4、TYPE-C 数据线 × 1

5、Air780EPM核心板和 AirLCD_1000配件板的硬件接线方式为:

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

LCD 显示屏接线

Air780EPM核心板 AirLCD_1000配件板
53/LCD_CLK SCLK/CLK
52/LCD_CS CS
49/LCD_RST RES/RST
50/LCD_SDA SDA/MOS
51/LCD_RS DC/RS
22/GPIO1 BLK
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/accessory_board/AirLCD_1000/lcd

Air780EHM脚本文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air780EHM_Air780EHV_Air780EGH/demo/accessory_board/AirLCD_1000/lcd

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

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

5.2 API 介绍

lcd 核心库:https://docs.openluat.com/osapi/core/lcd/

六、程序结构

AirLCD_1000/lcd/
│── font_drv
    │── customer_font_12.bin
    │── customer_font_22.bin
    │── customer_font_drv.lua
│── images   
    │── logo.jpg    
│── lcd_drv
    │── exlcd_drv.lua
    │── lcd_drv.lua     
│── tp_key_drv
    │── key_drv.lua 
│── ui
    │──  customer_font_page.lua
    │──  home_page.lua
    │──  lcd_page.lua
    │──  ui_main.lua            
│── readme.md

6.1 文件说明

1、font_drv

  • customer_font_12.bin:自定义字体文件(和lua脚本文件一起烧录,会自动放置在/luadb/目录下)
  • customer_font_22.bin:自定义字体文件(和lua脚本文件一起烧录,会自动放置在/luadb/目录下)
  • 点击查看自定义字体生成和使用说明
  • customer_font_drv.lua:自定义外部字体驱动功能模块

2、images

  • logo.jpg:演示图片文件(和lua脚本文件一起烧录,会自动放置在/luadb/目录下)

3、lcd_drv

  • lcd_drv.lua:LCD显示驱动模块,基于lcd核心库,lcd_drv和exlcd_drv二选一使用
  • exlcd_drv.lua:LCD显示驱动模块,基于exlcd扩展库,lcd_drv和exlcd_drv二选一使用

4、tp_key_drv

  • key_drv.lua:按键驱动模块,管理BOOT键和PWR键

5、ui

  • ui_main.lua:用户界面主控模块,管理页面切换和事件分发
  • home_page.lua :主页模块,提供应用入口和导航功能
  • lcd_page.lua:LCD图形绘制演示模块
  • customer_font_page.lua:自定义字体演示模块

七、代码详解

7.1 main.lua

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

7.2 customer_font_drv.lua

customer_font_drv是用户外部自定义外部点阵字体驱动功能模块,因为不需要进行初始化,所以本文件没有任何实质代码,只在此处描述在项目中如何使用。

--[[ 
说明:
customer_font_drv是用户外部自定义外部点阵字体驱动功能模块,因为不需要进行初始化,所以本文件没有任何实质代码,只在此处描述在项目中如何使用。
自定义字体制作说明可以参考lcd核心库自定义字体制作说明:https://docs.openluat.com/osapi/core/lcd/#_6
1、通过链接 https://gitee.com/Dozingfiretruck/u8g2_font_tool 下载字体文件制作工具
2、制作字体
   - 将.ttf和.otf格式字体加载到制作工具内
   - 选择自定义,输入需要生成的字体内容,调用自定义文字显示接口只能显示所输入的内容,其他内容需要切换支持的字体
   - 选择其他,则会按苏哦选编码格式生成对应的字体
   - 设置字体大小,生成合宙lcd核心库可加载的.bin格式的字体文件
3、使用lcd.setFontFile(font)接口设置
   - 其中font为字体文件路径
   - 若将生成的字体文件命名为customer_font_24.bin 并通过luatools工具同代码一起烧录到脚本分区,则设置接口为lcd.setFontFile("/luadb/customer_font_24.bin")
   - 若将生成的字体文件命名为customer_font_24.bin 并通过luatools工具同固件和代码一起烧录到文件系统,则设置接口为lcd.setFontFile("/customer_font_24.bin")
4、使用lcd.drawStr(x,y,str,fg_color)接口显示具体内容
]]

7.3 exlcd_drv.lua

本模块为扩展LCD显示驱动功能模块,主要功能包括:

1、初始化AirLCD_1000扩展LCD显示;

2、配置显示缓冲区和自动刷新设置;

对外接口:

1、exlcd_drv.init():初始化扩展LCD显示驱动

如果需要实现背光亮度调节,参考exlcd扩展库中的exlcd.set_bl(level)进行设置

local exlcd = require "exlcd"

local exlcd_drv = {}

--[[
初始化扩展LCD显示驱动

@api exlcd_drv.init()
@summary 配置并初始化AirLCD_1000扩展LCD显示
@return boolean 初始化成功返回true,失败返回false

@usage
-- 初始化扩展LCD显示
local result = exlcd_drv.init({})
if result then
    log.info("扩展LCD初始化成功")
else
    log.error("扩展LCD初始化失败")
end
]]

function exlcd_drv.init()
    local result = exlcd.init({lcd_model = "AirLCD_1000"})

    log.info("exlcd.init", result)

    if result then
        -- 显示设置
        lcd.setupBuff(nil, true)
        lcd.autoFlush(false)
    end

    return result
end

return exlcd_drv

7.4 lcd_drv.lua

本模块为LCD显示驱动功能模块,主要功能包括:

1、初始化AirLCD_1000 显示IC ST7796;

2、配置LCD显示参数和显示缓冲区;

3、支持多种屏幕方向和分辨率设置;

local lcd_drv = {}

--[[
初始化LCD显示驱动

@api lcd_drv.init()
@summary 配置并初始化ST7796 LCD控制器
@return boolean 初始化成功返回true,失败返回false

@usage
-- 初始化LCD显示
local result = lcd_drv.init()
if result then
    log.info("LCD初始化成功")
else
    log.error("LCD初始化失败")
end
]]

function lcd_drv.init()
    local result = lcd.init("st7796",
        {
            pin_rst = 36,                          -- 复位引脚
            pin_pwr = 1,                           -- 背光控制引脚GPIO的ID号
            port = lcd.HWID_0,                     -- 驱动端口
            -- pin_dc = 0xFF,          -- lcd数据/命令选择引脚GPIO ID号,使用lcd 专用 SPI 接口 lcd.HWID_0不需要填此参数,使用通用SPI接口需要赋值
            direction = 0,                         -- lcd屏幕方向 0:0° 1:90° 2:180° 3:270°,屏幕方向和分辨率保存一致
            w = 320,                               -- lcd 水平分辨率
            h = 480,                               -- lcd 竖直分辨率
            xoffset = 0,                           -- x偏移(不同屏幕ic 不同屏幕方向会有差异)
            yoffset = 0,                           -- y偏移(不同屏幕ic 不同屏幕方向会有差异)
            sleepcmd = 0X10,                       -- 睡眠命令,默认0X10
            wakecmd = 0X11,                        -- 唤醒命令,默认0X11
            -- bus_speed = 50*1000*1000,                            -- SPI总线速度,不填默认50M,若速率要求更高需要进行设置
            -- interface_mode = lcd.WIRE_4_BIT_8_INTERFACE_I,       -- lcd模式,默认lcd.WIRE_4_BIT_8_INTERFACE_I
            -- direction0 = {0x36,0x00},                            -- 0°方向的命令,(不同屏幕ic会有差异)
            -- direction90 = {0x36,0x60},                           -- 90°方向的命令,(不同屏幕ic会有差异)
            -- direction180 ={0x36,0xc0} ,                          -- 180°方向的命令,(不同屏幕ic会有差异)
            -- direction270 = {0x36,0xA0},                          -- 270°方向的命令,(不同屏幕ic会有差异)
            -- hbp = nil,                                           -- 水平后廊
            -- hspw = nil,                                          -- 水平同步脉冲宽度
            -- hfp = 0,                                             -- 水平前廊
            -- vbp = 0,                                             -- 垂直后廊
            -- vspw = 0,                                            -- 垂直同步脉冲宽度
            -- vfp = 0,                                             -- 垂直前廊
            -- initcmd = nil,                                       -- 自定义屏幕初始化命令表
            -- flush_rate = nil,                                    -- 刷新率
            -- spi_dev = nil,                                       -- spi设备,当port = "device"时有效,当port ≠ "device"时可不填或者填nil
            -- init_in_service = false,                             -- 允许初始化在lcd service里运行,在后台初始化LCD,默认是false,Air8000/G/W/T/A、Air780EHM/EGH/EHV 支持填true,可加快初始化速度,默认SPI总线速度80M
        })

    log.info("lcd.init", result)

    if result then
        -- 显示设置
        lcd.setupBuff(nil, true)
        lcd.autoFlush(false)
    end

    return result
end

return lcd_drv

7.5 key_drv.lua

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

1、初始化BOOT键(GPIO0)和PWR键(gpio.PWR_KEY)的GPIO引脚;

2、配置按键事件的GPIO中断处理函数,支持上升沿和下降沿触发;

3、实现50ms防抖功能,防止抖动误触发;

4、对外发布按键消息"KEY_EVENT",包含按键类型和状态信息;

local key_drv = {}

-- 按键定义
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 key_drv.init()
@summary 配置BOOT键和PWR键的GPIO中断
@return bool 初始化只会返回true

@usage
local result = key_drv.init()
if result then
    log.info("按键驱动初始化成功")
end
]]
function key_drv.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", "按键初始化完成")
    return true
end

key_drv.init()
return key_drv

7.6 ui_main.lua

本模块为用户界面主控模块,核心业务逻辑为:

1、管理页面切换和事件分发,支持主页、LCD演示页和自定义字体演示页;

2、处理按键事件,分发到对应页面的处理函数;

3、控制界面刷新频率,支持不同页面的不同刷新率需求;

4、加载和切换自定义字体文件;

注意:当前仅支持自定义点阵字体

-- 加载子页面
local home_page = require "home_page"
local lcd_page = require "lcd_page"
local customer_font_page = require "customer_font_page"

-- 当前页面状态
local current_page = "home"
local last_page = ""
frame_time = 20 * 1000 -- 超时刷新时间,进入刷新率要求高的页面可以更此变量,退出再更改回来

--[[
切换页面;
@api switch_page(new_page)
@summary 执行页面切换操作
@string new_page 目标页面名称
@valid_values "home", "lcd", "customer_font"
@return nil
]]
local function switch_page(new_page)
    log.info("switch_page", "从", current_page, "切换到", new_page)

    -- 调用旧页面的退出函数
    if current_page == "home" and home_page.on_leave then
        home_page.on_leave()
    elseif current_page == "lcd" and lcd_page.on_leave then
        lcd_page.on_leave()
    elseif current_page == "customer_font" and customer_font_page.on_leave then
        customer_font_page.on_leave()
    end

    last_page = current_page
    current_page = new_page

    -- 调用新页面的进入函数
    if new_page == "home" and home_page.on_enter then
        home_page.on_enter()
    elseif new_page == "lcd" and lcd_page.on_enter then
        lcd_page.on_enter()
    elseif new_page == "customer_font" and customer_font_page.on_enter then
        customer_font_page.on_enter()
    end

    log.info("ui_main", "已切换到页面:", current_page)
end

--[[
处理按键事件;
@api handle_key_event(key_event)
@summary 处理按键事件并分发到对应页面
@string key_event 按键事件类型
@valid_values "boot_up", "pwr_up"
@return bool 事件处理成功返回true,否则返回false
]]
local function handle_key_event(key_event)
    log.info("按键事件", "event:", key_event, "当前页面:", current_page)

    -- 只在按键释放时处理
    if key_event == "boot_up" then
        -- BOOT键:在主页作为方向键
        if current_page == "home" then
            return home_page.handle_key("next", switch_page)
        end
        -- 其他页面BOOT键无功能
        return false
    elseif key_event == "pwr_up" then
        -- PWR键:确认/返回功能
        if current_page == "home" then
            return home_page.handle_key("confirm", switch_page)
        elseif current_page == "lcd" then
            if lcd_page.handle_key then
                return lcd_page.handle_key("pwr_up", switch_page)
            end
        elseif current_page == "customer_font" then
            if customer_font_page.handle_key then
                return customer_font_page.handle_key("pwr_up", switch_page)
            end
        end
    end

    return false
end

--[[
用户界面主任务;
@api ui_main()
@summary 初始化显示和按键驱动,启动UI主循环
@return nil
]]
local function ui_main()
    if not lcd_drv.init() then
        log.error("ui_main", "显示初始化失败")
        return
    end

    if not key_drv.init() then
        log.error("ui_main", "按键驱动初始化失败")
        return
    end

    -- 使用自定义字体(12号)
    lcd.setFontFile("/luadb/customer_font_12.bin")

    -- 调用主页的进入函数
    if home_page.on_enter then
        home_page.on_enter()
    end

    while true do
        -- 根据当前页面绘制内容
        if current_page == "home" then
            home_page.draw()
        elseif current_page == "lcd" then
            lcd_page.draw()
        elseif current_page == "customer_font" then
            customer_font_page.draw()
        end

        lcd.flush()

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

sys.taskInit(ui_main)

7.7 home_page.lua

本模块为主页模块,核心业务逻辑为:

1、提供应用入口和导航功能,支持LCD演示和自定义字体演示两个功能选项;

2、显示系统标题和操作提示信息;

3、管理功能按钮的选中状态,支持光标指示器;

4、处理主页面的按键事件,支持BOOT键选择和PWR键确认;

注意:使用自定义字体显示中文

local home_page = {}

-- 按钮区域定义(调整为2个按钮)
local buttons = {
    { name = "lcd", text = "LCD演示", x1 = 40, y1 = 150, x2 = 140, y2 = 240, color = 0x001F }, -- 蓝色
    { name = "customer_font", text = "自定义字体", x1 = 180, y1 = 150, x2 = 280, y2 = 240, color = 0xF800 } -- 红色
}

-- 当前选中项索引
local selected_index = 1

--[[
绘制光标指示
@local
@return nil
]]
local function draw_cursor()
    local btn = buttons[selected_index]

    -- 在选中按钮周围绘制矩形光标
    lcd.drawRectangle(btn.x1 - 4, btn.y1 - 4, btn.x2 + 4, btn.y2 + 4, 0xFFFF) -- 白色外框
    lcd.drawRectangle(btn.x1 - 3, btn.y1 - 3, btn.x2 + 3, btn.y2 + 3, 0x0000) -- 黑色内框
end

--[[
绘制主页界面;
@api home_page.draw()
@summary 绘制主页面所有UI元素,包括选中指示
@return nil
]]
function home_page.draw()
    lcd.clear()
    -- 显示标题,使用22号自定义字体
    lcd.setColor(0xFFFF, 0x0000)
    lcd.setFontFile("/luadb/customer_font_22.bin")

    -- 顶部标题栏
    lcd.fill(0, 0, 320, 60, 0x001F) -- 蓝色背景
    lcd.drawStr(80, 39, "合宙LCD演示系统", 0xFFFF) -- 白色文字

    -- 显示演示内容,使用12号自定义字体
    lcd.setFontFile("/luadb/customer_font_12.bin")

    -- 绘制所有按钮
    for i, btn in ipairs(buttons) do
        local color = btn.color

        -- 绘制按钮背景
        lcd.fill(btn.x1, btn.y1, btn.x2, btn.y2, color)

        -- 绘制按钮文字(居中)
        local text_x = btn.x1 + (btn.x2 - btn.x1) / 2 - 25
        local text_y = btn.y1 + (btn.y2 - btn.y1) / 2

        lcd.drawStr(text_x, text_y, btn.text, 0xFFFF)

        -- 绘制按钮边框
        lcd.drawRectangle(btn.x1, btn.y1, btn.x2, btn.y2, 0x0000)
    end

    -- 绘制光标指示
    draw_cursor()

    -- 底部状态栏
    lcd.fill(0, 380, 320, 480, 0x001F) -- 蓝色背景
    lcd.drawStr(20, 405, "当前页面: 主页", 0xFFFF)
    lcd.drawStr(30, 430, "- BOOT键: 选择选项", 0xFFFF)
    lcd.drawStr(30, 450, "- PWR键: 确认进入", 0xFFFF)
    lcd.drawStr(30, 470, "- 中文仅支持自定义点阵字体", 0xFFFF)
end

--[[
处理主页按键事件;
@api home_page.handle_key(key_type, switch_page)
@summary 处理主页按键事件
@string key_type 按键类型
@valid_values "confirm", "next", "prev"
@function switch_page 页面切换回调函数
@return bool 事件处理成功返回true,否则返回false
]]
function home_page.handle_key(key_type, switch_page)
    log.info("home_page.handle_key", "key_type:", key_type, "selected_index:", selected_index)

    if key_type == "confirm" then
        -- 确认键:切换到选中的页面
        local btn = buttons[selected_index]
        switch_page(btn.name)
        return true
    elseif key_type == "right" or key_type == "next" then
        -- 向右/下一个
        selected_index = selected_index % #buttons + 1
        return true
    elseif key_type == "left" or key_type == "prev" then
        -- 向左/上一个
        selected_index = (selected_index - 2) % #buttons + 1
        return true
    end
    return false
end

--[[
页面进入时重置选中状态;
@api home_page.on_enter()
@summary 重置选中状态
@return nil
]]
function home_page.on_enter()
    selected_index = 1 -- 默认选中第一个
end

--[[
页面离开时执行清理操作;
@api home_page.on_leave()
@summary 页面离开时清理
@return nil
]]
function home_page.on_leave()
    -- 可以在这里执行清理操作
end

--[[
获取当前选中项信息;
@api home_page.get_selected_info()
@summary 获取当前选中项信息
@return table 包含选中项信息的表
]]
function home_page.get_selected_info()
    local btn = buttons[selected_index]
    return {
        index = selected_index,
        name = btn.name,
        text = btn.text
    }
end

return home_page

7.8 lcd_page.lua

本模块为LCD图形绘制演示功能模块,核心业务逻辑为:

1、展示LCD核心库的基本图形绘制功能,包括点、线、矩形、圆形;

2、演示图片显示功能,支持外部JPG图片文件;

3、显示二维码生成功能,动态生成并显示合宙文档二维码;

4、展示xbm格式位图示例,支持16x16点阵显示;

注意:使用自定义字体显示文字

local lcd_page = {}

--[[
绘制LCD演示页面
@api lcd_page.draw()
@summary 绘制LCD演示页面的所有图形和UI元素
@return nil
]]
function lcd_page.draw()
    lcd.clear()

    -- 设置背景颜色
    lcd.setColor(0xFFFF, 0x0000)

    -- 显示标题区域
    lcd.fill(0, 0, 320, 40, 0x001F) -- 蓝色标题栏    lcd.setColor(0xFFFF, 0x0000)

    -- 显示标题,使用22号自定义字体
    lcd.setFontFile("/luadb/customer_font_22.bin")
    lcd.drawStr(95, 31, "核心库演示", 0xFFFF)

    -- 显示演示内容,使用12号自定义字体
    lcd.setFontFile("/luadb/customer_font_12.bin")

    lcd.drawStr(20, 75, "基本图形绘制", 0x0000)
    lcd.drawLine(20, 55, 300, 55, 0x8410)

    lcd.drawStr(30, 98, "点", 0x0000)
    lcd.drawPoint(55, 98, 0xFCC0)
    lcd.drawPoint(65, 98, 0x07E0)
    lcd.drawPoint(75, 98, 0x001F)

    lcd.drawStr(30, 125, "线", 0x0000)
    lcd.drawLine(55, 113, 115, 113, 0xFCC0)
    lcd.drawLine(55, 118, 115, 123, 0x07E0)
    lcd.drawLine(55, 123, 115, 118, 0x001F)

    -- 绘制矩形(预留右侧空间)
    lcd.drawStr(30, 160, "矩形", 0x0000)
    lcd.drawRectangle(65, 138, 105, 163, 0x7296)
    lcd.fill(120, 138, 160, 163, 0x07E0)

    -- 绘制圆(预留右侧空间)
    lcd.drawStr(30, 200, "圆形", 0x0000)
    lcd.drawCircle(90, 193, 15, 0x001F)
    lcd.drawCircle(130, 193, 15, 0xFCC0)

    lcd.drawLine(170, 70, 170, 300, 0x8410) -- 垂直分隔线

    -- === 第二区域:图片和二维码 ===
    lcd.drawStr(180, 75, "图片二维码", 0x0000)

    -- 图片显示区域 (80x80)
    lcd.drawStr(180, 100, "LOGO", 0x0000)
    lcd.drawRectangle(200, 110, 290, 200, 0x0000)
    lcd.showImage(205, 115, "/luadb/logo.jpg")

    -- 二维码区域 (80x80)
    lcd.drawStr(180, 215, "二维码", 0x0000)
    lcd.drawRectangle(200, 225, 290, 308, 0x0000)
    lcd.drawQrcode(205, 226, "https://docs.openluat.com/air780epm/", 80)

    lcd.drawLine(20, 325, 300, 325, 0x8410)

    -- === 第三区域:位图 ===
    lcd.drawLine(20, 235, 160, 235, 0x8410)

    -- 位图区域
    lcd.drawStr(20, 255, "位图示例", 0x0000)

    -- 绘制位图
    local x_start = 30
    local y_start = 265
    lcd.drawXbm(x_start, y_start, 16, 16, string.char(
        0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x3F, 0x80, 0x00,
        0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xFE, 0x7F, 0x00, 0x00))

    lcd.drawXbm(x_start + 20, y_start, 16, 16, string.char(
        0x00, 0x00, 0x80, 0x00, 0xC4, 0x7F, 0x28, 0x00, 0x10, 0x00, 0xD0, 0x3F, 0x42, 0x20, 0x44, 0x22,
        0x40, 0x24, 0xF0, 0xFF, 0x24, 0x20, 0x24, 0x22, 0x24, 0x20, 0xE2, 0x7F, 0x02, 0x20, 0x02, 0x1E))

    lcd.drawXbm(x_start, y_start + 20, 16, 16, string.char(
        0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0x40, 0x02, 0x20, 0x04, 0x18, 0x18, 0xF4, 0x6F, 0x02, 0x00,
        0x00, 0x00, 0xF8, 0x1F, 0x08, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, 0x10, 0xF8, 0x1F, 0x08, 0x10))

    lcd.drawXbm(x_start + 20, y_start + 20, 16, 16, string.char(
        0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0xFE, 0x7F, 0x02, 0x40, 0x02, 0x40, 0x00, 0x01, 0xFC, 0x3F,
        0x04, 0x21, 0x04, 0x21, 0xFC, 0x3F, 0x04, 0x21, 0x04, 0x21, 0x04, 0x21, 0xFC, 0x3F, 0x04, 0x20))

    -- === 第四区域:字体 ===
    lcd.drawStr(20, 345, "中英文字体示例", 0x0000)


    lcd.drawStr(30, 368, "- 中文字体ABC123", 0x0000)
    lcd.drawStr(30, 394, "- 英文符号,-_./()[]{}<>!@#$%^&*_+=|?", 0x0000)

    -- 显示当前字体信息
    lcd.drawStr(20, 420, "字体路径:/luadb/customer_font_12.bin", 0x0000)

    -- 底部状态栏
    lcd.fill(0, 440, 320, 480, 0x001F) -- 蓝色背景
    lcd.drawStr(20, 465, "按PWR键返回主页", 0xFFFF)
end

--[[
处理按键事件;
@api lcd_page.handle_key(key_type, switch_page)
@summary 处理LCD页面按键事件
@string key_type 按键类型
@valid_values "pwr_up"
@function switch_page 页面切换回调函数
@return bool 事件处理成功返回true,否则返回false
]]
function lcd_page.handle_key(key_type, switch_page)
    log.info("lcd_page.handle_key", "key_type:", key_type)

    if key_type == "pwr_up" then
        -- PWR键:返回首页
        switch_page("home")
        return true
    end
    -- BOOT键无功能
    return false
end

return lcd_page

7.9 customer_font_page.lua

本模块为自定义字体演示功能模块,核心业务逻辑为:

1、展示外部自定义字体文件的加载和显示功能,支持12号和22号字体;

2、提供多颜色文字显示效果,支持红、绿、蓝三色文字;

3、显示字体使用说明和设备支持信息;

4、展示字体使用接口示例和文件路径信息;

local customer_font_page = {}

--[[
绘制自定义字体演示页面;
@api customer_font_page.draw()
@summary 绘制自定义字体演示页面的所有UI元素和字体内容
@return nil
]]
function customer_font_page.draw()
    lcd.clear()

    -- 显示标题,使用22号自定义字体
    -- 设置背景颜色
    lcd.setColor(0xFFFF, 0x0000)
    lcd.setFontFile("/luadb/customer_font_22.bin")

    -- 显示标题区域
    lcd.fill(0, 0, 320, 40, 0x001F) -- 蓝色标题栏    lcd.setColor(0xFFFF, 0x0000)

    -- 显示标题
    lcd.drawStr(70, 30, "自定义点阵字体演示", 0xFFFF)


    -- 显示演示内容,使用12号自定义字体
    lcd.setFontFile("/luadb/customer_font_12.bin")

    -- 字体支持说明区域(带背景色)
    lcd.fill(15, 60, 305, 155, 0xF7DE)          -- 浅灰色背景
    lcd.drawRectangle(15, 60, 305, 155, 0x8410) -- 边框

    -- 显示字体支持说明
    lcd.drawStr(30, 80, "当前设备字体支持:", 0x0000)
    lcd.drawStr(40, 105, "- 仅支持自定义字体", 0x0000)
    lcd.drawStr(40, 130, "- 不支持内置12号中文", 0x0000)

    lcd.drawLine(20, 165, 300, 165, 0x8410)

    -- 设置22号自定义字体文件显示示例文字
    lcd.setFontFile("/luadb/customer_font_22.bin")

    -- 示例文字区域(居中显示)
    lcd.drawStr(100, 200, "上海合宙", 0xF800) -- 红色
    lcd.drawStr(105, 230, "LuatOS", 0x07E0) -- 绿色
    lcd.drawStr(95, 260, "演示demo", 0x001F) -- 蓝色

    -- 恢复12号字体显示说明
    lcd.setFontFile("/luadb/customer_font_12.bin")
    lcd.setColor(0xFFFF, 0x0000)

    -- 字体文件信息区域
    lcd.drawLine(20, 280, 300, 280, 0x8410)
    lcd.drawStr(20, 300, "字体文件信息:", 0x0000)
    lcd.drawStr(30, 325, "- 12号字体: /luadb/customer_font_12.bin", 0x0000)
    lcd.drawStr(30, 350, "- 22号字体: /luadb/customer_font_22.bin", 0x0000)

    -- 显示使用接口
    lcd.drawStr(20, 380, "使用接口:", 0x0000)
    lcd.drawStr(35, 405, "- lcd.setFontFile(字体路径)", 0x0000)
    lcd.drawStr(35, 425, "- lcd.drawStr(x, y, 文本, 颜色)", 0x0000)

    -- 底部状态栏
    lcd.fill(0, 440, 320, 480, 0x001F) -- 蓝色背景
    lcd.drawStr(20, 465, "按PWR键返回主页", 0xFFFF)
end

--[[
处理按键事件;
@api customer_font_page.handle_key(key_type, switch_page)
@summary 处理自定义字体页面按键事件
@string key_type 按键类型
@valid_values "pwr_up"
@function switch_page 页面切换回调函数
@return bool 事件处理成功返回true,否则返回false
]]
function customer_font_page.handle_key(key_type, switch_page)
    log.info("customer_font_page.handle_key", "key_type:", key_type)

    if key_type == "pwr_up" then
        -- PWR键:返回首页
        switch_page("home")
        return true
    end
    -- BOOT键无功能
    return false
end

--[[
页面离开时恢复默认字体;
@api customer_font_page.on_leave()
@summary 恢复12号自定义字体
@return nil
]]
function customer_font_page.on_leave()
    -- 恢复使用12号自定义字体
    lcd.setFontFile("/luadb/customer_font_12.bin")
    log.info("customer_font_page", "已恢复12号自定义字体")
end

return customer_font_page

八、显示效果展示

8.1 硬件准备

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

8.2 软件配置

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

-- 加载显示屏驱动管理功能模块,有以下两种:
-- 1、使用lcd核心库驱动的lcd_drv.lua
-- 2、使用exlcd扩展库驱动的exlcd_drv.lua
-- 根据自己的需求,启用两者中的任何一种都可以
-- 也可以不启用任何一种,不使用显示屏功能
lcd_drv = require "lcd_drv"
-- lcd_drv = require "exlcd_drv"


-- 加载按键驱动管理功能模块
key_drv = require "key_drv"


-- 加载字库驱动管理功能模块
-- 使用外部自定义字体不需要require "customer_font_drv",可以参照customer_font_drv.lua内的使用说明进行创建和加载字体文件


-- 加载输入法驱动管理功能模块(正在开发中,后续补充)


-- 加载lcd核心库实现的用户界面功能模块
-- 实现多页面切换、按键事件分发和界面渲染功能
-- 包含主页、lcd核心库功能演示页和自定义字体演示页
require "ui_main"

8.3 软件烧录

  1. 使用Luatools烧录最新内核固件
  2. 下载并烧录本项目所有脚本文件
  3. 将字体文件和图片文件随脚本文件一起烧录到脚本分区
  4. 烧录成功后设备自动重启后开始运行

8.4 功能测试

8.4.1 主页面操作

  1. 设备启动后显示主页面,包含两个个功能按钮,作为按键页面切换演示
  2. 使用boot键切换选择,pwr键进入对应演示页面

8.4.2 LCD演示页面

  1. 查看基本图形绘制示例(点、线、矩形、圆形)
  2. 查看图片显示区域(显示logo图片)
  3. 查看二维码区域(合宙文档二维码)
  4. 查看位图和字体示例
  5. 按pwr键返回主页

8.4.3 自定义字体页面

  1. 查看外部字体文件显示效果
  2. 查看多颜色文字显示(红色、绿色、蓝色)
  3. 查看字体使用说明和接口信息
  4. 按pwr键返回主页

8.5 预期效果

  • 主页面:正常显示,使用boot键切换选项,pwr键确认
  • LCD演示页面:图形绘制清晰,图片和二维码显示正常,颜色示例完整,pwr键返回
  • 自定义字体页面:外部字体加载正确,多颜色文字显示正常,pwr键返回
  • 按键交互:所有按键操作响应及时准确,页面切换流畅

九、常见问题

  1. 显示异常:检查LCD接线是否正确,确认电源供电稳定
  2. 按键无响应:检查参数是否配置正确,确认按键驱动初始化成功
  3. 字体显示异常:检查所需显示内容是否包含在字体内,确认字体文件路径正确
  4. 图片无法显示:确认图片文件已正确烧录到指定路径
  5. 系统卡顿:检查内存使用情况,适当调整刷新频率