跳转至

01 lcd核心库应用

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

一、概述

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

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

2、触摸部分:I2C接口+触摸中断INT信号,5点电容触摸

3、11个插针管脚:LCD_CLK LCD_SDA LCD_RST LCD_RS LCD_CS BKL I2C_SCL I2C_SDA INT VCC GND;

说明:

  • INT为触摸中断信号;
  • BKL:背光控制管脚,默认高电平,背光常亮;低电平时背光熄灭;
  • VCC:2.8V-3.3V;

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

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

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

二、演示功能概述

1、核心主程序模块

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

2、显示页面模块

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

注意:同时使用自定义字体和非自定义字体需要使用V2020版本及以上固件

3、驱动模块

  1. lcd_drv.lua - LCD显示驱动模块,基于lcd核心库,lcd_drv和exlcd_drv二选一使用
  2. exlcd_drv.lua - LCD显示驱动模块,基于exlcd扩展库,lcd_drv和exlcd_drv二选一使用
  3. tp_drv.lua - 触摸驱动模块,基于tp核心库,tp_drv和extp_drv二选一使用
  4. extp_drv.lua - 触摸驱动模块,基于extp扩展库,tp_drv和extp_drv二选一使用
  5. customer_font_drv.lua - 自定义外部字体驱动功能模块
  6. hzfont_drv.lua - 合宙软件矢量字库(开发中)
  7. customer_font_drv、hzfont_drv
  8. 可以都不启用
  9. 可以仅启用一种
  10. 可以启用任意两种
  11. 可以全部启用

三、触摸消息介绍

"BASE_TOUCH_EVENT" - 基础触摸事件消息,包含触摸坐标和事件类型

  • tp触摸库事件类型:tp.EVENT_DOWN(按下)、tp.EVENT_MOVE(移动)、tp.EVENT_UP(抬起)
  • extp触摸库事件类型:SINGLE_TAP(单击)、LONG_PRESS(长按)可根据UI需求打开滑动事件
  • 坐标范围:X: 0-319,Y: 0-479

四、准备硬件环境

1、Air8000核心板 × 1

2、AirLCD_1010 触摸配件板 × 1

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

4、TYPE-C 数据线 × 1

5、Air8000核心板和 AirLCD_1010 配件板的硬件接线方式为

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

LCD 显示屏接线

Air8000核心板 AirLCD_1010配件板
LCD_CLK SCLK/CLK
LCD_CS CS
LCD_RST RES/RST
LCD_SDA SDA/MOS
LCD_RS DC/RS
GPIO1 BLK
VBAT VCC
I2C1_SCL SCL
I2C1_SDA SDA
WAKEUP0 INT
GND GND

五、准备软件环境

5.1 软件环境

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

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

2、内核固件:

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

注意:同时使用自定义字体和非自定义字体需要使用V2020版本及以上固件

3、脚本文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air8000/demo/accessory_board/AirLCD_1010/lcd

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

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

5.2 API 介绍

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

六、程序结构

AirLCD_1000/lcd/
│── font_drv
    │── customer_font_24.bin
    │── customer_font_drv.lua
    │── hzfont_drv.lua    
│── images   
    │── logo.jpg    
│── lcd_drv
    │── exlcd_drv.lua
    │── lcd_drv.lua     
│── tp_key_drv
    │── extp_drv.lua 
    │── tp_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_24.bin:自定义字体文件(和lua脚本文件一起烧录,会自动放置在/luadb/目录下)
  • 点击查看自定义字体生成和使用说明
  • customer_font_drv.lua:自定义外部字体驱动功能模块
  • hzfont_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

  • extp_drv.lua:触摸驱动模块,基于extp扩展库,tp_drv和extp_drv二选一使用
  • tp_drv.lua:触摸驱动模块,基于tp扩展库,tp_drv和extp_drv二选一使用

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 hzfont_drv.lua

