mcu_lcd_display
概述
display API接口是对不同接口的屏幕驱动的抽象,客户根据不同的屏幕类型使用对应的接口创建handle。
display hardwarefeature:
支持不同的屏幕类型,如RGB LCD(RGB565,RGB888)、MCU LCD(8线,16线)等。
- 支持像素转换功能,即输入数据可以和lcd支持的输出数据格式不同,比如可以提供YUYV数据刷屏。
YUYV到RGB565/RGB888/RGB666的转换
RGB565到RGB888的转换
RGB888到RGB565的转换
RGB565到RGB666的转换
RGB888到RGB666的转换
RGB565格式使用的GPIO为高位有效, 即R3-R7为高位,G2-G7为高位,B3-B7为高位。
本节主要说明display模块如何驱动MCU LCD,包括其API调用,参数说明以及注意事项。
有关RGB LCD显示的示例工程,请参阅:
有关API参考,请参阅:
开发介绍
1. 关于电源LDO控制
BK7258 开发板SDK中默认的LCD LDO控制引脚是GPIO13,如果客户的IO不一致,需要在方案中主动调用GPIO驱动配置。
2. 关于背光只支持
LCD背光控制引脚,需要在方案中调用GPIO驱动配置。
3. 关于lcd设备
BK7258 开发板SDK中默认的LCD RGB设备是st7796s,如果客户的设备不一致,需要在方案中添加device设备。
关于devices设备应该如何添加请参考: - LCD设备添加指南
3. 关于mcu输出格式(8线16线)配置
MCU接口支持数据线是8线(D0-7)和16线(D0-15)的接口配置,但是对不同的像素格式RGB565/666/888有限制,如下:
8线支持RGB565, RGB888输出:out_fmt = PIXEL_FMT_RGB565,out_fmt = PIXEL_FMT_RGB888;
16线只支持RGB666输出:out_fmt = PIXEL_FMT_RGB666
16线只支持RGB888输出:out_fmt = PIXEL_FMT_RGB888_16BIT
如何配置MCU屏的输出格式是在lcd_device中的lcd_device_t中配置out_fmt。 下面的配置即:Display模块的输入数据源是YUYV数据,MCU接口是8线RGB565,display模块内部将YUYV数据转换为RGB565,输出给MCU LCD。
代码示例
const lcd_device_t lcd_device_st7796s =
{
.id = LCD_DEVICE_ST7796S,
.name = "st7796s",
.type = LCD_TYPE_MCU8080,
.width = 320,
.height = 480,
.mcu = &lcd_mcu,
.src_fmt = PIXEL_FMT_YUYV,
.out_fmt = PIXEL_FMT_RGB565,
.lcd_init = lcd_st7796s_init,
.lcd_off = st7796s_lcd_off,
};
API调用流程概览
MCU LCD Display的典型使用流程如下:
┌─────────────────────────────────────────────────────────────┐
│ MCU LCD Display API 调用流程 │
└─────────────────────────────────────────────────────────────┘
1. 硬件准备 ──→ 配置LCD LDO和背光GPIO
└─ 使能电源和背光控制
2. bk_display_mcu_new() ──→ 创建MCU LCD控制器实例
└─ 配置LCD设备和TE引脚
3. bk_display_open() ──→ 打开显示控制器
└─ 初始化LCD硬件
4. bk_display_flush() ──→ 刷新显示(可多次调用)
└─ 将帧数据发送到LCD
5. bk_display_close() ──→ 关闭显示控制器
└─ 停止硬件,关闭时钟
6. bk_display_delete() ──→ 删除控制器实例
└─ 释放资源
注意
必须按照上述顺序调用API
刷新显示前必须先创建并打开控制器
MCU LCD使用8线或16线数据总线,需要根据设备配置
帧释放回调函数必须正确实现
完整使用示例
以下是一个完整的MCU LCD使用示例:
#include <components/bk_display/bk_display.h>
#include <components/bk_display/bk_display_types.h>
#include <driver/gpio.h>
#define TAG "mcu_lcd_demo"
#define BL_PIN GPIO_7
#define LCD_LDO_PIN GPIO_13
// 帧数据释放回调
static avdk_err_t display_frame_free_cb(void *frame)
{
frame_buffer_display_free((frame_buffer_t *)frame);
return AVDK_ERR_OK;
}
avdk_err_t mcu_lcd_demo(void)
{
avdk_err_t ret = AVDK_ERR_OK;
bk_display_ctlr_handle_t lcd_display_handle = NULL;
const lcd_device_t *lcd_device = &lcd_device_st7796s;
// 步骤1: 配置LDO和背光
gpio_dev_unmap(LCD_LDO_PIN);
bk_gpio_enable_output(LCD_LDO_PIN);
bk_gpio_set_output_high(LCD_LDO_PIN);
gpio_dev_unmap(BL_PIN);
bk_gpio_enable_output(BL_PIN);
bk_gpio_set_output_high(BL_PIN);
// 步骤2: 创建MCU LCD控制器
bk_display_mcu_ctlr_config_t lcd_config = {0};
lcd_config.lcd_device = lcd_device;
lcd_config.te_pin = GPIO_INVALID_PIN; // 不使用TE功能
ret = bk_display_mcu_new(&lcd_display_handle, &lcd_config);
if (ret != AVDK_ERR_OK) {
LOGE("bk_display_mcu_new failed: %d\n", ret);
return ret;
}
// 步骤3: 打开显示控制器
ret = bk_display_open(lcd_display_handle);
if (ret != AVDK_ERR_OK) {
LOGE("bk_display_open failed: %d\n", ret);
bk_display_delete(lcd_display_handle);
return ret;
}
// 步骤4: 分配并刷新显示
uint32_t frame_size = lcd_device->width * lcd_device->height * 2;
frame_buffer_t *disp_frame = frame_buffer_display_malloc(frame_size);
if (disp_frame) {
disp_frame->fmt = PIXEL_FMT_RGB565;
disp_frame->width = lcd_device->width;
disp_frame->height = lcd_device->height;
ret = bk_display_flush(lcd_display_handle, disp_frame, display_frame_free_cb);
if (ret != AVDK_ERR_OK) {
frame_buffer_display_free(disp_frame);
}
}
// 步骤5: 关闭显示
bk_display_close(lcd_display_handle);
// 步骤6: 删除控制器
bk_display_delete(lcd_display_handle);
lcd_display_handle = NULL;
// 关闭背光和LDO
bk_gpio_set_output_low(BL_PIN);
bk_gpio_set_output_low(LCD_LDO_PIN);
return AVDK_ERR_OK;
}
API详细说明
1. bk_display_mcu_new - 创建MCU LCD控制器
功能描述:
创建MCU LCD显示控制器实例,配置LCD设备和TE(Tearing Effect)引脚。
函数原型:
avdk_err_t bk_display_mcu_new(bk_display_ctlr_handle_t *handle,
const bk_display_mcu_ctlr_config_t *config);
参数说明:
handle: [输出] 指向显示控制器句柄的指针,成功后存储创建的句柄
config: [输入] MCU LCD控制器配置参数结构体指针
配置结构体成员说明:
lcd_device: LCD设备指针,包含分辨率、接口类型等信息(必填)
te_pin: Tearing Effect信号引脚(如不需要设为GPIO_INVALID_PIN)
返回值:
AVDK_ERR_OK: 成功
AVDK_ERR_NOMEM: 内存分配失败
AVDK_ERR_INVAL: 参数无效(handle或config为NULL,或lcd_device为NULL)
使用注意:
lcd_device参数必须传入有效的设备指针
TE功能用于同步显示,避免撕裂效果,如果LCD不支持可设为-1
LCD设备需要提前定义,参考:LCD设备添加指南
MCU LCD支持8线和16线数据总线
示例代码:
#include <components/bk_display/bk_display.h>
#include <components/bk_display/bk_display_types.h>
bk_display_ctlr_handle_t lcd_display_handle = NULL;
const lcd_device_t *lcd_device = &lcd_device_st7796s; // 使用ST7796S设备
// 创建MCU LCD控制器配置
bk_display_mcu_ctlr_config_t lcd_config = {0};
lcd_config.lcd_device = lcd_device;
lcd_config.te_pin = GPIO_INVALID_PIN; // 不使用TE功能
// 创建控制器
avdk_err_t ret = bk_display_mcu_new(&lcd_display_handle, &lcd_config);
if (ret != AVDK_ERR_OK) {
LOGE("Failed to create MCU LCD controller: %d\n", ret);
return ret;
}
LOGI("MCU LCD controller created: %p\n", lcd_display_handle);
2. bk_display_open - 打开LCD显示控制器
功能描述:
打开LCD显示控制器,初始化显示硬件、使能时钟并调用LCD设备的初始化函数。
此API在RGB LCD和MCU LCD中通用
avdk_err_t bk_display_open(bk_display_ctlr_handle_t handle);
3. bk_display_flush - 刷新LCD显示
功能描述:
将帧数据发送到LCD显示屏进行显示。MCU LCD支持RGB565、RGB888、RGB666、YUYV格式的源数据。
此API在RGB LCD和MCU LCD中通用,但MCU LCD有特殊的数据总线配置
avdk_err_t bk_display_flush(bk_display_ctlr_handle_t handle, void *frame, avdk_err_t (*free_cb)(void *));
MCU LCD特殊说明:
MCU接口支持8线(D0-D7)和16线(D0-D15)数据总线,对不同像素格式有限制:
8线总线: 支持RGB565、RGB888输出
16线总线: 支持RGB666、RGB888输出
输出格式在lcd_device的out_fmt中配置:
const lcd_device_t lcd_device_st7796s = {
.type = LCD_TYPE_MCU8080,
.width = 320,
.height = 480,
.out_fmt = PIXEL_FMT_RGB565, // 8线总线RGB565输出
// ...
};
4. bk_display_close - 关闭LCD显示控制器
功能描述:
关闭LCD显示控制器,停止显示硬件并关闭相关时钟。
此API在RGB LCD和MCU LCD中通用
avdk_err_t bk_display_close(bk_display_ctlr_handle_t handle);
5. bk_display_delete - 删除LCD控制器
功能描述:
删除LCD控制器实例,释放所有分配的资源。
此API在RGB LCD和MCU LCD中通用
avdk_err_t bk_display_delete(bk_display_ctlr_handle_t handle);
使用建议和注意事项
MCU LCD数据总线配置:
8线数据总线(D0-D7): - 支持RGB565输出: out_fmt = PIXEL_FMT_RGB565 - 支持RGB888输出: out_fmt = PIXEL_FMT_RGB888
16线数据总线(D0-D15): - 支持RGB666输出: out_fmt = PIXEL_FMT_RGB666 - 支持RGB888输出: out_fmt = PIXEL_FMT_RGB888_16BIT
输出格式在lcd_device_t结构体的out_fmt成员中配置
帧数据格式:
支持的源数据格式:RGB565、RGB888、YUYV
Display模块会自动进行格式转换(源格式->MCU输出格式)
源数据通过frame->fmt指定,每次刷屏都可以动态改变
输出格式通过lcd_device->out_fmt固定配置
API调用顺序和其他注意事项:
与RGB LCD相同,详细请参考:RGB LCD Display - 使用建议和注意事项
MCU LCD特有注意事项:
MCU LCD初始化命令需要根据屏厂提供的规格书配置
数据总线宽度(8线/16线)需要与硬件连接匹配
输出格式需要与数据总线宽度匹配,否则显示异常
TE功能可选,用于避免显示撕裂
刷屏速度通常低于RGB LCD,取决于时钟频率和数据总线宽度
Display API函数列表
控制器生命周期管理:
bk_display_mcu_new: 创建MCU LCD控制器实例(MCU专用)
bk_display_open: 打开显示控制器,初始化硬件(通用)
bk_display_close: 关闭显示控制器,停止硬件(通用)
bk_display_delete: 删除控制器实例,释放资源(通用)
显示操作:
bk_display_flush: 刷新显示内容到LCD屏幕(通用)
其他功能:
bk_display_set_yuv_mode: 设置YUV数据模式(通用)
bk_display_ioctl: Display控制操作(通用)