spi_lcd_display
概述
display函数是对不同接口的屏幕驱动的抽象,客户根据不同的屏幕类型使用对应的接口创建handle。 接口说明参考bk_display.h。
本节主要说明display模块如何驱动SPI LCD,包括其API调用,参数说明以及注意事项。
开发介绍
1. 关于背光
BK7258 SDK中默认的LCD背光控制引脚是GPIO7,如果客户的IO不一致,需要在方案中主动配置。此外,背光控制是由用户自行控制的,可按照SDK工程中的背光接口自行封装打开和关闭接口。
2. 关于lcd设备
BK7258 SDK中已添加一些SPI LCD的设备,如果客户的设备不一致,需要在方案中添加新的device设备,可参考下面章节说明。
代码流程
1. 创建LCD控制器
介绍参数:
- handle: 输出参数,存储创建的display控制器句柄
- config: 控制器配置参数,包含LCD设备信息和GPIO引脚配置
示例代码:
bk_display_spi_ctlr_config_t spi_ctlr_config = {
.lcd_device = &lcd_device_st7796u,
.spi_id = 0,
.dc_pin = GPIO_8,
.reset_pin = GPIO_40,
.te_pin = 0,
};
static bk_display_ctlr_handle_t lcd_display_handle = NULL;
avdk_err_t ret = bk_display_spi_new(&lcd_display_handle, &spi_ctlr_config);
if (ret != AVDK_ERR_OK) {
// 错误处理
}
注意
如果TE功能未使用,可将te_pin设置为任意值。 lcd_device是传入的lcd设备指针,用于获取屏幕的分辨率、接口类型等信息,该参数必须传入。
2. 打开LCD显示
介绍参数:
- handle: display控制器句柄
描述: 打开LCD显示,初始化显示控制器。
示例代码:
// 打开背光
lcd_backlight_open(GPIO_7);
// 打开显示控制器
ret = bk_display_open(lcd_display_handle);
if (ret != AVDK_ERR_OK) {
// 错误处理
}
注意
由于硬件环境不同,背光需要用户自己配置
3. 刷新LCD显示
介绍参数:
- handle: display控制器句柄
- frame: 要显示的帧数据指针
- free_t: 帧数据释放回调函数
描述: 刷新LCD显示内容,将帧数据发送到显示屏。
示例代码:
// 帧数据释放回调函数
static avdk_err_t display_frame_free_cb(void *frame)
{
frame_buffer_display_free((frame_buffer_t *)frame);
return AVDK_ERR_OK;
}
// 刷新显示
ret = bk_display_flush(lcd_display_handle, (void *)disp_frame, display_frame_free_cb);
if (ret != AVDK_ERR_OK) {
// 错误处理,需要手动释放帧
display_frame_free_cb(disp_frame);
}
注意
1:display_frame_free_cb是刷新显示时的帧数据释放回调函数,用于释放刷新完成后的帧数据。 如果客户不需要释放frame, 可以将free_t设置为NULL。 2:刷屏的源数据格式支持RGB数据,具体的RGB格式可参考LCD的spec说明。
4. 关闭LCD显示
介绍参数:
- handle: display控制器句柄
描述: 关闭LCD显示,停止显示控制器。
示例代码:
// 关闭显示控制器
ret = bk_display_close(lcd_display_handle);
if (ret != AVDK_ERR_OK) {
// 错误处理
}
// 关闭背光
lcd_backlight_close(GPIO_7);
5. 删除LCD控制器
介绍参数:
- handle: display控制器句柄
描述: 删除LCD控制器,释放相关资源。
示例代码:
// 删除显示控制器
ret = bk_display_delete(lcd_display_handle);
if (ret != AVDK_ERR_OK) {
// 错误处理
}
lcd_display_handle = NULL; // 重置句柄
6. 新增lcd device
static const lcd_qspi_init_cmd_t gc9d01_init_cmds[] =
{
{0xFE, {0x00}, 0},
{0xEF, {0x00}, 0},
{0x80, {0xFF}, 1},
{0x81, {0xFF}, 1},
{0x82, {0xFF}, 1},
{0x83, {0xFF}, 1},
{0x84, {0xFF}, 1},
{0x85, {0xFF}, 1},
{0x86, {0xFF}, 1},
{0x87, {0xFF}, 1},
{0x88, {0xFF}, 1},
{0x89, {0xFF}, 1},
{0x8A, {0xFF}, 1},
{0x8B, {0xFF}, 1},
{0x8C, {0xFF}, 1},
{0x8D, {0xFF}, 1},
{0x8E, {0xFF}, 1},
{0x8F, {0xFF}, 1},
{0x3A, {0x05}, 1},
{0xEC, {0x01}, 1},
{0x74, {0x02, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00}, 7},
{0x98, {0x3E, 0x99, 0x3E}, 3},
{0XB5, {0x0D, 0x0D}, 2},
{0x60, {0x38, 0x0F, 0x79, 0x67}, 4},
{0x61, {0x38, 0x11, 0x79, 0x67}, 4},
{0x64, {0x38, 0x17, 0x71, 0x5F, 0x79, 0x67}, 6},
{0x65, {0x38, 0x13, 0x71, 0x5B, 0x79, 0x67}, 6},
{0x6A, {0x00, 0x00}, 2},
{0x6C, {0x22, 0x02, 0x22, 0x02, 0x22, 0x22, 0x50}, 7},
{0x6E, {0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x0F, 0x0F, 0x0D, 0x0D, 0x0B, 0x0B, 0x09, 0x09, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x0A, 0x0C, 0x0C, 0x0E, 0x0E, 0x10, 0x10, 0x00, 0x00, 0x02, 0x02, 0x04, 0x04}, 32},
{0xBF, {0x01}, 1},
{0xF9, {0x40}, 1},
{0x9B, {0x3B}, 1},
{0x93, {0x33, 0x7F, 0x00}, 3},
{0x7E, {0x30}, 1},
{0x70, {0x0D, 0x02, 0x08, 0x0D, 0x02, 0x08}, 6},
{0x71, {0x0D, 0x02, 0x08}, 3},
{0X91, {0x0E, 0x09}, 2},
{0xC3, {0x18}, 1},
{0xC4, {0x18}, 1},
{0xC9, {0x3C}, 1},
{0xF0, {0x13, 0x15, 0x04, 0x05, 0x01, 0x38}, 6},
{0xF2, {0x13, 0x15, 0x04, 0x05, 0x01, 0x34}, 6},
{0xF1, {0x4B, 0xB8, 0x7B, 0x34, 0x35, 0xEF}, 6},
{0xF3, {0x47, 0xB4, 0x72, 0x34, 0x35, 0xDA}, 6},
{0x36, {0x00}, 1},
{0x34, {0x00}, 0},
{0x11, {0x00}, 0},
{0x00, {0x78}, 0xFF},
{0x29, {0x00}, 0},
};
static const lcd_spi_t lcd_spi_gc9d01_config =
{
.clk = LCD_QSPI_60M,
.init_cmd = gc9d01_init_cmds,
.device_init_cmd_len = sizeof(gc9d01_init_cmds) / sizeof (lcd_qspi_init_cmd_t),
.frame_len = (PPI_160X160 >> 16) * (PPI_160X160 & 0xFFFF) * 2,
};
const lcd_device_t lcd_device_gc9d01 =
{
.id = LCD_DEVICE_GC9D01,
.name = "gc9d01",
.type = LCD_TYPE_SPI,
.ppi = PPI_160X160,
.spi = &lcd_spi_gc9d01_config,
.init = NULL,
.lcd_off = NULL,
};
参考工程
SPI LCD示例:
./projects/spi_lcd_example
注意事项
确保在调用flush之前已经成功创建和打开了display控制器
帧数据释放回调函数必须正确实现,否则会导致内存泄漏
不同的LCD设备需要配置正确的GPIO引脚
帧缓冲区大小应根据实际显示分辨率和像素格式计算
操作完成后应及时关闭和删除控制器释放资源