合宙开发的一个内置矢量字体库,目前正在开发中

-- hzfont 是合宙开发的一个内置矢量字体库,目前正在开发中

7.4 exlcd_drv.lua

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

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

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

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

local exlcd = require "exlcd"

local exlcd_drv = {}

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

@api exlcd_drv.init()
@summary 配置并初始化AirLCD_1010扩展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_1010", pin_vcc = 0xFF})

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

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

    return result
end

return exlcd_drv

7.5 lcd_drv.lua

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

1、初始化ST7796 LCD控制器;

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.6 extp_drv.lua

本模块为扩展触摸面板驱动功能模块,主要功能包括:

1、初始化AirLCD_1010扩展触摸面板;

2、配置I2C通信接口和触摸参数;

3、发布触摸事件消息供UI系统处理;

local extp = require "extp"

local extp_drv = {}

--[[
初始化扩展触摸面板驱动;

@api extp_drv.init()
@summary 配置并初始化AirLCD_1010扩展触摸面板
@return boolean 初始化成功返回true,失败返回false

@usage
-- 初始化扩展触摸面板
local result = extp_drv.init()
if result then
    log.info("扩展触摸面板初始化成功")
else
    log.error("扩展触摸面板初始化失败")
end
]]

function extp_drv.init()
    -- 初始化I2C
    local result = i2c.setup(1, i2c.SLOW)

    if result==0 then
        log.error("extp_drv.init i2c.setup error")
        return false
    end

    result = extp.init({tp_model = "AirLCD_1010", i2c_id = 1, pin_rst = 0xFF, pin_int = gpio.WAKEUP0, w = 320, h = 480})

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

    return result
end

return extp_drv

7.7 tp_drv.lua

本模块为触摸面板驱动功能模块,主要功能包括:

1、初始化GT911触摸控制器;

2、配置I2C通信接口和触摸回调函数;

3、发布触摸事件消息供UI系统处理;

local tp_drv = {}

--[[
触摸事件回调函数;

@local
@function tp_callback(tp_device, tp_data)
@userdata tp_device 触摸设备对象
@table tp_data 触摸数据数组
@return nil
]]

local function tp_callback(tp_device, tp_data)
    if tp_data[1].event == tp.EVENT_DOWN then
        -- log.info("tp_drv tp_callback", tp_data[1].event, tp_data[1].x, tp_data[1].y)
        sys.publish("BASE_TOUCH_EVENT", tp_data[1].event, tp_data[1].x, tp_data[1].y)
    end
end

--[[
初始化触摸面板驱动;

@api tp_drv.init()
@summary 配置并初始化GT911触摸控制器
@return boolean 初始化成功返回true,失败返回false

@usage
-- 初始化触摸面板
local result = tp_drv.init()
if result then
    log.info("触摸面板初始化成功")
else
    log.error("触摸面板初始化失败")
end
]]

function tp_drv.init()
    -- 初始化I2C
    local result = i2c.setup(1, i2c.SLOW)

    if result==0 then
        log.error("tp_drv.init i2c.setup error")
        return false
    end

    result = tp.init("gt911", {port = 1, pin_rst = 0xFF, pin_int = gpio.WAKEUP0, w = 320, h = 480}, tp_callback)

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

    return result
end

return tp_drv

7.8 ui_main.lua

本模块为核心UI控制模块,主要功能包括:

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)
@string new_page 目标页面名称
@valid_values "home", "lcd", "customer_font_page"
@return nil

@usage
-- 切换到LCD演示页面
switch_page("lcd")
]]
local function switch_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_page" 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_page" and customer_font_page.on_enter then
        customer_font_page.on_enter()
    end

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

