跳转至

LCD屏驱动

一、LCD 概述:

LCD(Liquid Crystal Display,液晶显示器)是嵌入式系统中常用的显示设备,广泛应用于智能家居、工业控制、医疗设备、消费电子等领域。以下是 LCD 的详细介绍:

1.1 嵌入式 LCD 的基本原理

LCD 通过控制液晶分子的排列来改变光的透过率,从而显示图像或文字。其核心组成部分包括:

  • 液晶层:通过电场控制液晶分子的排列
  • 背光模块:提供光源(如 LED 背光)
  • 驱动电路:控制液晶分子的电场和像素的显示
  • 控制芯片:负责处理图像数据并发送给驱动电路

1.2 接口类型

  • SPI(串行接口,适合低引脚数场景)。
  • 8080 并行接口(8/9/16/18 位数据总线,高速传输)
  • RGB 接口(直接驱动 RGB 数据,需搭配时序控制器)
  • MIPI DSI(部分型号支持,用于高性能移动设备)

1.3 硬件连接示例(SPI 模式)

二、演示功能概述

本例程将使用 Air8000 的 LCD 功能,配合 Air8000 开发板配套的 LCD 屏幕显示内容。

三、准备硬件环境

参考:硬件环境清单第二章节内容,准备以及组装好硬件环境。

3.1 ST7796 LCD 屏幕一个

3.2 8000 与 ST7796 LCD 屏幕 接线图如下

3.3 实物接线图

四、软件环境

“凡事预则立,不预则废。”在详细阐述本功能示例之前,我们需先精心筹备好以下软件环境。

1. Luatools 工具

2. 内核固件文件(底层 core 固件文件):LuatOS-SoC_V2003_Air8000;参考项目使用的内核固件

3. luatos 需要的脚本和资源文件

脚本和资源文件:https://gitee.com/openLuat/LuatOS-Air8000/tree/master/demo/lcd

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

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

五、使用 LCD 软硬件资料:

5.1 LCD 硬件参考资料

Air8000 支持 LCD 接口参考:LCD 参考电路和选型推荐

5.2 API 接口介绍

api 链接地址:lcd-api 地址

lcd.init(tp, args, spi_dev, init_in_service)

lcd 显示屏初始化

参数

返回值

例子

lcd.init("st7796", {
    port = port,
    pin_dc = pin_dc,
    pin_pwr = bl,
    pin_rst = pin_reset,
    direction = 0,
    -- direction0 = 0x00,
    w = 320,
    h = 480,
    xoffset = 0,
    yoffset = 0,
    sleepcmd = 0x10,
    wakecmd = 0x11,
})

lcd.clear(color)

lcd 清屏

参数

返回值

例子

-- lcd清屏lcd.clear()

lcd.drawLine(x0,y0,x1,y1,color)

在两点之间画一条线.

参数

返回值

例子

lcd.drawLine(100, 240, 240, 240, 0x001F)

lcd.drawRectangle(x0,y0,x1,y1,color)

从 x / y 位置(左上边缘)开始绘制一个框

参数

返回值

例子

lcd.drawRectangle(100, 240, 240, 70, 0xF800)

lcd.drawCircle(x0,y0,r,color)

从 x / y 位置(圆心)开始绘制一个圆

参数

返回值

例子

lcd.drawCircle(150, 240, 100, 0x0CE0)

lcd.setFont(font, indentation)

设置字体

参数

返回值

例子

-- 显示之前先设置为中文字体,对之后的drawStr有效
lcd.setFont(lcd.font_opposansm32)
lcd.drawStr(60,240,"hello hezhou") --显示字符
sys.wait(2000)
lcd.setFont(lcd.font_opposansm16_chinese) -- 具体取值可参考api文档的常量表
lcd.drawStr(120,240,"你好合宙")

lcd.drawStr(x,y,str,fg_color)

显示字符串

参数

返回值

例子

-- 显示之前先设置为中文字体,对之后的drawStr有效
lcd.setFont(lcd.font_opposansm32)
lcd.drawStr(60,240,"hello hezhou") --显示字符
sys.wait(2000)
lcd.setFont(lcd.font_opposansm16_chinese) -- 具体取值可参考api文档的常量表,需云编译支持中文大小的固件
lcd.drawStr(60,240,"你好合宙")

lcd.showImage(x, y, file)

显示图片,当前只支持 jpg,jpeg

参数

返回值

例子

lcd.showImage(0,0,"/luadb/logo.jpg")

lcd.flush()

主动刷新数据到界面, 仅设置 buff 且禁用自动属性后使用

参数

返回值

例子

-- 本API与 lcd.setupBuff lcd.autoFlush 配合使用lcd.flush()

lcd.setupBuff(conf, onheap)

设置显示缓冲区, 所需内存大小为 2× 宽 × 高 字节. 请衡量内存需求与业务所需的刷新频次.

参数

返回值

例子

-- 初始化lcd的buff缓冲区, 可理解为FrameBuffer区域.lcd.setupBuff()

lcd.autoFlush(enable)

设置自动刷新, 需配合 lcd.setupBuff 使用

参数

返回值

例子

-- 设置buff 并禁用自动更新lcd.setupBuff()lcd.autoFlush(false)-- 禁止自动更新后, 需要使用 lcd.flush() 主动刷新数据到屏幕

六、代码示例介绍

