Pārlūkot izejas kodu

add:新增Air8101搭配AirLCD_1020使用lcd核心库开发demo

江访 1 mēnesi atpakaļ
vecāks
revīzija
68b0d528df

+ 3 - 0
module/Air8101/demo/accessory_board/AirLCD_1020/lcd/font_drv/customer_font_drv.lua

@@ -0,0 +1,3 @@
+--[[ 
+说明:customer_font_drv是用户外部自定义外部点阵字体驱动功能模块,目前正在开发中。。。
+]]

+ 50 - 0
module/Air8101/demo/accessory_board/AirLCD_1020/lcd/font_drv/gtfont_drv.lua

@@ -0,0 +1,50 @@
+--[[
+@module  gtfont_drv
+@summary GTFont矢量字库驱动模块
+@version 1.0
+@date    2025.12.1
+@author  江访
+@usage
+本模块为GTFont矢量字库驱动功能模块,主要功能包括:
+1、初始化AirFONTS_1000矢量字库小板的SPI接口;
+2、配置SPI通信参数和设备对象;
+3、初始化矢量字库核心功能;
+
+
+说明:
+1、gtfont核心库演示demo,是使用gtfont核心库来驱动合宙AirFONTS_1000矢量字库小板
+2、在主程序mian.lua中require "gtfont_drv"即可执行加载本demo内的演示代码
+3、通过使用gtfont_drv.init()对合宙AirFONTS_1000矢量字库小板进行初始化
+4、通过使用 lcd.drawGtfontUtf8Gray(str,size,gray,x,y)接口在lcd屏幕上灰度显示 UTF8 字符串,支持10-192号字体
+]]
+
+--初始化AirFONTS_1000的SPI配置
+--AirFONTS_1000通过SPI接口(SCK CS MOSI MISO)和主控相连
+--主控设备为SPI主设备,AirFONTS_1000为SPI从设备
+
+--spi_id:number类型;
+--     表示主设备的SPI ID;
+--     取值范围:主控产品上有效的SPI ID值,目前合宙模组的硬件SPI的总线ID只有0/1,部分产品内部占用了SPI0接口可优先选择时SPI1;
+
+--spi_cs:number类型;
+--     表示cs引脚的GPIO ID;
+--     取值范围:主控产品上有效的GPIO ID值,实际使用过程中可根据自己的电路设计选择对应的GPIO编号;
+
+--返回值:成功返回true,失败返回false
+local function init()
+    --创建一个SPI设备对象
+    gtfont_spi = spi.deviceSetup(1 , 3, 0, 0, 8, 20*1000*1000, spi.MSB, 1, 0)
+    log.error("AirFONTS_1000.init", "spi.deviceSetup", type(gtfont_spi))
+    --检查SPI设备对象是否创建成功
+    if type(gtfont_spi) ~= "userdata" then
+        log.error("AirFONTS_1000.init", "spi.deviceSetup error", type(gtfont_spi))
+    end
+
+    --初始化矢量字库
+    if not gtfont.init(gtfont_spi) then
+        log.error("gtfont_drv.init", "gtfont_drv.init error")
+    end
+
+end
+
+init()

+ 1 - 0
module/Air8101/demo/accessory_board/AirLCD_1020/lcd/font_drv/hzfont_drv.lua

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

BIN
module/Air8101/demo/accessory_board/AirLCD_1020/lcd/images/logo.jpg


+ 50 - 0
module/Air8101/demo/accessory_board/AirLCD_1020/lcd/lcd_drv/exlcd_drv.lua