--[[
处理触摸事件;

@api handle_touch_event(event, x, y)
@number event 触摸事件类型
@valid_values tp.EVENT_DOWN, tp.EVENT_MOVE, tp.EVENT_UP
@number x 触摸点X坐标,范围0-319
@number y 触摸点Y坐标,范围0-479
@return boolean 事件处理成功返回true,否则返回false
]]
-- 处理触摸事件
local function handle_touch_event(event, x, y)
    log.info("触摸事件", "event:", event, "x:", x, "y:", y)

    if event then -- 只在抬起时处理点击
        if current_page == "home" then
            return home_page.handle_touch(x, y, switch_page)
        elseif current_page == "lcd" then
            return lcd_page.handle_touch(x, y, switch_page)
        elseif current_page == "customer_font_page" then
            return customer_font_page.handle_touch(x, y, switch_page)
        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 tp_drv.init() then
        log.error("ui_main", "触摸初始化失败")
        return
    end

    -- 默认使用系统自带的12号中文字体
    lcd.setFont(lcd.font_opposansm12_chinese)

    -- 调用主页的进入函数
    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_page" then
            customer_font_page.draw()
        end

        lcd.flush()


        -- 等待触摸事件
        local result, event, x, y = sys.waitUntil("BASE_TOUCH_EVENT",frame_time)
        if result then
            handle_touch_event(event, x, y)
        end
    end
end


sys.taskInit(ui_main)

7.9 home_page.lua

本模块为主页面功能模块,主要功能包括:

1、绘制主页面UI界面,显示应用标题和功能介绍;

2、提供三个功能按钮:LCD演示、矢量字体演示、自定义字体演示;

3、处理主页面的触摸事件,实现页面导航;

local home_page = {}

-- 屏幕尺寸
local width, height = lcd.getSize()

local center_x = math.floor(width / 2)

-- 按钮区域定义
local buttons = {
    lcd_page = { x1 = 10, y1 = 350, x2 = 150, y2 = 420 },
    customer_font_page = { x1 = 170, y1 = 350, x2 = 310, y2 = 420 }
}

local title = "合宙lcd演示系统"
local content1 = "本页面使用的是系统内置的12号中文点阵字体"


--[[
绘制主页界面;

@api home_page.draw()
@summary 绘制主页面所有UI元素
@return nil
]]
function home_page.draw()
    lcd.clear()
    lcd.setColor(0xFFFF, 0x0000)
    lcd.setFont(lcd.font_opposansm12_chinese)

    -- 显示标题
    -- 后续V2020版本以上支持lcd核心库的固件会新增lcd.getStrWidth(title)接口获取文本宽度,对齐、居中、换行可使用
    -- lcd.drawStr(center_x - lcd.getStrWidth(title) / 2, 50, title, 0x0000) -- 自动居中
    lcd.drawStr(106, 50, title, 0x0000)

    -- 显示说明文字
    lcd.drawStr(46, 68, content1, 0x0000)

    -- 绘制LCD演示按钮
    lcd.fill(buttons.lcd_page.x1, buttons.lcd_page.y1,
        buttons.lcd_page.x2, buttons.lcd_page.y2, 0x001F)
    lcd.drawStr(40, 390, "lcd核心库演示", 0xFFFF)

    -- 绘制自定义字体演示按钮
    lcd.fill(buttons.customer_font_page.x1, buttons.customer_font_page.y1,
        buttons.customer_font_page.x2, buttons.customer_font_page.y2, 0x07E0)
    lcd.drawStr(205, 390, "自定义字体", 0xFFFF)
end

--[[
处理主页触摸事件;

@api home_page.handle_touch(x, y, switch_page)
@number x 触摸点X坐标,范围0-319
@number y 触摸点Y坐标,范围0-479
@function switch_page 页面切换回调函数
@return boolean 事件处理成功返回true,否则返回false
]]
function home_page.handle_touch(x, y, switch_page)
    -- 检查LCD演示按钮
    if x >= buttons.lcd_page.x1 and x <= buttons.lcd_page.x2 and
        y >= buttons.lcd_page.y1 and y <= buttons.lcd_page.y2 then
        switch_page("lcd")
        return true
    end

    -- 检查自定义字体演示按钮
    if x >= buttons.customer_font_page.x1 and x <= buttons.customer_font_page.x2 and
        y >= buttons.customer_font_page.y1 and y <= buttons.customer_font_page.y2 then
        switch_page("customer_font_page")
        return true
    end

    return false
