TR2S 显示接口驱动库
用户使用说明
API 使用说明 & 平台移植指南
适用范围:TR2S 系列 LCD 控制器 支持接口:4-wire SPI / QSPI / 8080-8bit / 8080-16bit 默认参考工程:STM32F10x(FSMC 示例 / 软件 SPI 示例)
1. 概述
本驱动库面向 TR2S 系列 LCD 控制器,提供统一的显示控制 API(字体绘制、几何图形、填充、背光、旋转、版本读取、自检、软复位等),并通过函数指针(LCD_Transmit 结构体)将底层主机接口抽象化,从而支持以下四种主机接口:
- 4-wire SPI(INTERFACE_SPI)
- Quad SPI(INTERFACE_QSPI)
- 8080 8 位并口(INTERFACE_8080_8B)
- 8080 16 位并口(INTERFACE_8080_16B) 上层 API 完全接口无关:用户只需在 lcd_init.h 中选择一种接口宏,并在对应的接口源文件中实现 BSP 适配层(用 /* user_change_begin / 与 / user_change_end */ 标记的区域),即可在任意 MCU 平台运行。8080 并口在 STM32 默认参考工程中通过 FSMC 实现,在其他平台可根据实际情况替换为 EMIF / GPMC / GPIO 模拟等等效方式。
2. 目录结构与文件说明
驱动库的目录结构如下:
Display_interface/
├── lcd_init.h / lcd_init.c
├── lcd_cmd.h / lcd_cmd.c
└── interface/
├── interface.h
├── spi.c / spi.h
├── qspi.c / qspi.h
├── 8080_8b.c / 8080_8b.h
└── 8080_16b.c / 8080_16b.h各文件职责说明:
- lcd_init.{h,c}:驱动初始化主流程,集中定义配置宏(接口选择、WIDTH/HEIGHT 分辨率、旋转方向、颜色格式)、命令宏、LCD_Transmit 结构体声明与 lcd_device_init() 入口。
- lcd_cmd.{h,c}:★ 用户 API 实现。所有 tr2s_xxx 系列显示控制函数(系统控制、显示窗口、字体、几何图形、通用命令发送等)均定义于此,是用户主要调用的文件。
- interface/interface.h:统一头文件,聚合所有接口头文件,并定义 STM32 参考平台包含、BUSY 引脚、WAIT_BUSY_SIGN 宏。应用代码只需 #include "interface.h" 即可。
- interface/spi.{c,h}:4-wire SPI 接口实现,提供使能函数 spi_enable()。
- interface/qspi.{c,h}:QSPI 接口实现,提供使能函数 qspi_enable()。STM32 默认参考工程中使用 FSMC 模拟 4 线 QSPI 时序,移植时按平台替换为等效实现。
- interface/8080_8b.{c,h}:8080 8 位并口实现,提供使能函数 _8080_8b_enable()。
- interface/8080_16b.{c,h}:8080 16 位并口实现,提供使能函数 _8080_16b_enable()。
说明:移植时只需修改 interface/ 目录下对应接口源文件中 /* user_change_begin / ~ / user_change_end */ 之间的 BSP 适配层,lcd_init.{h,c} 与 lcd_cmd.{h,c} 无需改动。8080 并口适配层在默认参考工程中基于 STM32 FSMC 实现,仅作为示例;其他平台可按需要使用专用并口控制器(EMIF / GPMC / EBI 等)或 GPIO 模拟 8080 时序。
3. 配置说明
所有配置集中在 lcd_init.h 中,宏定义为 1 表示使能该选项:
#define INTERFACE_SPI 0 /* 4-wire SPI */
#define INTERFACE_QSPI 0 /* Quad SPI */
#define INTERFACE_8080_8B 0
#define INTERFACE_8080_16B 1
#define WIDTH 480
#define HEIGHT 480
//#define LCD_DISPLAY_ROTATE_0
#define LCD_DISPLAY_ROTATE_90
//#define LCD_DISPLAY_ROTATE_180
//#define LCD_DISPLAY_ROTATE_270
#define LCD_COLOR_FORMATE_RGB565
//#define LCD_COLOR_FORMATE_RGB888在 interface.h 中可配置 BUSY 引脚(用于阻塞等待控制器忙信号):
#define BUSYPINGROUP GPIOC
#define BUSYPIN GPIO_Pin_64. 软件架构
库采用「分层抽象 + 函数指针注入」的设计。lcd_init.c 中的 lcd_device_init() 根据宏选择调用对应的 xxx_enable(),后者完成两件事:
- ① 初始化 BSP(GPIO、并口控制器 / FSMC / SPI / QSPI 等外设),由用户在 user_change 区域填充;
- ② 调用 xxx_transmit_init(),把本接口的底层读写函数挂载到全局 lcd_transmit 结构体。 此后,所有上层 tr2s_xxx API 只通过 lcd_transmit 调用底层,与具体接口完全解耦:
| LCD_Transmit 成员 | 作用 | 上层调用场景 |
|---|---|---|
| writecmd(cmd) | 写入一条命令 | 所有命令发送 |
| writedatas(data,len) | 写入一段数据 | 参数、像素、字符串 |
| writestartsign() | 开始一次像素写入流 | 写显存前奏(含 CMD_WRAM=0x2C) |
| writeendsign() | 结束一次命令/数据流 | 拉高 CS |
| writepix(buf,len) | 写入像素数据 | lcd_fillcolor 刷屏 |
| readcmddatas(cmd,buf,len) | 读命令数据 | 读取版本/IC 信息 |
| delay(ms) | 毫秒延时 | 上电/复位等待 |
| width / height | 当前有效显示宽高(考虑旋转) | 应用层获知分辨率 |
5. 快速上手
在用户应用代码中包含接口头文件,调用初始化,即可使用显示 API:
#include "interface.h"
int main(void)
{
lcd_device_init();
u8 ver[9] = {0};
tr2s_lcd_read_version(ver);
tr2s_set_font_initdata(2, 2, 0, WHITE, BLACK);
tr2s_dispchar_usestandardfont_24x24(10, 10, "Hello TR2S");
tr2s_draw_circle_s(240, 240, 80, RED);
tr2s_lcd_fillcolor(0, 0, 100, 100, BLUE);
tr2s_set_pwm(80);
while (1) { }
}6. API 使用说明
下列 API 全部定义于 lcd_cmd.{c,h},前缀均为 tr2s_。颜色参数除特别说明外采用 RGB565(与 LCD_COLOR_FORMATE_RGB565 配套),可直接使用预定义颜色宏。每个 API 以独立小节给出,依次包含:函数原型、对应命令、功能说明、参数列表。
6.1 初始化与系统控制
lcd_device_init —— 初始化入口
void lcd_device_init(void)初始化入口。根据 lcd_init.h 中使能的 INTERFACE_xxx 宏选择并调用对应接口的 xxx_enable(),完成 BSP 初始化与 lcd_transmit 函数指针挂载;随后按 LCD_DISPLAY_ROTATE_x 设置有效宽高并在需要时下发旋转命令。应用层最先调用此函数。
tr2s_soft_reset —— 软件复位
void tr2s_soft_reset(void)对应命令:CMD_SOFT_RESET = 0x5A
对 LCD 控制器执行软件复位,内部发送固定数据 0x01。复位后建议等待控制器稳定再进行后续操作。
tr2s_set_selftest_mode —— 自检模式
void tr2s_set_selftest_mode(u8 state)对应命令:CMD_SELF_TEST = 0x12
进入或退出 LCD 自检模式(彩条/测试图案)。
state:非 0 值进入自检,0 退出自检
tr2s_set_rotation_angle —— 设置旋转
void tr2s_set_rotation_angle(u8 angle)对应命令:CMD_ROTATION = 0xAD
设置显示旋转方向。注意:lcd_device_init() 内部已根据 LCD_DISPLAY_ROTATE_x 自动调用本函数,应用层一般无需重复调用;仅在运行时动态切换方向时使用。
angle:0 = 0°,1 = 90°,2 = 180°,3 = 270°
tr2s_set_pwm —— 设置背光
void tr2s_set_pwm(u8 bl)对应命令:CMD_CONTROL_BL = 0x20
设置背光 PWM 占空比。
bl:0 ~ 100,单位为百分比;0 为关闭背光
tr2s_lcd_read_version —— 读取版本与 IC 信息
void tr2s_lcd_read_version(u8 *version)对应命令:CMD_VERSION = 0x01 / CMD_IC = 0x02
读取控制器固件版本与驱动 IC 信息,并通过 printf 打印。其中 version[0] 高 4 位为主版本、低 4 位为次版本;version[1..8] 为 IC 名称字符串(以 \0 结尾)。
version:调用方提供的缓冲区,至少 9 字节
6.2 显示窗口与像素写入
tr2s_set_display_window —— 设置活动窗口
void tr2s_set_display_window(u16 start_x, u16 start_y, u16 end_x, u16 end_y)对应命令:CMD_SET_X = 0x2A / CMD_SET_Y = 0x2B
设置活动显示窗口(列地址范围 + 行地址范围)。后续向显存写入的像素将依次落入该矩形区域内。调用本函数后通常紧跟一次 tr2s_lcd_fillcolor 或自定义像素写入流。
start_x / start_y:窗口左上角坐标end_x / end_y:窗口右下角坐标
tr2s_lcd_fillcolor —— 区域填充纯色
void tr2s_lcd_fillcolor(u16 x, u16 y, u16 w, u16 h, u32 color)对应命令:CMD_WRAM = 0x2C
在矩形区域填充纯色。内部先调用 tr2s_set_display_window 设置窗口,再通过 CMD_WRAM(0x2C) 连续写入像素。颜色按 lcd_init.h 的颜色格式宏自动打包:RGB565 时每像素 2 字节,RGB888 + 8080_16b 时每像素3 字节。
x, y:起点坐标w, h:此处实际作为窗口的「结束坐标」使用,与 tr2s_set_display_window 语义一致color:颜色值;RGB565 模式下低 16 位有效,可直接使用 WHITE/RED/BLUE 等宏
说明:调用时传入「起点 + 终点」语义,例如填充 (10,10)~(109,109) 的 100×100 区域应写作 tr2s_lcd_fillcolor(10, 10, 109, 109, BLUE)。
6.3 字体显示
显示字符串前需先调用 tr2s_set_font_initdata 配置字体属性,三种内置字号可混用,字符串均以 \0 结尾。内部使用 100 字节临时缓冲,单次显示字符串不应超过约 95 字节。
tr2s_set_font_initdata —— 配置字体属性
void tr2s_set_font_initdata(u16 word_distance, u16 line_distance, u8 displaymode, u16 fontcolor, u16 backgroundcolor)对应命令:FONT_PROPERTY_SETTING = 0x75
配置字体渲染参数,对后续所有 tr2s_dispchar_* 调用生效。
word_distance:字符之间的水平间距(像素)line_distance:行之间的垂直间距(像素)displaymode:0 = 透明背景(仅绘字形),1 = 不透明背景(用 backgroundcolor 填充字背景)fontcolor:字体颜色,RGB565backgroundcolor:字背景颜色,RGB565;displaymode=0 时无效
tr2s_dispchar_usestandardfont_16x16 —— 16×16 字体显示
void tr2s_dispchar_usestandardfont_16x16(u16 x, u16 y, const char *word)对应命令:DISPLAY_16_16_FONT = 0x81
使用控制器内置 16×16 字体在指定坐标显示字符串。
x, y:字符串起点坐标(左上角)word:以 \0 结尾的字符串;为 NULL 时直接返回不绘制
tr2s_dispchar_usestandardfont_24x24 —— 24×24 字体显示
void tr2s_dispchar_usestandardfont_24x24(u16 x, u16 y, const char *word)对应命令:DISPLAY_24_24_FONT = 0x82
使用控制器内置 24×24 字体显示字符串。参数语义与 16×16 版本一致。
x, y:字符串起点坐标(左上角)word:以 \0 结尾的字符串;为 NULL 时直接返回不绘制
tr2s_dispchar_usestandardfont_32x32 —— 32×32 字体显示
void tr2s_dispchar_usestandardfont_32x32(u16 x, u16 y, const char *word)对应命令:DISPLAY_32_32_FONT = 0x83
使用控制器内置 32×32 字体显示字符串。参数语义与 16×16 版本一致。
x, y:字符串起点坐标(左上角)word:以 \0 结尾的字符串;为 NULL 时直接返回不绘制
6.4 几何图形绘制
tr2s_draw_point_line_s —— 绘制直线
void tr2s_draw_point_line_s(u16 xs, u16 ys, u16 xe, u16 ye, u8 width, u32 color)对应命令:DRAW_POINT_LINE = 0xB0
在两点之间绘制一条直线。
xs, ys:直线起点坐标xe, ye:直线终点坐标width:线宽(像素),>1 时按粗线绘制color:直线颜色,RGB565
tr2s_draw_circle_s —— 绘制圆
void tr2s_draw_circle_s(u16 x, u16 y, u16 r, u32 color)对应命令:DRAW_CIRCLE = 0xB1
绘制圆轮廓(非填充)。
x, y:圆心坐标r:半径(像素)color:圆轮廓颜色,RGB565
tr2s_draw_rectangles_s —— 绘制/填充矩形
void tr2s_draw_rectangles_s(u16 xs, u16 ys, u16 xe, u16 ye, u32 color)对应命令:DRAW_RECTANGLES = 0xB2
绘制/填充矩形。
xs, ys:矩形左上角坐标xe, ye:矩形右下角坐标color:矩形颜色,RGB565
6.5 通用命令发送
tr2s_sendcmddatas —— 通用命令发送
void tr2s_sendcmddatas(u8 cmd, u8 *data, u16 datalen)通用命令发送函数:先发命令 cmd,再发 datalen 字节数据 data,最后调用 writeendsign() 结束。所有上层 API 内部均基于本函数实现,移植或扩展时也可直接使用。
cmd:命令字节,建议使用 6.7 节的命令宏data:数据缓冲区指针datalen:数据字节数
6.6 颜色宏(lcd_cmd.h)
库预定义了常用 RGB565 颜色宏,可直接作为 color 参数传入上述 API:
#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define MAGENTA 0xF81F
#define GREEN 0x07E0
#define CYAN 0x7FFF
#define YELLOW 0xFFE0
#define BROWN 0xBC40
#define BRRED 0xFC07
#define GRAY 0x8430
#define DARKBLUE 0x01CF
#define LIGHTBLUE 0x7D7C
#define GRAYBLUE 0x5458
#define LIGHTGREEN 0x841F
#define LGRAY 0xC6186.7 底层命令宏(lcd_init.h)
上层 API 内部通过下列命令宏与控制器通信。如需直接下发命令,可使用 6.5 节的 tr2s_sendcmddatas 配合这些宏:
| 宏名 | 值 | 含义 |
|---|---|---|
| CMD_VERSION | 0x01 | 读取固件/面板版本 |
| CMD_IC | 0x02 | 读取驱动 IC 信息 |
| CMD_SELF_TEST | 0x12 | 进入/退出自检模式 |
| CMD_SOFT_RESET | 0x5A | 软件复位面板 |
| CMD_SET_X | 0x2A | 设置列地址范围 |
| CMD_SET_Y | 0x2B | 设置行地址范围 |
| CMD_WRAM | 0x2C | 写像素数据到显存 |
| CMD_CONTROL_BL | 0x20 | 背光 PWM 控制 |
| CMD_ROTATION | 0xAD | 显示旋转角度 |
| FONT_PROPERTY_SETTING | 0x75 | 配置字体参数 |
| DISPLAY_16_16_FONT | 0x81 | 16×16 字体显示 |
| DISPLAY_24_24_FONT | 0x82 | 24×24 字体显示 |
| DISPLAY_32_32_FONT | 0x83 | 32×32 字体显示 |
| DRAW_POINT_LINE | 0xB0 | 绘制直线 |
| DRAW_CIRCLE | 0xB1 | 绘制圆 |
| DRAW_RECTANGLES | 0xB2 | 绘制/填充矩形 |
7. 平台移植指南
本驱动库的移植工作量集中在每个接口源文件中 /* user_change_begin / 与 / user_change_end */ 之间的 BSP 适配层。上层 API 与 LCD_Transmit 挂载逻辑无需改动。8080 并口与 QSPI 在默认参考工程中基于 STM32 FSMC 实现,仅作为示例;在其他平台可根据外设资源替换为专用并口控制器(EMIF / GPMC / EBI 等)、硬件 QSPI / Quad SPI 控制器,或通过 GPIO 模拟时序。
7.1 移植步骤
- 步骤 1:在 lcd_init.h 中将目标接口宏置 1(其余置 0),按需调整 WIDTH/HEIGHT、旋转、颜色格式。
- 步骤 2:在 interface.h 中根据目标 MCU 修改或屏蔽 STM32 相关包含与 BUSY 引脚定义;若不使用 BUSY 引脚,注释 BUSYPINGROUP 即可让 WAIT_BUSY_SIGN 为空。
- 步骤 3:打开对应接口源文件(如 8080_16b.c),定位 /* user_change_begin / ~ / user_change_end */ 区域,将其中所有 BSP 调用替换为目标平台的等效函数。
- 步骤 4:实现一个毫秒级延时函数并挂接到 lcd_transmit.delay。
- 步骤 5:调用 lcd_device_init(),再用 tr2s_lcd_read_version() 验证通信是否成功。
7.2 user_change 区域适配函数清单
每个接口源文件中 /* user_change_begin / 与 / user_change_end */ 之间定义了一组 static 适配函数。移植时只需替换这些函数体内的 BSP 调用,函数签名与名称保持不变。以下按接口列出函数签名与其功能描述。
7.2.1 interface/spi.c
static void spi_gpio_init(void)功能:初始化 SPI 接口相关 GPIO 与 SPI 外设(含 CS / RS / BUSY 控制引脚)。
static void spi_wait_busy_sign(void)功能:等待 LCD 控制器 BUSY 信号释放,确保控制器空闲后再进行下一步通信。
static void spi_rs_set_value(u8 value)功能:设置 RS(DC)引脚电平,用于区分命令(0)与数据(1)。
static void spi_cs_set_value(u8 value)功能:设置 CS 片选引脚电平,0 选中控制器,1 释放。
static void spi_writebytes(u8* byte, u32 bytelen)功能:连续写入 bytelen 字节数据到 SPI 总线。
static void spi_readbytes(u8 register_address, u8* data, u32 datalen)功能:从指定寄存器地址连续读取 datalen 字节数据到 data 缓冲区。
static void spi_delay(u32 time)功能:毫秒级延时,用于上电/复位等待时序。
7.2.2 interface/qspi.c
static void qspi_gpio_init(void)功能:初始化 QSPI 接口相关 GPIO 与主机接口外设。在 STM32 默认参考工程中为 FSMC,其他平台按实际外设替换。
static void qspi_wait_busy_sign(void)功能:等待 LCD 控制器 BUSY 信号释放。
static void qspi_set_cs_value(u8 value)功能:设置 CS 片选引脚电平。
static void qspi_send_one_line_data(u8 senddata)功能:将 1 字节数据按位拆分,以单线模式逐位发送,用于 QSPI 命令/地址传输。
static void qspi_send_four_line_data(u8* data, u32 datalen)功能:将数据按每字节拆为高/低 4 位,以 4 线模式发送,用于 QSPI 数据传输。
static void qspi_read_bytes(u8* data, u32 datalen)功能:以单线方式逐位读取,拼装成 datalen 字节数据到 data 缓冲区。
static void qspi_delay(u32 time)功能:毫秒级延时。
7.2.3 interface/8080_8b.c
static void _8080_8b_gpio_Init(void)功能:初始化 8080 8 位并口相关 GPIO 与主机并口外设。在 STM32 默认参考工程中为 FSMC,其他平台按实际外设替换。
static void _8080_8b_set_cs_value(u8 value)功能:设置 CS 片选引脚电平,0 选中控制器,1 释放。
static void _8080_8b_wait_busy_sign(void)功能:等待 LCD 控制器 BUSY 信号释放,确保控制器空闲。
static void _8080_8b_set_dc_value(u8 value)功能:设置 DC 引脚电平,区分命令(0)与数据(1)。
static void _8080_8b_set_rd_value(u8 value)功能:设置 RD 读使能引脚电平,用于读时序控制。
static void _8080_8b_write_cmd(u8 cmd)功能:通过 8080 并口向命令地址写入一字节命令。
static void _8080_8b_write_data(u8* data, u32 datalen)功能:通过 8080 并口连续向数据地址写入 datalen 字节数据。
static void _8080_8b_read_bytes(u8* data, u32 datalen)功能:通过 8080 并口读时序连续读取 datalen 字节数据到 data 缓冲区。
static void _8080_8b_delay(u32 time)功能:毫秒级延时。
7.2.4 interface/8080_16b.c
static void _8080_16b_gpio_init(void)功能:初始化 8080 16 位并口相关 GPIO 与主机并口外设。在 STM32 默认参考工程中为 FSMC,其他平台按实际外设替换。
static void _8080_16b_set_cs_value(u8 value)功能:设置 CS 片选引脚电平,0 选中控制器,1 释放。
static void _8080_16b_wait_busy_sign(void)功能:等待 LCD 控制器 BUSY 信号释放,确保控制器空闲。
static void _8080_16b_set_dc_value(u8 value)功能:设置 DC 引脚电平,区分命令(0)与数据(1)。
static void _8080_16b_set_rd_value(u8 value)功能:设置 RD 读使能引脚电平,用于读时序控制。
static void _8080_16b_write_cmd(u8 cmd)功能:通过 8080 并口向命令地址写入一字节命令。
static void _8080_16b_write_data(u8* data, u32 datalen)功能:将字节数据按 16-bit 半字打包后,通过 8080 并口连续写入数据地址(奇数字节会补齐)。
static void _8080_16b_read_bytes(u8* data, u32 datalen)功能:通过 8080 并口读时序连续读取 datalen 个 16-bit 半字到 data 缓冲区。
static void _8080_16b_delay(u32 time)功能:毫秒级延时。
说明:移植时只需替换上述函数体内的 BSP 调用为目标平台等效函数;函数签名、static 修饰符,以及 user_change 区域之外的 xxx_writecmd / xxx_transmit_init 等挂载逻辑均保持不变。8080 并口与 QSPI 的默认参考实现基于 STM32 FSMC,迁移到其他 MCU 时请按平台外设资源重写对应适配层。
7.3 移植示例:将 4-wire SPI 接口移植到无 STM32 HAL 的平台
假设目标平台已提供 my_gpio_init()、my_spi_xfer()、my_delay_ms(),只需修改 spi.c 的 user_change 区域:
/*************************user_change_begin*************************/
static void spi_gpio_init(void)
{
my_gpio_init();
my_spi_init(SPI_MODE_0, 8);
}
static void spi_wait_busy_sign(void) { WAIT_BUSY_SIGN }
static void spi_rs_set_value(u8 v) { my_gpio_write(RS_PIN, v); }
static void spi_cs_set_value(u8 v) { my_gpio_write(CS_PIN, v); }
static void spi_writebytes(u8* b, u32 n)
{
while (n--) my_spi_xfer(*b++);
}
static u8 spi_readbyte(void) { return my_spi_xfer(0xFF); }
static void spi_delay(u32 ms) { my_delay_ms(ms); }
/*************************user_change_end*************************/说明:保持 user_change 区域之外的 spi_writecmd / spi_senddatas / spi_transmit_init 等函数原样,它们已实现与上层 API 的协议对接。
8. 附录:API 速查表
| 分类 | 函数 | 一句话说明 |
|---|---|---|
| 系统 | lcd_device_init | 初始化入口 |
| 系统 | tr2s_soft_reset | 软复位 |
| 系统 | tr2s_set_selftest_mode | 自检模式 |
| 系统 | tr2s_set_rotation_angle | 设置旋转 |
| 系统 | tr2s_set_pwm | 设置背光 |
| 系统 | tr2s_lcd_read_version | 读取版本/IC |
| 显示 | tr2s_set_display_window | 设置活动窗口 |
| 显示 | tr2s_lcd_fillcolor | 区域填色 |
| 通用 | tr2s_sendcmddatas | 通用命令发送 |
| 字体 | tr2s_set_font_initdata | 字体属性 |
| 字体 | tr2s_dispchar_usestandardfont_16x16 | 16×16 显示 |
| 字体 | tr2s_dispchar_usestandardfont_24x24 | 24×24 显示 |
| 字体 | tr2s_dispchar_usestandardfont_32x32 | 32×32 显示 |
| 图形 | tr2s_draw_point_line_s | 画直线 |
| 图形 | tr2s_draw_circle_s | 画圆 |
| 图形 | tr2s_draw_rectangles_s | 画矩形 |