03-Machine-3-display_and_touch.py K230外接液晶显示屏与电容触摸屏功能演示

display_and_touch.py 为K230外接液晶显示屏与电容触摸屏功能演示程序,实现的效果为在屏幕上随机位置绘制"Hello World!,你好世界!!!"字符串,同时响应触摸事件,在触摸点绘制红色十字。

K230 支持 电容屏电阻屏 的触摸输入,提供了基于 RT-Smart 封装的 TOUCH 类接口。可使用它读取触点坐标、事件类型等信息,广泛应用于 HMI、交互终端等场景。01Studio配套的mipi LCD分无触摸版本和带触摸版本,带触摸版本配的是电容触摸,支持单点和多点触控,使用时直接调用即可。

基本的使用方式如下:

python 复制代码
from machine import TOUCH

# 实例化触摸设备 0
tp = TOUCH(0)

# 可选:启用坐标旋转(旋转 90 度),适配屏幕方向
# tp = TOUCH(0, 1)

# 读取当前触摸点数据
p = tp.read()

# 输出完整的触摸数据结构
print(p)

# 如有触摸点,可访问第一个触点的坐标与事件类型
# print(p[0].x)       # X 坐标
# print(p[0].y)       # Y 坐标
# print(p[0].event)   # 事件类型(如 Touch Down、Move、Up)

接口说明

接口名 说明
TOUCH(id) 创建触摸屏实例,id=0 表示设备号
TOUCH(id, rotate) 实例化并启用屏幕坐标旋转,rotate=1 代表旋转 90 度
read() 返回当前触摸点信息,通常是一个列表结构

示例详解

1. 实例化设备

复制代码
tp = TOUCH(0)

创建 TOUCH 设备对象,表示使用触摸通道 0。

可选参数 TOUCH(0, 1) 用于对坐标做旋转,适用于竖屏方向的设备。

2. 读取触摸数据

复制代码
p = tp.read()
print(p)

返回的 p 通常是一个包含多个触点对象的列表。每个对象包含:

  • x: X 坐标

  • y: Y 坐标

  • event: 触摸事件(如 Touch Down、Move、Touch Up)

3. 示例输出参考

复制代码
[<TouchPoint x=120 y=65 event=0>]

如果有多个触点,例如支持多指操作:

复制代码
[<TouchPoint x=120 y=65 event=0>, <TouchPoint x=250 y=130 event=0>]

应用场景

场景 示例
图形界面交互 基于触摸点驱动按钮点击、滑动切换
自定义手势识别 多点滑动、旋转等操作识别
简单绘图板或签名板 基于触点轨迹做线条绘制

常见问题

Q:没有读取到触摸点,返回是空列表? A:此时说明屏幕未被触摸。tp.read() 只在屏幕被按下时返回触点。

Q:如何处理多点触控? A:读取到的是一个包含多个 TouchPoint 的列表,使用 for 循环逐个读取即可。

Q:是否支持旋转坐标系? A:支持,通过第二个参数 TOUCH(0, 1) 可开启坐标旋转(90 度顺时针)。

显示接口API 介绍

01studio k230 canMV开发板上外接的是01官方提供的ST7701显示驱动器的3.5寸液晶显示屏。

init

描述

初始化 Display 通路,包括 VO 模块、 DSI 模块和 LCD/HDMI。
必须在 MediaManager.init()之前调用

语法

复制代码
init(type=None, width=None, height=None, osd_num=1, to_ide=False, flag=None, fps=None, quality=90)

参数

参数名称 描述 输入 / 输出 说明
type 显示设备类型 输入 必选
width 分辨率宽度 输入 可选参数,默认值根据 type 决定
height 分辨率高度 输入 可选参数,默认值根据 type 决定
osd_num show_image 时支持的 LAYER 数量 输入 越大占用内存越多
to_ide 是否将屏幕显示传输到 IDE 显示 输入 开启时占用更多内存
flag 显示 标志 输入
fps 显示帧率 输入 仅支持 VIRT 类型
quality 设置 Jpeg 压缩质量 输入 仅在 to_ide=True 时有效,范围 [10-100]