end

return home_page

7.10 lcd_page.lua

本模块为LCD图形绘制演示功能模块,主要功能包括:

1、展示LCD核心库的基本图形绘制功能;

2、演示点、线、矩形、圆形等基本图形绘制;

3、显示图片和二维码生成功能;

4、提供颜色示例展示;

local lcd_page = {}

-- 按钮区域定义
local back_button = { x1 = 10, y1 = 10, x2 = 80, y2 = 50 }

--[[
绘制LCD演示页面

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

    -- 绘制返回按钮
    lcd.fill(back_button.x1, back_button.y1, back_button.x2, back_button.y2, 0xC618)
    lcd.setColor(0x07E0, 0x0000)
    lcd.drawStr(35, 35, "返回", 0x0000)
    -- 设置默认颜色
    lcd.setColor(0xFFFF, 0x0000)

    -- 显示标题
    lcd.drawStr(120, 33, "LCD核心库演示", 0x0000)
    lcd.drawLine(20, 55, 300, 55, 0x8410)

    -- === 第一区域:基本图形 ===
    lcd.drawStr(20, 75, "基本图形绘制:", 0x0000)

    -- 绘制点
    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(180, 110, 270, 200, 0x0000) 
    lcd.showImage(185, 115, "/luadb/logo.jpg")  

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

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

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

    -- 位图区域
    lcd.setFont(lcd.font_opposansm12_chinese)
    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.setFont(lcd.font_opposansm12_chinese)
    lcd.drawStr(20, 368, "中文字体ABC123", 0x0000)

    -- 英文字体
    local font_y = 388
    lcd.setFont(lcd.font_opposansm12)
    lcd.drawStr(20, font_y, "12px: ABCabc123", 0x0000)
    font_y = font_y + 18

    lcd.setFont(lcd.font_opposansm16)
    lcd.drawStr(20, font_y, "16px: ABCabc123", 0x0000)
    font_y = font_y + 22

    lcd.setFont(lcd.font_opposansm20)
    lcd.drawStr(20, font_y, "20px: ABCabc123", 0x0000)
    font_y = font_y + 26

    lcd.setFont(lcd.font_opposansm24)
    lcd.drawStr(20, font_y, "24px: ABCabc123", 0x0000)

    lcd.drawLine(20, 470, 300, 470, 0x8410)
end

--[[
处理LCD页面触摸事件

@api lcd_page.handle_touch(x, y, switch_page)
@number x 触摸点X坐标,范围0-319
@number y 触摸点Y坐标,范围0-479
@function switch_page 页面切换回调函数
@return boolean 事件处理成功返回true,否则返回false
]]
function lcd_page.handle_touch(x, y, switch_page)
    -- 检查返回按钮
    if x >= back_button.x1 and x <= back_button.x2 and
        y >= back_button.y1 and y <= back_button.y2 then
        switch_page("home")
        return true
    end
    return false
end

return lcd_page

7.11 customer_font_page.lua

本模块为自定义字体演示功能模块,主要功能包括:

1、展示外部自定义字体文件的使用方法;

2、演示不同颜色的字体显示效果;

3、提供字体文件路径和使用接口说明;

4、支持页面离开时恢复系统默认字体;

local customer_font_page = {}

-- 按钮区域定义
local back_button = { x1 = 10, y1 = 10, x2 = 80, y2 = 50 }


--[[
绘制自定义字体演示页面;

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

    -- 绘制返回按钮
    lcd.fill(back_button.x1, back_button.y1, back_button.x2, back_button.y2, 0xC618)
    lcd.setColor(0x07E0, 0x0000)
    lcd.drawStr(35, 35, "返回", 0x0000)

    -- 设置默认颜色
    lcd.setColor(0xFFFF, 0x0000)

    -- 显示标题(使用系统字体)
    lcd.drawStr(106, 20 + 12, "自定义点阵字体演示", 0x0000)

    -- 设置自定义字体文件
    lcd.setFontFile("/luadb/customer_font_24.bin")

    lcd.drawStr(112, 206, "上海合宙", 0xF800) -- 红色
    lcd.drawStr(120, 240, "LuatOS", 0x07E0) -- 绿色
    lcd.drawStr(100, 274, "演示demo", 0x001F) -- 蓝色

    -- 恢复系统字体显示说明
    lcd.setFont(lcd.font_opposansm12_chinese)
    lcd.setColor(0xFFFF, 0x0000)

    -- 显示说明信息
    lcd.drawStr(20, 410, "- 字体路径: /luadb/customer_font_24.bin", 0x0000)
    -- 显示使用说明
    lcd.drawStr(20, 430, "使用接口:", 0x0000)
    lcd.drawStr(20, 450, "lcd.setFontFile(字体路径)", 0x0000)
    lcd.drawStr(20, 470, "lcd.drawStr(x, y,文本)", 0x0000)
end

--[[
处理自定义字体页面触摸事件;

@api customer_font_page.handle_touch(x, y, switch_page)
@number x 触摸点X坐标,范围0-319
@number y 触摸点Y坐标,范围0-479
@function switch_page 页面切换回调函数
@return boolean 事件处理成功返回true,否则返回false
]]
function customer_font_page.handle_touch(x, y, switch_page)
    -- 检查返回按钮
    if x >= back_button.x1 and x <= back_button.x2 and
        y >= back_button.y1 and y <= back_button.y2 then
        switch_page("home")
        return true
    end

    return false
end

--[[
页面离开时恢复系统字体;

@api customer_font_page.on_leave()
@summary 恢复系统默认字体设置
@return nil
]]
function customer_font_page.on_leave()
    -- 恢复使用12号中文字体
    lcd.setFont(lcd.font_opposansm12_chinese)
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"


-- 加载触摸面板驱动管理功能模块,有以下两种:
-- 1、使用tp核心库驱动的tp_drv.lua
-- 2、使用extp扩展库驱动的extp_drv.lua
-- 根据自己的需求,启用两者中的任何一种都可以
-- 也可以不启用任何一种,不使用触摸面板功能
tp_drv = require "tp_drv"
-- tp_drv = require "extp_drv"


-- 加载字库驱动管理功能模块,有以下两种:
-- 1、使用hzfont核心库驱动内核固件中支持的软件矢量字库的hzfont_drv.lua(正在开发中,后续补充)
-- 2、使用自定义字体
-- 根据自己的需求,启用两者中的任何几种都可以
-- 也可以不启用任何一种,只使用内核固件中自带的点阵字库
-- require "hzfont_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. 查看系统功能概览信息
  3. 点击各功能按钮进入对应演示页面

8.4.2 LCD演示页面

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

8.4.3 自定义字体页面

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

8.4 预期效果

  • 主页面:正常显示,三个功能按钮响应灵敏
  • LCD演示页面:图形绘制清晰,图片和二维码显示正常,颜色示例完整
  • 自定义字体页面:外部字体加载正确,多颜色文字显示正常
  • 触摸交互:所有触摸操作响应及时准确,页面切换流畅

九、常见问题

  1. 显示异常:检查LCD接线是否正确,确认电源供电稳定
  2. 触摸无响应:检查I2C接线,确认触摸芯片初始化成功
  3. 字体显示异常:确认字体文件路径正确
  4. 图片无法显示:确认图片文件已正确烧录到指定路径
  5. 系统卡顿:检查内存使用情况,适当调整刷新频率