You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 11:37:06