@@ -0,0 +1,50 @@
+--[[
+@module  exlcd_drv
+@summary 扩展LCD显示驱动模块,基于exlcd扩展库
+@version 1.0
+@date    2025.12.1
+@author  江访
+@usage
+本模块为扩展LCD显示驱动功能模块,主要功能包括:
+1、初始化AirLCD_1020扩展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_1020扩展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_1020"})
+
+    if result then
+        -- 开启缓冲区, 刷屏速度会加快, 但也消耗2倍屏幕分辨率的内存
+        lcd.setupBuff(nil, true)
+        lcd.autoFlush(false)
+    end
+
+    return result
+end
+
+return exlcd_drv

+ 69 - 0
module/Air8101/demo/accessory_board/AirLCD_1020/lcd/lcd_drv/lcd_drv.lua

@@ -0,0 +1,69 @@
+--[[
+@module  lcd_drv
+@summary LCD显示驱动模块,基于lcd核心库
+@version 1.0
+@date    2025.12.1
+@author  江访
+@usage
+本模块为LCD显示驱动功能模块,主要功能包括:
+1、初始化AirLCD_1020 LCD屏幕;
+2、配置LCD显示参数和显示缓冲区;
+3、支持多种屏幕方向和分辨率设置;
+
+对外接口:
+1、lcd_drv.init():初始化LCD显示驱动
+]]
+
+
+local lcd_drv = {}
+
+--[[
+初始化LCD显示驱动;
+
+@api lcd_drv.init()
+@summary 配置并初始化AirLCD_1020 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("nv3052c",
+        {
+            pin_pwr = 8,              -- 背光控制引脚GPIO端口号
+            port = lcd.RGB,           -- 驱动端口
+            direction = 0,            -- lcd屏幕方向 0:0° 1:90° 2:180° 3:270°,屏幕方向和分辨率保存一致
+            w = 800,                  -- lcd 水平分辨率
+            h = 480,                  -- lcd 竖直分辨率
+            xoffset = 0,              -- x偏移(不同屏幕ic 不同屏幕方向会有差异)
+            yoffset = 0,              -- y偏移(不同屏幕ic 不同屏幕方向会有差异)
+            bus_speed = 30 * 1000 * 1000, -- SPI总线速度,不填默认50M,若速率要求更高需要进行设置
+            hbp = 8,                  -- 水平后廊
+            hspw = 4,                 -- 水平同步脉冲宽度
+            hfp = 8,                  -- 水平前廊
+            vbp = 16,                 -- 垂直后廊
+            vspw = 4,                 -- 垂直同步脉冲宽度
+            vfp = 16,                 -- 垂直前廊
+        })
+
+    log.info("lcd.init", result)
+
+    if result then
+        -- 开启缓冲区, 刷屏速度会加快, 但也消耗2倍屏幕分辨率的内存
+        lcd.setupBuff(nil, true)
+        lcd.autoFlush(false)
+
+        -- 开启背光引脚供电
+        gpio.setup(8,1)
+    end
+    return result
+end
+
+return lcd_drv

+ 48 - 0
module/Air8101/demo/accessory_board/AirLCD_1020/lcd/tp_key_drv/extp_drv.lua

@@ -0,0 +1,48 @@
+--[[
+@module  extp_drv
+@summary 扩展触摸面板驱动模块,基于extp扩展库
+@version 1.0
+@date    2025.12.1
+@author  江访
+@usage
+本模块为扩展触摸面板驱动功能模块,主要功能包括:
+1、初始化AirLCD_1020扩展触摸面板;
+2、配置I2C通信接口和触摸参数;
+3、发布触摸事件消息供UI系统处理;
+
+说明:
+成功执行extp_drv.init()之后,在触摸面板上有触摸动作时,在extp扩展库内,默认会发布以下消息:
+1、sys.publish("BASE_TOUCH_EVENT", "SINGLE_TAP", x, y) --单击消息,x和y表示坐标
+2、sys.publish("BASE_TOUCH_EVENT", "LONG_PRESS", x, y) --长按消息,x和y表示坐标
+如果需要发布上下左右滑动、移动、原始数据几种消息,参考extp扩展库中的extp.set_publish_enabled(msg_type, enabled)进行设置
+
+对外接口:
+1、extp_drv.init():初始化扩展触摸面板驱动
+]]
+
+local extp = require "extp"
+
+local extp_drv = {}
+
+--[[
+初始化扩展触摸面板驱动;
+
+@api extp_drv.init()
+@summary 配置并初始化AirLCD_1020扩展触摸面板
+@return boolean 初始化成功返回true,失败返回false
+
+@usage
+-- 初始化扩展触摸面板
+local result = extp_drv.init()
+if result then
+    log.info("扩展触摸面板初始化成功")
+else
+    log.error("扩展触摸面板初始化失败")
+end
+]]
+
+function extp_drv.init()
+    extp.init({ tp_model = "AirLCD_1020" })
+end
+
+return extp_drv

+ 69 - 0
module/Air8101/demo/accessory_board/AirLCD_1020/lcd/tp_key_drv/tp_drv.lua

@@ -0,0 +1,69 @@
+--[[
+@module  tp_drv
+@summary 触摸面板驱动模块,基于tp核心库
+@version 1.0
+@date    2025.12.1
+@author  江访
+@usage
+本模块为触摸面板驱动功能模块,主要功能包括:
+1、初始化GT911触摸控制器;
+2、配置I2C通信接口和触摸回调函数;
+3、发布触摸事件消息供UI系统处理;
+
+对外接口:
+1、tp_drv.init():初始化触摸面板驱动
+]]
+
+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,接口i2c.createSoft(scl, sda, delay)
+    local result = i2c.createSoft(0, 1)
+
+    if type(result) ~= "userdata" then
+        log.error("tp_drv.init i2c.createSoft error")
+        return false
+    end
+    -- 此处触摸IC数据读取使用的是软件I2C接口
+    result = tp.init("gt911", { port = result, pin_rst = 28, pin_int = 7, w = 800, h = 480 }, tp_callback)
+
+    log.info("tp.init", result)
+
+    return result
+end
+
+return tp_drv

+ 91 - 0
module/Air8101/demo/accessory_board/AirLCD_1020/lcd/ui/customer_font_page.lua

@@ -0,0 +1,91 @@
+--[[
+@module  customer_font_page
+@summary 自定义字体演示模块
+@version 1.0
+@date    2025.12.1
+@author  江访
+@usage
+本模块为自定义字体演示功能模块,主要功能包括:
+1、展示外部自定义字体文件的使用方法;
+2、演示不同颜色的字体显示效果;
+3、提供字体文件路径和使用接口说明;
+4、支持页面离开时恢复系统默认字体;
+
+对外接口:
+1、customer_font_page.draw():绘制自定义字体演示页面
+2、customer_font_page.handle_touch():处理自定义字体页面触摸事件
+3、customer_font_page.on_leave():页面离开时恢复系统字体
+]]
+
+local customer_font_page = {}
+
+-- 屏幕尺寸
+local width, height
+
+local center_x
+
+-- 按钮区域定义
+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()
+
+    width, height = lcd.getSize()
+    center_x = width / 2
+    
+    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(0xFFFF, 0x0000)
+    lcd.drawStr(35, 35, "返回", 0x0000)
+
+    -- 设置默认颜色
+    lcd.setColor(0xFFFF, 0x0000)
+
+    -- 显示标题(居中显示)
+    -- 后续V2020版本以上支持lcd核心库的固件会新增lcd.getStrWidth(title)接口获取文本宽度,对齐、居中、换行可使用
+    -- lcd.drawStr(center_x - lcd.getStrWidth(title) / 2, 50, title, 0x0000) -- 自动居中
+    lcd.drawStr(center_x - 80, 30, "自定义点阵字体Air8101正在开发中...", 0x0000)
+end
+
+--[[
+处理自定义字体页面触摸事件;
+
+@api customer_font_page.handle_touch(x, y, switch_page)
+@number x 触摸点X坐标,范围0-799
+@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

+ 332 - 0
module/Air8101/demo/accessory_board/AirLCD_1020/lcd/ui/gtfont_page.lua

@@ -0,0 +1,332 @@
+--[[
+@module  gtfont_page
+@summary GTFont矢量字体演示模块
+@version 1.1
+@date    2025.12.1
+@author  江访
+@usage
+本模块为GTFont矢量字体演示功能模块,主要功能包括:
+1、展示AirFONTS_1000矢量字库小板的字体显示功能;
+2、支持10-192号字体大小动态变化演示;
+3、支持灰度模式和常规模式切换;
+4、提供倒计时和字体大小变化两种演示阶段;
+
+对外接口:
+1、gtfont_page.draw():绘制GTFont演示页面
+2、gtfont_page.handle_touch():处理GTFont页面触摸事件
+3、gtfont_page.on_enter():页面进入时状态重置
+]]
+local gtfont_page = {}
+
+-- 按钮区域定义
+local back_button = { x1 = 10, y1 = 10, x2 = 80, y2 = 50 }
+local switch_button = { x1 = 650, y1 = 10, x2 = 740, y2 = 50 }
+
+-- 字体显示状态
+local font_demo_state = {
+    use_gray = true,                   -- 默认为灰度模式
+    demo_phase = 1,                    -- 演示阶段
+    last_update = 0,
+    update_interval = 1000,            -- 倒计时更新间隔
+    font_update_interval = 20,         -- 字体更新间隔
+    countdown = 18,                     -- 倒计时
+    current_size = 16,                 -- 当前字体大小
+    color_phase = 1,                   -- 颜色阶段
+}
+
+--[[
+绘制开关按钮
+@local
+@return nil
+]]
+local function draw_switch_button()
+    -- 按钮背景
+    lcd.fill(switch_button.x1, switch_button.y1, switch_button.x2, switch_button.y2, 0xC618)
+
+    -- 开关指示器
+    if font_demo_state.use_gray then
+        -- 灰度模式,左边填充
+        lcd.fill(switch_button.x1, switch_button.y1,
+            switch_button.x1 + (switch_button.x2 - switch_button.x1) / 2,
+            switch_button.y2, 0x07E0)
+    else
+        -- 常规模式,右边填充
+        lcd.fill(switch_button.x1 + (switch_button.x2 - switch_button.x1) / 2,
+            switch_button.y1, switch_button.x2, switch_button.y2, 0x07E0)
+    end
+
+    -- 按钮文字
+    lcd.setColor(0xFFFF, 0x0000)
+    lcd.setFont(lcd.font_opposansm12_chinese)
+    lcd.drawStr(switch_button.x1 + 10, switch_button.y1 + 25, "灰度", 0x0000)
+    lcd.drawStr(switch_button.x1 + (switch_button.x2 - switch_button.x1) / 2 + 10,
+        switch_button.y1 + 25, "常规", 0x0000)
+end
+
+--[[
+绘制返回按钮
+@local
+@return nil
+]]
+local function draw_back_button()
+    lcd.fill(back_button.x1, back_button.y1, back_button.x2, back_button.y2, 0xC618)
+    lcd.setColor(0xFFFF, 0x0000)
+    lcd.setFont(lcd.font_opposansm12_chinese)
+    lcd.drawStr(back_button.x1 + 25, back_button.y1 + 25, "返回", 0x0000)
+end
+
+--[[
+绘制倒计时阶段
+@local
+@return boolean 是否完成倒计时
+]]
+local function draw_countdown_phase()
+    local _, current_time = mcu.ticks2(1)
+    
+    if current_time - font_demo_state.last_update > font_demo_state.update_interval then
+        font_demo_state.countdown = font_demo_state.countdown - 1
+        font_demo_state.last_update = current_time
+        
+        if font_demo_state.countdown <= 0 then
+            font_demo_state.demo_phase = 2
+            font_demo_state.current_size = 16
+            font_demo_state.color_phase = 1
+            font_demo_state.last_update = current_time
+            return true
+        end
+    end
+    
+    -- 设置背景色为白色,文字的前景色为黑色
+    lcd.setColor(0xFFFF, 0x0000)
+    if font_demo_state.use_gray then
+        lcd.drawGtfontUtf8Gray("AirFONTS_1000配件板", 32, 2, 250, 70)
+    else
+        lcd.drawGtfontUtf8("AirFONTS_1000配件板", 32, 250, 70)
+    end
+
+    -- 设置背景色为白色,文字的前景色为红色
+    lcd.setColor(0xFFFF, 0xF800)
+    if font_demo_state.use_gray then
+        lcd.drawGtfontUtf8Gray("支持10到192号的黑体字体", 32, 2, 228, 122)
+    else
+        lcd.drawGtfontUtf8("支持10到192号的黑体字体", 32, 228, 122)
+    end
+
+    -- 设置背景色为白色,文字的前景色为绿色
+    lcd.setColor(0xFFFF, 0x07E0)
+    if font_demo_state.use_gray then
+        lcd.drawGtfontUtf8Gray("支持GBK中文和ASCII码字符集", 32, 2, 188, 174)
+    else
+        lcd.drawGtfontUtf8("支持GBK中文和ASCII码字符集", 32, 188, 174)
+    end
+
+    -- 设置背景色为白色,文字的前景色为蓝色
+    lcd.setColor(0xFFFF, 0x001F)
+    if font_demo_state.use_gray then
+        lcd.drawGtfontUtf8Gray("支持灰度显示,字体边缘更平滑", 32, 2, 190, 226)
+    else
+        lcd.drawGtfontUtf8("支持灰度显示,字体边缘更平滑", 32, 190, 226)
+    end
+
+    -- 倒计时
+    lcd.setColor(0xFFFF, 0x0000)
+    if font_demo_state.use_gray then
+        lcd.drawGtfontUtf8Gray("倒计时 : " .. font_demo_state.countdown, 24, 2, 340, 278)
+    else
+        lcd.drawGtfontUtf8("倒计时 : " .. font_demo_state.countdown, 24, 340, 278)
+    end
+    
+    return false
+end
+
+--[[
+绘制字体大小变化阶段
+@local
+@return boolean 是否完成所有阶段
+]]
+local function draw_font_size_phase()
+    local _, current_time = mcu.ticks2(1)
+    
+    if current_time - font_demo_state.last_update > font_demo_state.font_update_interval then
+        font_demo_state.current_size = font_demo_state.current_size + 1
+        font_demo_state.last_update = current_time
+    end
+    
+    -- 根据颜色阶段设置颜色
+    if font_demo_state.color_phase == 1 then
+        lcd.setColor(0xFFFF, 0x0000) -- 黑色
+    elseif font_demo_state.color_phase == 2 then
+        lcd.setColor(0xFFFF, 0xF800) -- 红色
+    elseif font_demo_state.color_phase == 3 then
+        lcd.setColor(0xFFFF, 0x07E0) -- 绿色
+    else
+        lcd.setColor(0xFFFF, 0x001F) -- 蓝色
+    end
+    
+    -- 根据颜色阶段和字体大小显示不同内容
+    if font_demo_state.color_phase == 1 then
+        if font_demo_state.current_size <= 64 then
+            if font_demo_state.use_gray then
+                lcd.drawGtfontUtf8Gray(font_demo_state.current_size .. "号:合宙AirFONTS_1000", 
+                                      font_demo_state.current_size, 4, 10, 100)
+            else
+                lcd.drawGtfontUtf8(font_demo_state.current_size .. "号:合宙AirFONTS_1000", 
+                                  font_demo_state.current_size, 10, 100)
+            end
+        else
+            font_demo_state.color_phase = 2
+            font_demo_state.current_size = 65
+        end
+    elseif font_demo_state.color_phase == 2 then
+        if font_demo_state.current_size <= 96 then
+            if font_demo_state.use_gray then
+                lcd.drawGtfontUtf8Gray(font_demo_state.current_size .. "号", 
+                                      font_demo_state.current_size, 4, 10, 100)
+                lcd.drawGtfontUtf8Gray("AirFONTS_1000", 
+                                      font_demo_state.current_size, 4, 10, 100 + font_demo_state.current_size + 5)
+            else
+                lcd.drawGtfontUtf8(font_demo_state.current_size .. "号", 
+                                  font_demo_state.current_size, 10, 100)
+                lcd.drawGtfontUtf8("AirFONTS_1000", 
+                                  font_demo_state.current_size, 10, 100 + font_demo_state.current_size + 5)
+            end
+        else
+            font_demo_state.color_phase = 3
+            font_demo_state.current_size = 97
+        end
+    elseif font_demo_state.color_phase == 3 then
+        if font_demo_state.current_size <= 128 then
+            if font_demo_state.use_gray then
+                lcd.drawGtfontUtf8Gray(font_demo_state.current_size .. "号", 
+                                      font_demo_state.current_size, 4, 210, 50)
+                lcd.drawGtfontUtf8Gray("合宙", 
+                                      font_demo_state.current_size, 4, 210, 50 + font_demo_state.current_size + 5)
+            else
+                lcd.drawGtfontUtf8(font_demo_state.current_size .. "号", 
+                                  font_demo_state.current_size, 210, 50)
+                lcd.drawGtfontUtf8("合宙", 
+                                  font_demo_state.current_size, 210, 50 + font_demo_state.current_size + 5)
+            end
+        else
+            font_demo_state.color_phase = 4
+            font_demo_state.current_size = 129
+        end
+    else
+        if font_demo_state.current_size <= 192 then
+            -- 矢量字体大小目前不能到180号,常规字体可到192号
+            -- if font_demo_state.use_gray then
+            --     lcd.drawGtfontUtf8Gray(font_demo_state.current_size .. "号", 
+            --                           font_demo_state.current_size, 4, 10, 50)
+            --     lcd.drawGtfontUtf8Gray("合宙", 
+            --                           font_demo_state.current_size, 4, 10, 50 + font_demo_state.current_size + 5)
+            -- else
+                lcd.drawGtfontUtf8(font_demo_state.current_size .. "号", 
+                                  font_demo_state.current_size, 210, 50)
+                lcd.drawGtfontUtf8("合宙", 
+                                  font_demo_state.current_size, 210, 50 + font_demo_state.current_size + 5)
+            -- end
+        else
+            -- 所有阶段完成,重置
+            font_demo_state.demo_phase = 1
+            font_demo_state.countdown = 5
+            font_demo_state.color_phase = 1
+            font_demo_state.current_size = 16
+            return true
+        end
+    end
+    
+    return false
+end
+
+--[[
+绘制字体演示内容
+@local
+@return nil
+]]
+local function draw_font_demo()
+    -- 根据演示阶段调用不同的绘制函数
+    if font_demo_state.demo_phase == 1 then
+        draw_countdown_phase()
+    else
+        draw_font_size_phase()
+    end
+end
+
+--[[
+绘制GTFont演示页面;
+
+@api gtfont_page.draw()
+@summary 绘制GTFont演示页面的所有UI元素和字体演示内容
+@return nil
+]]
+function gtfont_page.draw()
+    lcd.clear()
+    -- 绘制按钮区域
+    draw_back_button()
+    draw_switch_button()
+
+    -- 绘制字体演示内容
+    draw_font_demo()
+
+    lcd.flush()
+end
+
+--[[
+处理GTFont页面触摸事件;
+
+@api gtfont_page.handle_touch(x, y, switch_page)
+@number x 触摸点X坐标,范围0-799
+@number y 触摸点Y坐标,范围0-479
+@function switch_page 页面切换回调函数
+@return boolean 事件处理成功返回true,否则返回false
+]]
+function gtfont_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
+
+    -- 检查切换按钮
+    if x >= switch_button.x1 and x <= switch_button.x2 and
+        y >= switch_button.y1 and y <= switch_button.y2 then
+        font_demo_state.use_gray = not font_demo_state.use_gray
+        return true
+    end
+
+    return false
+end
+
+--[[
+页面进入时重置状态;
+
+@api gtfont_page.on_enter()
+@summary 重置字体演示状态到初始值
+@return nil
+]]
+function gtfont_page.on_enter()
+    font_demo_state.use_gray = true -- 默认灰度模式
+    font_demo_state.demo_phase = 1
+    font_demo_state.countdown = 18
+    font_demo_state.current_size = 16
+    font_demo_state.color_phase = 1
+    local _, ms_l = mcu.ticks2(1)
+    font_demo_state.last_update = ms_l
+    frame_time = 20 -- 进入时改成20ms刷新一次
+end
+
+
+--[[
+页面离开时恢复系统刷新率;
+
+@api gtfont_page.on_leave()
+@summary 恢复刷新率
+@return nil
+]]
+function gtfont_page.on_leave()
+    -- 恢复恢复20S刷新一次
+    frame_time = 20*1000
+end
+
+return gtfont_page

+ 112 - 0
module/Air8101/demo/accessory_board/AirLCD_1020/lcd/ui/home_page.lua

@@ -0,0 +1,112 @@
+--[[
+@module  home_page
+@summary 主页模块,提供应用入口和导航功能
+@version 1.1
+@date    2025.12.1
+@author  江访
+@usage
+本模块为主页面功能模块,主要功能包括:
+1、绘制主页面UI界面,显示应用标题和功能介绍;
+2、提供三个功能按钮:LCD演示、矢量字体演示、自定义字体演示;
+3、处理主页面的触摸事件,实现页面导航;
+
+对外接口:
+1、home_page.draw():绘制主页界面
+2、home_page.handle_touch():处理主页触摸事件
+]]
+
+local home_page = {}
+
+-- 屏幕尺寸
+local width, height
+
+local center_x
+
+-- 按钮区域定义(适配800x480)
+local buttons = {
+    lcd_page = { x1 = 100, y1 = 350, x2 = 250, y2 = 430 },
+    gtfont_page = { x1 = 300, y1 = 350, x2 = 450, y2 = 430 },
+    customer_font_page = { x1 = 500, y1 = 350, x2 = 650, y2 = 430 }
+}
+
+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)
+
+    width, height = lcd.getSize()
+    center_x = width / 2
+
+    -- 显示标题(居中)
+    -- 后续V2020版本以上支持lcd核心库的固件会新增lcd.getStrWidth(title)接口获取文本宽度,对齐、居中、换行可使用
+    -- lcd.drawStr(center_x - lcd.getStrWidth(title) / 2, 50, title, 0x0000) -- 自动居中
+    lcd.drawStr(center_x - 70, 50, title, 0x0000)
+
+    -- 显示说明文字
+    lcd.drawStr(center_x - 130, 90, content1, 0x0000)
+
+    -- 添加演示说明
+    lcd.drawStr(center_x - 75, 120, "屏幕尺寸: " .. width .. "x" .. height, 0x0000)
+
+    -- 绘制LCD演示按钮
+    lcd.fill(buttons.lcd_page.x1, buttons.lcd_page.y1,
+        buttons.lcd_page.x2, buttons.lcd_page.y2, 0x001F)
+    lcd.setColor(0xFFFF, 0x0000)
+    lcd.drawStr(buttons.lcd_page.x1 + 45, buttons.lcd_page.y1 + 45, "LCD演示", 0xFFFF)
+
+    -- 绘制GTFont演示按钮
+    lcd.fill(buttons.gtfont_page.x1, buttons.gtfont_page.y1,
+        buttons.gtfont_page.x2, buttons.gtfont_page.y2, 0xF800)
+    lcd.drawStr(buttons.gtfont_page.x1 + 35, buttons.gtfont_page.y1 + 45, "矢量字体演示", 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(buttons.customer_font_page.x1 + 35, buttons.customer_font_page.y1 + 45, "自定义字体演示", 0xFFFF)
+end
+
+--[[
+处理主页触摸事件;
+
+@api home_page.handle_touch(x, y, switch_page)
+@number x 触摸点X坐标,范围0-799
+@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
+
+    -- 检查GTFont演示按钮
+    if x >= buttons.gtfont_page.x1 and x <= buttons.gtfont_page.x2 and
+        y >= buttons.gtfont_page.y1 and y <= buttons.gtfont_page.y2 then
+        switch_page("gtfont")
+        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

+ 144 - 0
module/Air8101/demo/accessory_board/AirLCD_1020/lcd/ui/lcd_page.lua

@@ -0,0 +1,144 @@
+--[[
+@module  lcd_page
+@summary LCD图形绘制演示模块
+@version 1.0
+@date    2025.12.1
+@author  江访
+@usage
+本模块为LCD图形绘制演示功能模块,主要功能包括:
+1、展示LCD核心库的基本图形绘制功能;
+2、演示点、线、矩形、圆形等基本图形绘制;
+3、显示图片和二维码生成功能;
+4、提供颜色示例展示;
+
+对外接口:
+1、lcd_page.draw():绘制LCD演示页面
+2、lcd_page.handle_touch():处理LCD页面触摸事件
+]]
+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(364, 20 + 12, "lcd核心库演示", 0x0000)
+
+    -- 绘制各种图形
+    lcd.drawStr(20, 60 + 12, "基本图形绘制:", 0x0000)
+
+    -- 绘制点
+    lcd.drawPoint(30, 100, 0xFCC0)
+    lcd.drawPoint(40, 100, 0x07E0)
+    lcd.drawPoint(50, 100, 0x001F)
+
+    -- 绘制线
+    lcd.drawLine(70, 90, 150, 90, 0xFCC0)
+    lcd.drawLine(70, 100, 150, 110, 0x07E0)
+    lcd.drawLine(70, 110, 150, 90, 0x001F)
+
+    -- 绘制矩形
+    lcd.drawRectangle(170, 90, 220, 120, 0x7296)
+    lcd.fill(230, 90, 280, 120, 0x07E0)
+
+    -- 绘制圆
+    lcd.drawCircle(100, 180, 25, 0x001F)
+    lcd.drawCircle(180, 180, 25, 0xFCC0)
+
+    -- 显示图片示例文字
+    -- 注意, jpg需要是常规格式, 不能是渐进式JPG
+    -- 如果无法解码, 可以用画图工具另存为,新文件就能解码了
+    lcd.drawStr(20, 220 + 12, "图片显示区域", 0x0000)
+    lcd.drawRectangle(20, 240, 150, 370, 0x0000)
+    lcd.showImage(45, 265, "/luadb/logo.jpg")
+
+    -- 显示二维码示例文字
+    lcd.drawStr(170, 220 + 12, "二维码区域", 0x0000)
+    lcd.drawRectangle(170, 240, 300, 370, 0x0000)
+    lcd.drawQrcode(185, 255, "https://docs.openluat.com/air8101/", 100)
+
+    -- 显示颜色示例
+    lcd.drawStr(20, 390 + 12, "颜色示例:", 0x0000)
+    lcd.fill(100, 390, 120, 410, 0xF800)
+    lcd.fill(130, 390, 150, 410, 0x07E0)
+    lcd.fill(160, 390, 180, 410, 0x001F)
+    lcd.fill(190, 390, 210, 410, 0xFCC0)
+    lcd.fill(220, 390, 240, 410, 0x0000)
+
+    -- 位图示例
+    lcd.drawStr(420, 60 + 12, "绘制 XBM 格式位图:", 0x0000)
+    -- 在位置(520,82)绘制一个16x16的位图,内容依次为“上”,“海”,“合”,“宙”
+    -- 位图数据使用字符串格式表示
+    lcd.drawXbm(420, 88, 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(420 + 18, 88, 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(420 + 36, 88, 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(420 + 54, 88, 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.setFont(lcd.font_opposansm12_chinese)
+    lcd.drawStr(420, 220 + 12, "英文字体示例:", 0x0000)
+    lcd.setFont(lcd.font_opposansm12)
+    lcd.drawStr(420, 249, "ABC abc 0123456789") --显示字符
+    lcd.setFont(lcd.font_opposansm16)
+    lcd.drawStr(420, 266, "ABC abc 0123456789") --显示字符
+    lcd.setFont(lcd.font_opposansm18)
+    lcd.drawStr(420, 287, "ABC abc 0123456789") --显示字符
+    lcd.setFont(lcd.font_opposansm20)
+    lcd.drawStr(420, 310, "ABC abc 0123456789") --显示字符
+    lcd.setFont(lcd.font_opposansm22)
+    lcd.drawStr(420, 337, "ABC abc 0123456789") --显示字符
+    lcd.setFont(lcd.font_opposansm24)
+    lcd.drawStr(420, 366, "ABC abc 0123456789") --显示字符
+    lcd.setFont(lcd.font_opposansm32)
+    lcd.drawStr(420, 403, "ABC abc 0123456789") --显示字符
+end
+
+--[[
+处理LCD页面触摸事件;
+
+@api lcd_page.handle_touch(x, y, switch_page)
+@number x 触摸点X坐标,范围0-799
+@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

+ 149 - 0
module/Air8101/demo/accessory_board/AirLCD_1020/lcd/ui/ui_main.lua

@@ -0,0 +1,149 @@
+--[[
+@module  ui_main
+@summary 用户界面主控模块,负责页面管理和事件分发
+@version 1.0
+@date    2025.12.1
+@author  江访
+@usage
+本模块为核心UI控制模块,主要功能包括:
+1、初始化LCD显示和触摸面板驱动;
+2、管理多个页面之间的切换逻辑;
+3、分发触摸事件到各个页面处理;
+4、维护页面状态和生命周期管理;
+
+对外接口:
+1、ui_main():主UI任务入口函数
+2、switch_page():页面切换函数
+3、handle_touch_event():触摸事件处理函数
+]]
+
+-- 加载子页面
+local home_page = require "home_page"
+local lcd_page = require "lcd_page"
+local gtfont_page = require "gtfont_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", "gtfont", "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 == "gtfont" and gtfont_page.on_leave then
+        gtfont_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 == "gtfont" and gtfont_page.on_enter then
+        gtfont_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-799
+@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 == "gtfont" then
+            return gtfont_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 == "gtfont" then
+            gtfont_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)