TFT液晶屏显示图片文字
用于大屏或高性能应用(如STM32 LTDC外设),直接传输RGB像素数据和同步信号(HSYNC, VSYNC, DE, CLK)。直接存储每个像素的RGB值(RGB565最常见)。TFT屏和背光(LED)通常需要单独的电源(3.3V, 5V, 甚至更高电压),电流可能较大,确保电源设计合理。速度快,适合高分辨率屏,需较多IO引脚(数据线D0-D15/8, 控制线RD/WR/RS/CS/RESET
一、 硬件基础
-
TFT液晶屏接口
-
并行接口 (如8080/6800模式): 速度快,适合高分辨率屏,需较多IO引脚(数据线D0-D15/8, 控制线RD/WR/RS/CS/RESET)。
-
SPI接口: 引脚少(SCK, MOSI, MISO, CS, DC, RESET),速度较慢,适合小尺寸或低分辨率屏。
-
RGB接口: 用于大屏或高性能应用(如STM32 LTDC外设),直接传输RGB像素数据和同步信号(HSYNC, VSYNC, DE, CLK)。
-
MIPI DSI: 高速串行接口,用于高端嵌入式平台。
-
-
控制器
-
屏本身可能自带控制器(如ILI9341, ST7789, SSD1963等),MCU通过上述接口与控制器通信。
-
部分ARM MCU(如STM32F4/F7/H7系列)内置LCD控制器(LTDC),可直接驱动RGB接口屏。
-
二、 软件实现流程
1. 底层驱动开发
-
初始化配置:
-
配置MCU的GPIO、SPI、FSMC(用于8080接口)或LTDC外设。
-
发送初始化序列(
Init Code)给TFT控制器(通常由屏厂商提供)。 -
设置扫描方向、像素格式(RGB565/RGB888)、显示区域等。
-
-
基本绘图函数实现:
-
画点 (
DrawPixel(x, y, color)): 最基础函数,设置光标位置,写入颜色数据。 -
清屏 (
FillScreen(color)): 快速填充整个屏幕为单一颜色。 -
画线/矩形/圆 (
DrawLine,DrawRect,DrawCircle): 基于画点函数实现。 -
设置窗口 (
SetWindow(x0, y0, x1, y1)): 告诉控制器后续写入的数据属于哪个矩形区域。这是高效显示图片的关键!
-
2. 显示文字
-
字库获取:
-
点阵字库: 最常用(如12x12, 16x16, 24x24汉字)。存储在MCU Flash或外部SPI Flash中。
-
工具:PCtoLCD2002, FontConverter 等可生成字模数组。
-
-
矢量字库 (较少用): 如FreeType库,资源消耗大,但可缩放无锯齿。
-
-
显示字符函数 (
DrawChar(x, y, char, font, fgColor, bgColor)):-
根据字符编码(ASCII/GBK/Unicode)查找字模数据。
-
循环遍历字模的每一位(bit)。
-
如果该位为1,则在对应位置画前景色 (
fgColor);如果为0,则画背景色 (bgColor) 或透明(不画)。
-
-
显示字符串 (
DrawString(x, y, str, ...)):-
循环调用
DrawChar,并计算下一个字符的位置(考虑字符宽度和间距)。
-
3. 显示图片
-
图片格式转换 (在PC上完成):
-
将JPG/PNG/BMP等格式转换为嵌入式系统易处理的格式:
-
位图数组 (C Array): 直接存储每个像素的RGB值(RGB565最常见)。工具:Img2Lcd, LCD Image Converter。
-
压缩格式 (可选): RLE, LZ77等,节省存储空间但需解压(消耗CPU)。
-
-
选择格式:
-
RGB565(16位): 最常用,平衡速度和色彩。 -
RGB888(24/32位): 色彩更好,占用空间/带宽更大。 -
Indexed Color(调色板): 节省空间,适合颜色数少的图片。
-
-
-
图片显示函数 (
DrawImage(x, y, width, height, *imgData)):-
调用
SetWindow(x, y, x+width-1, y+height-1)设置显示区域。 -
发送命令(如
Memory Write)。 -
连续写入像素数据: 将转换好的图片数组 (
imgData) 通过SPI或并行接口连续地、快速地写入TFT控制器。这是性能关键点!-
使用DMA传输可极大解放CPU,提高效率。
-
-
三、 性能优化技巧
-
减少通信开销:
-
批量传输: 显示图片或填充区域时,务必使用
SetWindow+ 连续写入,避免单点写入。 -
使用硬件加速接口: 优先选择FSMC/LTDC等并行接口。
-
启用DMA: 让DMA控制器搬运像素数据到接口外设,CPU可处理其他任务。
-
提高SPI时钟频率: 在SPI屏上尽可能使用最高稳定时钟。
-
-
优化存储空间:
-
使用压缩图片格式(需解压)。
-
将大图片、字库存放在外部SPI Flash或SD卡,使用时再加载到RAM(需足够RAM)。
-
-
双缓冲 (Double Buffering):
-
在RAM中开辟两块与屏幕大小相同的缓冲区 (
FrameBuffer1,FrameBuffer2)。 -
绘图操作在后台缓冲区(如
FrameBuffer1)进行。 -
完成后,一次性将整个后台缓冲区数据快速拷贝到TFT(或LTDC外设的显存)。
-
避免屏幕撕裂,提升流畅度,但消耗大量RAM。
-
-
利用MCU硬件特性:
-
有GPU的MCU(如i.MX RT)可用GPU加速渲染。
-
有Chrom-ART加速器(DMA2D)的STM32可用其加速填充、拷贝、混合图像。
-
四、 常用库和工具
-
嵌入式GUI库 (简化开发):
-
LVGL: 开源,轻量级,功能强大,资源丰富,支持多种MCU和屏。
-
emWin (Segger): 商用,成熟稳定,性能好。
-
TouchGFX (ST): ST主推,视觉效果优异,对STM32优化好。
-
Qt for MCUs: 适用于高性能MCU。
-
-
图片/字模转换工具:
-
Img2Lcd
-
LCD Image Converter
-
PCtoLCD2002 (经典汉字字模工具)
-
Bmp2Lcd
-
-
调试工具: 逻辑分析仪(抓取时序)、示波器(看信号质量)。
五、 开发注意事项
-
仔细阅读数据手册: TFT控制器的Datasheet和屏的规格书是圣经,初始化序列、命令集、时序参数都来自这里。
-
注意电源和背光: TFT屏和背光(LED)通常需要单独的电源(3.3V, 5V, 甚至更高电压),电流可能较大,确保电源设计合理。
-
引脚电平匹配: 确保MCU IO电平与TFT逻辑电平兼容(通常3.3V)。
-
时序要求: 严格遵守接口时序(建立时间、保持时间),必要时加延时。
-
内存瓶颈: 高分辨率图片和帧缓冲会消耗大量RAM和Flash,合理规划存储空间。
-
刷新率: 计算理论最大刷新率(总线速度 / (宽高每像素字节数)),评估是否满足需求。
六、 基本代码示例 (伪代码 - 基于SPI屏)
// 初始化SPI和GPIO
void TFT_Init() {
SPI_Init(SPI_BaudRatePrescaler_2); // 高速SPI
GPIO_Init(CS_PIN, OUTPUT, HIGH); // 片选初始高
GPIO_Init(DC_PIN, OUTPUT); // 数据/命令控制
GPIO_Init(RESET_PIN, OUTPUT);
// 硬件复位
GPIO_Write(RESET_PIN, LOW);
Delay(100);
GPIO_Write(RESET_PIN, HIGH);
Delay(100);
// 发送初始化命令序列
TFT_SendCommand(0x01); // 软件复位
Delay(150);
TFT_SendCommand(0x11); // 退出睡眠
Delay(255);
// ... 更多初始化命令 (设置方向、颜色模式等)
TFT_SendCommand(0x29); // 开启显示
}
// 设置显示窗口 (矩形区域)
void TFT_SetWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
TFT_SendCommand(0x2A); // 列地址设置命令
TFT_SendData(x0 >> 8); TFT_SendData(x0 & 0xFF);
TFT_SendData(x1 >> 8); TFT_SendData(x1 & 0xFF);
TFT_SendCommand(0x2B); // 行地址设置命令
TFT_SendData(y0 >> 8); TFT_SendData(y0 & 0xFF);
TFT_SendData(y1 >> 8); TFT_SendData(y1 & 0xFF);
TFT_SendCommand(0x2C); // 内存写入命令 (接下来是像素数据)
}
// 显示图片 (假设imgData是RGB565格式的数组)
void TFT_DrawImage(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint16_t *imgData) {
TFT_SetWindow(x, y, x + w - 1, y + h - 1);
GPIO_Write(CS_PIN, LOW); // 片选拉低
GPIO_Write(DC_PIN, HIGH); // 数据模式
for (uint32_t i = 0; i < (w * h); i++) {
SPI_SendData16(imgData[i]); // 发送一个16位像素 (RGB565)
}
GPIO_Write(CS_PIN, HIGH); // 片选拉高
}
// 显示一个ASCII字符 (16x8点阵)
void TFT_DrawChar(uint16_t x, uint16_t y, char c, uint16_t color, uint16_t bgcolor) {
uint8_t i, j;
uint8_t line;
const uint8_t *font = &Font8x16[c * 16]; // 指向字符字模首地址
for (i = 0; i < 16; i++) { // 16行
line = font[i];
for (j = 0; j < 8; j++) { // 8列
if (line & 0x01) {
TFT_DrawPixel(x + j, y + i, color); // 画前景色点
} else if (bgcolor != TRANSPARENT) {
TFT_DrawPixel(x + j, y + i, bgcolor); // 画背景色点
}
line >>= 1;
}
}
}
总结
在ARM嵌入式系统上驱动TFT屏显示图片和文字,核心在于:
-
正确配置硬件接口(SPI/FSMC/LTDC)。
-
准确实现TFT控制器的初始化和基本绘图函数(尤其是
SetWindow)。 -
高效处理像素数据传输(使用DMA和连续写入优化)。
-
管理字库和图片资源(转换格式、存储位置、加载方式)。
-
考虑性能优化(DMA、双缓冲、使用GUI库)。
更多推荐



所有评论(0)