6.1 代码介绍

PROJECT = "lcddemo"
VERSION = "1.0.0"

log.info("main", PROJECT, VERSION)

-- sys库是标配
sys = require("sys")

-- 添加硬狗防止程序卡死
if wdt then
    wdt.init(9000) -- 初始化watchdog设置为9s
    sys.timerLoopStart(wdt.feed, 3000) -- 3s喂一次狗
end

pm.ioVol(pm.IOVOL_ALL_GPIO, 3000)--所有IO电平开到3V,电平匹配
gpio.setup(28, 1) -- GPIO28打开给lcd电源供电

local rtos_bsp = rtos.bsp()
-- local chip_type = hmeta.chip()
-- 根据不同的BSP返回不同的值
-- 根据不同的BSP返回不同的值
-- spi_id,pin_reset,pin_dc,pin_cs,bl
local function lcd_pin()
    local rtos_bsp = rtos.bsp()
    if string.find(rtos_bsp, "8000") then
        return lcd.HWID_0, 36, 0xff, 0xff, 25 -- 注意:EC718P有硬件lcd驱动接口, 无需使用spi,当然spi驱动也支持
    else
        log.info("main", "没找到合适的cat.1芯片", rtos_bsp)
        return
    end
end

local spi_id, pin_reset, pin_dc, pin_cs, bl = lcd_pin()
if spi_id ~= lcd.HWID_0 then
    spi_lcd = spi.deviceSetup(spi_id, pin_cs, 0, 0, 8, 20 * 1000 * 1000, spi.MSB, 1, 0)
    port = "device"
else
    port = spi_id
end

lcd.init("st7796", {
    port = port,
    pin_dc = pin_dc,
    pin_pwr = bl,
    pin_rst = pin_reset,
    direction = 0,
    -- direction0 = 0x00,
    w = 320,
    h = 480,
    xoffset = 0,
    yoffset = 0,
    sleepcmd = 0x10,
    wakecmd = 0x11,
})

-- 不在内置驱动的, 看demo/lcd_custom

sys.taskInit(function()
    -- 开启缓冲区, 刷屏速度回加快, 但也消耗2倍屏幕分辨率的内存
    -- lcd.setupBuff()          -- 使用lua内存
    lcd.setupBuff(nil, true) -- 使用sys内存, 只需要选一种
    lcd.autoFlush(false)

    while 1 do
        lcd.clear()
        log.info("合宙 8000 LCD演示")
        -- API 文档 https://wiki.luatos.com/api/lcd.html
        if lcd.showImage then
            -- 注意, jpg需要是常规格式, 不能是渐进式JPG
            -- 如果无法解码, 可以用画图工具另存为,新文件就能解码了
            lcd.showImage(0, 0, "/luadb/picture.jpg")
            sys.wait(100)
        end
        -- log.info("lcd.drawLine", lcd.drawLine(100, 240, 240, 240, 0x001F)) -- 画线
        -- log.info("lcd.drawRectangle", lcd.drawRectangle(100, 240, 240, 70, 0xF800)) -- 画框
        -- log.info("lcd.drawCircle", lcd.drawCircle(150, 240, 100, 0x0CE0)) -- 画圆

        -- lcd.setFont(lcd.font_opposansm32)
        -- lcd.drawStr(60,240,"hello hezhou") --显示字符
        -- sys.wait(2000)
        -- lcd.setFont(lcd.font_opposansm16_chinese) -- 具体取值可参考api文档的常量表
        -- lcd.drawStr(60,240,"你好合宙")--显示中文
        lcd.flush()
        sys.wait(1000)
    end
end)

-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!

6.2 结果演示

1.使用 Air8000 开发板 + 分辨率为 320*480 的 LCD 屏幕显示图片,效果如下图所示:

2.使用 Air8000 开发板 + 分辨率为 320*480 的 LCD 屏幕画线,效果如下图所示:

3.使用 Air8000 开发板 + 分辨率为 320*480 的 LCD 屏幕画框,效果如下图所示:

3.使用 Air8000 开发板 + 分辨率为 320*480 的 LCD 屏幕画圆,效果如下图所示:

4.使用 Air8000 开发板 + 分辨率为 320*480 的 LCD 屏幕中文显示,效果如下图所示:

5.使用 Air8000 开发板 + 分辨率为 320*480 的 LCD 屏幕中文显示,效果如下图所示:

6.3 烧录代码注意事项

因为烧录脚本区可用空间有限,所以烧录时仅放置自己所用照片即可

七、总结

本文演示如何在 Air8000 开发板上实现 LCD 屏幕显示图片、中英文和画线,框,圆的功能。

八、常见问题

8.1 注意:中文显示 需要云编译支持中文大小的固件

例如代码中 lcd.setFont(lcd.font_opposansm16_chinese) 云编译选项要选择 u8g2.font_opposansm16_chinese

云编译链接:https://luatos.com/zh_cn/page/home.html

给读者的话

本篇文章描述的内容,如果有错误、细节缺失、细节不清晰或者其他任何问题,总之就是无法解决您遇到的问题;

请登录合宙技术交流论坛,点击文档找错赢奖金;

用截图标注+文字描述的方式跟帖回复,记录清楚您发现的问题;

我们会迅速核实并且修改文档;

同时也会为您累计找错积分,您还可能赢取月度找错奖金!