返回值

返回值 描述

show_image

描述

在屏幕上显示图像。

语法

复制代码
show_image(img, x=0, y=0, layer=None, alpha=255, flag=None)

参数

参数名称 描述 输入 / 输出 说明
img 显示的图像 输入
x 起始坐标的 x 值 输入
y 起始坐标的 y 值 输入
layer 显示到 指定层 输入 仅支持 OSD 层,若需要多层请在 init 中设置 osd_num
alpha 图层混合 alpha 输入
flag 显示 标志 输入

返回值

返回值 描述

deinit

描述

执行反初始化, deinit 方法会关闭整个 Display 通路,包括 VO 模块、 DSI 模块和 LCD/HDMI。
必须在 MediaManager.deinit()之前调用
必须在 sensor.stop()之后调用

语法

复制代码
deinit()

返回值

返回值 描述

bind_layer

描述

sensorvdec 模块的输出绑定到屏幕显示。无需用户手动干预即可持续显示图像。
必须在 init 之前调用

语法

复制代码
bind_layer(src=(mod, dev, layer), dstlayer, rect=(x, y, w, h), pix_format, alpha, flag)

参数

参数名称 描述 输入 / 输出 说明
src sensorvdec 的输出信息 输入 可通过 sensor.bind_info() 获取
dstlayer 绑定到 Display 的 显示层 输入 可绑定到 videoosd
rect 显示区域 输入 可通过 sensor.bind_info() 获取
pix_format 图像像素格式 输入 可通过 sensor.bind_info() 获取
alpha 图层混合 alpha 输入
flag 显示 标志 输入 LAYER_VIDEO1 不支持

返回值

返回值 描述

width

描述

获取屏幕或某一图层的显示宽度

语法

复制代码
width(layer = None):

参数

参数名称 描述 输入 / 输出 说明
layer 指定获取 显示层 的宽度,如果不传则表示获取屏幕的分辨率宽度

返回值

返回值 描述
width 屏幕或显示层的宽度信息

height

描述

获取屏幕或某一图层的显示高度

语法

复制代码
height(layer = None):

参数

参数名称 描述 输入 / 输出 说明
layer 指定获取 显示层 的高度,如果不传则表示获取屏幕的分辨率高度

返回值

返回值 描述
height 屏幕或显示层的高度信息

数据结构描述

type

类型 参数取值 备注
VIRT 640x480@90 默认值 IDE 调试专用,不在外接屏幕上显示内容 用户可自定义设置分辨率 (64x64)-(4096x4096) 和帧率 (1-200)
DEBUGGER 调试屏幕专用
ST7701 Display.init(Display.ST7701, width = 800, height = 480) 默认值 800x480
Display.init(Display.ST7701, width = 480, height = 800) 480x800
Display.init(Display.ST7701, width = 854, height = 480) 854x480
Display.init(Display.ST7701, width = 480, height = 854) 480x854
Display.init(Display.ST7701, width = 640, height = 480) 640x480
Display.init(Display.ST7701, width = 480, height = 640) 480x640
Display.init(Display.ST7701, width = 368, height = 552) 368x552
Display.init(Display.ST7701, width = 552, height = 368) 552x368
HX8399 Display.init(Display.HX8399, width = 1920, height = 1080) 默认值 1920x1080
Display.init(Display.HX8399, width = 1080, height = 1920) 1920x1080
ILI9806 Display.init(Display.ILI9806, width = 800, height = 480) 默认值 800x480
Display.init(Display.ILI9806, width = 480, height = 800) 480x800
ILI9881 Display.init(Display.ILI9881, width = 1280, height = 800) 默认值 1280x800
Display.init(Display.ILI9881, width = 800, height = 1280) 800x1280
LT9611 Display.init(Display.LT9611, width = 1920, height = 1080, fps = 30) 默认值 1920x1080@30
Display.init(Display.LT9611, width = 1920, height = 1080, fps = 60) 1920x1080@60
Display.init(Display.LT9611, width = 1280, height = 720, fps = 60) 1280x720@60
Display.init(Display.LT9611, width = 1280, height = 720, fps = 50) 1280x720@50
Display.init(Display.LT9611, width = 1280, height = 720, fps = 30) 1280x720@30
Display.init(Display.LT9611, width = 640, height = 480, fps = 60) 640x480@60

