STM32F4平台下如何基于自研ILI9341驱动使用位图字体?
ILI9341位图字体显示实现指南
问题背景
已实现ILI9341的SPI驱动,能正常显示位图,但无法实现位图字体显示,核心需求是基于现有lcd_pixel_write函数完成字符显示功能。
核心实现步骤
准备位图字体数据
用PC端工具(如PCtoLCD2002)生成目标字号的单色或RGB565格式点阵字体,将每个字符的点阵按ASCII码顺序存入数组。比如16x16的RGB565字体,每个字符占32字节(16行×2字节/行)。示例定义:// 示例:'A'的16x16 RGB565点阵数据 const uint16_t font_16x16_A[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07E0, 0x0810, 0x1008, 0x1008, 0x2004, 0x2004, 0x4002, 0xFFFE, 0x4002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07E0, 0x0810, 0x1008, 0x1008, 0x2004, 0x2004, 0x4002, 0xFFFE, 0x4002, 0x0000, 0x0000 }; // 字体表,按ASCII码索引对应 const uint16_t* font_16x16_table[] = { /* 0x00-0x20 控制字符可留空 */ NULL, NULL, ..., font_16x16_A, /* 对应'A'的ASCII码0x41 */ ... };实现字符显示函数
先通过ILI9341的命令设置字符的显示窗口,再将字体点阵(或结合背景色转换后的像素数据)传入lcd_pixel_write。示例代码:// 辅助函数:设置ILI9341显示窗口 void lcd_set_window(uint16_t x1, uint16_t x2, uint16_t y1, uint16_t y2) { cs_low(); // 发送列地址设置命令0x2A spi_send_byte(0x2A); spi_send_byte((x1 >> 8) & 0xFF); spi_send_byte(x1 & 0xFF); spi_send_byte((x2 >> 8) & 0xFF); spi_send_byte(x2 & 0xFF); // 发送行地址设置命令0x2B spi_send_byte(0x2B); spi_send_byte((y1 >> 8) & 0xFF); spi_send_byte(y1 & 0xFF); spi_send_byte((y2 >> 8) & 0xFF); spi_send_byte(y2 & 0xFF); // 发送写GRAM命令0x2C spi_send_byte(0x2C); cs_high(); } // 显示单个字符 void lcd_draw_char(uint16_t x, uint16_t y, char c, uint16_t fg_color, uint16_t bg_color) { // 跳过不可打印字符 if(c < 0x20 || c > 0x7E) return; // 获取字符点阵 const uint16_t* char_data = font_16x16_table[(uint8_t)c]; if(!char_data) return; // 设置字符显示窗口(16x16字体) lcd_set_window(x, x+15, y, y+15); // 准备像素缓冲区:将单色点阵转换为带背景的RGB565数据(如果是RGB字体可直接用) uint16_t buffer[16*16]; for(int i=0; i<16*16; i++){ // 假设单色点阵中0为背景,非0为前景 buffer[i] = (char_data[i] != 0) ? fg_color : bg_color; } // 调用现有函数发送像素数据 lcd_pixel_write((uint8_t*)buffer, sizeof(buffer)); }扩展字符串显示
循环调用字符显示函数,每次x坐标累加字体宽度即可实现字符串显示:void lcd_draw_string(uint16_t x, uint16_t y, const char* str, uint16_t fg_color, uint16_t bg_color) { while(*str) { lcd_draw_char(x, y, *str++, fg_color, bg_color); x += 16; // 16为字体宽度 // 超出屏幕范围时换行,可自行添加逻辑 } }
关键注意事项
- 确保字体点阵格式与SPI传输格式匹配:你的
lcd_pixel_write用16位传输,所以字体必须是RGB565格式,若用单色点阵需转换为RGB565颜色值; - 显示窗口的坐标不能超出ILI9341的320x240屏幕范围;
- 字体表的索引必须与字符的ASCII码一一对应,避免显示错乱;
- 若追求效率,可提前预先生成带颜色的字体数组,避免每次显示时转换。
内容的提问来源于stack exchange,提问作者franksterb92
相关产品推荐
相关产品推荐