layer

K230 提供 2 层视频图层支持和 4 层 OSD 图层支持。分列如下:

显示层 说明 备注
LAYER_VIDEO1 仅可在 bind_layer 中使用,支持硬件旋转
LAYER_VIDEO2 仅可在 bind_layer 中使用,不支持硬件旋转
LAYER_OSD0 支持 show_imagebind_layer 使用
LAYER_OSD1 支持 show_imagebind_layer 使用
LAYER_OSD2 支持 show_imagebind_layer 使用
LAYER_OSD3 支持 show_imagebind_layer 使用

flag

标志 说明 备注
FLAG_ROTATION_0 旋转 0
FLAG_ROTATION_90 旋转 90
FLAG_ROTATION_180 旋转 180
FLAG_ROTATION_270 旋转 270
FLAG_MIRROR_NONE 不镜像
FLAG_MIRROR_HOR 水平镜像
FLAG_MIRROR_VER 垂直镜像
FLAG_MIRROR_BOTH 水平与垂直镜像

导入模块

复制代码
import time, os, urandom, sys
from media.display import *
from media.media import *
from machine import TOUCH
  • time: 用于时间控制

  • os: 操作系统接口

  • urandom: 生成随机数

  • media.displaymedia.media: 显示和媒体相关功能

  • TOUCH: 触摸屏驱动

常量定义

复制代码
DISPLAY_WIDTH = ALIGN_UP(800, 16)  # 显示宽度,对齐到16像素
DISPLAY_HEIGHT = 480               # 显示高度

初始化

复制代码
tp = TOUCH(0)  # 初始化触摸屏设备0

主函数 display_test()

1. 图像缓冲区创建

复制代码
img = image.Image(DISPLAY_WIDTH, DISPLAY_HEIGHT, image.ARGB8888)
img2 = image.Image(DISPLAY_WIDTH, DISPLAY_HEIGHT, image.ARGB8888)
  • img: 主显示图像缓冲区

  • img2: 触摸点显示图像缓冲区(用于绘制触摸轨迹)

  • ARGB8888: 32位颜色格式(Alpha, Red, Green, Blue各8位)

2. 显示系统初始化

复制代码
Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)
MediaManager.init()
  • 初始化ST7701显示控制器

  • to_ide=True: 可能表示同时输出到IDE预览

3. 主循环

触摸处理部分
复制代码
point = tp.read(1)  # 读取触摸点数据
if len(point):
    pt = point[0]
    if pt.event == 0 or pt.event == TOUCH.EVENT_DOWN or pt.event == TOUCH.EVENT_MOVE:
        img2.draw_cross(pt.x, pt.y, color=(255,0,0), width=1, think_ness=1)
        Display.show_image(img2, layer=Display.LAYER_OSD2, alpha=128)
  • 检测触摸事件(按下、移动)

  • 在触摸位置绘制红色十字

  • 在OSD2图层显示触摸轨迹,设置半透明效果(alpha=128)

文字显示部分
复制代码
x = (urandom.getrandbits(11) % img.width())
y = (urandom.getrandbits(11) % img.height())
img.draw_string_advanced(x, y, 32, "Hello World!,你好世界!!!", color=(0,0,255))
Display.show_image(img)
  • 在随机位置显示中英文文字

  • 文字颜色为蓝色

  • 将图像显示到屏幕上

循环控制
复制代码
img.clear()  # 清空主图像缓冲区
time.sleep(0.05)  # 50ms延迟,控制刷新率

4. 异常处理和清理

复制代码
except KeyboardInterrupt as e:
    print("user stop: ", e)
except BaseException as e:
    sys.print_exception(e)

Display.deinit()  # 释放显示资源
MediaManager.deinit()  # 释放媒体资源

程序入口

复制代码
if __name__ == "__main__":
    os.exitpoint(os.EXITPOINT_ENABLE)
    display_test()
  • 启用退出点机制,允许安全中断程序

  • 调用主测试函数

程序功能总结

  1. 显示测试: 在屏幕随机位置显示"Hello World!,你好世界!!!"

  2. 触摸测试: 检测触摸并在触摸位置绘制红色十字轨迹

  3. 多图层显示: 使用不同图层分别显示文字和触摸轨迹

  4. 实时更新: 以约20FPS的速率刷新显示

程序用于嵌入式设备的显示和触摸屏功能验证。

源程序如下:

python 复制代码
import time, os, urandom, sys

from media.display import *
from media.media import *

from machine import TOUCH

DISPLAY_WIDTH = ALIGN_UP(800, 16)
DISPLAY_HEIGHT = 480

tp = TOUCH(0)

def display_test():
    print("display and touch test")

    # create image for drawing
    img = image.Image(DISPLAY_WIDTH, DISPLAY_HEIGHT, image.ARGB8888)
    img.clear()

    img2 = image.Image(DISPLAY_WIDTH, DISPLAY_HEIGHT, image.ARGB8888)
    img2.clear()

    # use lcd as display output
    Display.init(Display.ST7701, width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT, to_ide = True)
    # init media manager
    MediaManager.init()

    try:
        while True:
            os.exitpoint()
            point = tp.read(1)
            if len(point):
                print(point)
                pt = point[0]
                if pt.event == 0 or pt.event == TOUCH.EVENT_DOWN or pt.event == TOUCH.EVENT_MOVE:
                    img2.draw_cross(pt.x, pt.y, color=(255,0,0), width = 1, think_ness = 1)
                    Display.show_image(img2, layer = Display.LAYER_OSD2, alpha = 128)

            x = (urandom.getrandbits(11) % img.width())
            y = (urandom.getrandbits(11) % img.height())
            img.draw_string_advanced(x,y,32, "Hello World!,你好世界!!!", color = (0, 0, 255),)
            # draw result to screen
            Display.show_image(img)
            img.clear()
            time.sleep(0.05)
    except KeyboardInterrupt as e:
        print("user stop: ", e)
    except BaseException as e:
        import sys
        sys.print_exception(e)

    # deinit display
    Display.deinit()
    os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
    time.sleep_ms(100)
    # release media buffer
    MediaManager.deinit()

if __name__ == "__main__":
    os.exitpoint(os.EXITPOINT_ENABLE)
    display_test()
相关推荐
MThinker1 天前
03-Machine-2-dht.py K230外接数字温湿度传感器DHT11模块演示
智能硬件·micropython·canmv·k230
hazy1k11 天前
K230基础-录放视频
网络·人工智能·stm32·单片机·嵌入式硬件·音视频·k230
hazy1k12 天前
K230基础-录放音频
人工智能·stm32·单片机·嵌入式硬件·音视频·k230
hazy1k12 天前
K230基础-获取触摸坐标
图像处理·stm32·单片机·嵌入式硬件·k230
hazy1k21 天前
K230基础-显示画面
stm32·单片机·嵌入式硬件·k230
hazy1k24 天前
K230基础-RTC时钟介绍及使用
stm32·单片机·嵌入式硬件·k230
MThinker25 天前
02-Media-11-video_player.py 对H.264或H.265格式视频播放器的示例程序
python·音视频·h.265·h.264·micropython·canmv·k230
MThinker1 个月前
02-Media-8-uvc_with_csc.py 使用硬件解码的USB摄像头(UVC)捕获视频并显示的程序
音视频·智能硬件·micropython·canmv·k230
MThinker2 个月前
k230 按键拍照后,将摄像头拍照的1920*1080分辨率的图片以jpg文件格式,保存到板载TF存储卡的指定文件夹目录中
python·嵌入式硬件·智能硬件·micropython·canmv·k230