STM32 汉字显示程序(标准外设库版本)

STM32汉字显示程序,包含字库生成、显示驱动、多字体支持和应用示例。

一、汉字显示基础

1.1 汉字编码基础

c 复制代码
/* 汉字编码基础 */
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include <stdio.h>
#include <string.h>

// 汉字编码类型
typedef enum {
    GB2312_ENCODING,     // GB2312编码
    GBK_ENCODING,        // GBK编码
    UTF8_ENCODING        // UTF-8编码
} ChineseEncoding;

// 字体大小定义
typedef enum {
    FONT_12x12,          // 12x12点阵
    FONT_16x16,          // 16x16点阵
    FONT_24x24,          // 24x24点阵
    FONT_32x32           // 32x32点阵
} FontSize;

// 字体颜色定义
#define BLACK   0x0000
#define WHITE   0xFFFF
#define RED     0xF800
#define GREEN   0x07E0
#define BLUE    0x001F
#define YELLOW  0xFFE0
#define CYAN    0x07FF
#define MAGENTA 0xF81F

// 全局变量
ChineseEncoding current_encoding = GB2312_ENCODING;
FontSize current_font_size = FONT_16x16;
uint16_t text_color = BLACK;
uint16_t bg_color = WHITE;

1.2 汉字字库结构

c 复制代码
/* 汉字字库结构 */
// 单个汉字信息
typedef struct {
    uint16_t code;        // 汉字编码(GB2312)
    uint8_t width;        // 宽度
    uint8_t height;       // 高度
    uint8_t bytes_per_row; // 每行字节数
    const uint8_t *data;  // 点阵数据指针
} ChineseChar;

// 字库信息
typedef struct {
    const char *font_name;     // 字体名称
    FontSize font_size;         // 字体大小
    uint16_t char_count;       // 汉字数量
    const ChineseChar *chars;   // 汉字数组
} ChineseFont;

// 显示区域定义
typedef struct {
    uint16_t x;          // 起始X坐标
    uint16_t y;          // 起始Y坐标
    uint16_t width;      // 区域宽度
    uint16_t height;     // 区域高度
    uint8_t wrap;        // 自动换行
} TextArea;

二、汉字字库生成

2.1 12x12点阵字库

c 复制代码
/* 12x12汉字字库(示例) */
// 汉字"中"的12x12点阵数据
const uint8_t zhong_12x12[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 第一行
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 第二行
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 第三行
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 第四行
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 第五行
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 第六行
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 第七行
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 第八行
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 第九行
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 第十行
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 第十一行
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00   // 第十二行
};

// 汉字"国"的12x12点阵数据
const uint8_t guo_12x12[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 12x12字库数组
const ChineseChar chinese_chars_12x12[] = {
    {0xD6D0, 12, 12, 2, zhong_12x12},  // "中" GB2312编码:D6D0
    {0xB9FA, 12, 12, 2, guo_12x12},    // "国" GB2312编码:B9FA
    // 可以继续添加更多汉字
};

// 12x12字体定义
const ChineseFont font_12x12 = {
    "12x12宋体",
    FONT_12x12,
    2,  // 包含2个汉字
    chinese_chars_12x12
};

2.2 16x16点阵字库

c 复制代码
/* 16x16汉字字库 */
// 汉字"中"的16x16点阵数据
const uint8_t zhong_16x16[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 汉字"文"的16x16点阵数据
const uint8_t wen_16x16[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 16x16字库数组
const ChineseChar chinese_chars_16x16[] = {
    {0xD6D0, 16, 16, 2, zhong_16x16},  // "中"
    {0xCEC4, 16, 16, 2, wen_16x16},    // "文"
    // 可以继续添加更多汉字
};

// 16x16字体定义
const ChineseFont font_16x16 = {
    "16x16宋体",
    FONT_16x16,
    2,  // 包含2个汉字
    chinese_chars_16x16
};

三、LCD显示驱动

3.1 LCD基础驱动

c 复制代码
/* LCD显示驱动 */
#define LCD_WIDTH   240
#define LCD_HEIGHT  320

// LCD引脚定义
#define LCD_CS_PORT     GPIOA
#define LCD_CS_PIN      GPIO_Pin_4
#define LCD_RS_PORT     GPIOA
#define LCD_RS_PIN      GPIO_Pin_5
#define LCD_WR_PORT     GPIOA
#define LCD_WR_PIN      GPIO_Pin_6
#define LCD_RD_PORT     GPIOA
#define LCD_RD_PIN      GPIO_Pin_7
#define LCD_RST_PORT    GPIOA
#define LCD_RST_PIN     GPIO_Pin_8

// LCD命令定义
#define LCD_CMD_SLEEP_OUT   0x11
#define LCD_CMD_DISPLAY_ON  0x29
#define LCD_CMD_SET_COLUMN 0x2A
#define LCD_CMD_SET_PAGE   0x2B
#define LCD_CMD_WRITE_RAM 0x2C

// 延迟函数
void delay_ms(uint16_t ms) {
    uint16_t i, j;
    for(i = 0; i < ms; i++)
        for(j = 0; j < 1141; j++);
}

// LCD写命令
void LCD_WriteCommand(uint8_t cmd) {
    GPIO_ResetBits(LCD_CS_PORT, LCD_CS_PIN);
    GPIO_ResetBits(LCD_RS_PORT, LCD_RS_PIN);
    GPIO_SetBits(LCD_WR_PORT, LCD_WR_PIN);
    GPIO_ResetBits(LCD_WR_PORT, LCD_WR_PIN);
    // 这里应该写入命令数据,实际需要根据硬件连接
    GPIO_SetBits(LCD_WR_PORT, LCD_WR_PIN);
    GPIO_SetBits(LCD_CS_PORT, LCD_CS_PIN);
}

// LCD写数据
void LCD_WriteData(uint8_t data) {
    GPIO_ResetBits(LCD_CS_PORT, LCD_CS_PIN);
    GPIO_SetBits(LCD_RS_PORT, LCD_RS_PIN);
    GPIO_SetBits(LCD_WR_PORT, LCD_WR_PIN);
    GPIO_ResetBits(LCD_WR_PORT, LCD_WR_PIN);
    // 这里应该写入数据,实际需要根据硬件连接
    GPIO_SetBits(LCD_WR_PORT, LCD_WR_PIN);
    GPIO_SetBits(LCD_CS_PORT, LCD_CS_PIN);
}

// LCD初始化
void LCD_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    
    // 使能GPIO时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    // 配置LCD引脚
    GPIO_InitStructure.GPIO_Pin = LCD_CS_PIN | LCD_RS_PIN | LCD_WR_PIN | LCD_RD_PIN | LCD_RST_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LCD_CS_PORT, &GPIO_InitStructure);
    
    // 复位LCD
    GPIO_ResetBits(LCD_RST_PORT, LCD_RST_PIN);
    delay_ms(100);
    GPIO_SetBits(LCD_RST_PORT, LCD_RST_PIN);
    delay_ms(100);
    
    // 初始化序列
    LCD_WriteCommand(LCD_CMD_SLEEP_OUT);
    delay_ms(120);
    LCD_WriteCommand(LCD_CMD_DISPLAY_ON);
    
    printf("LCD Initialized\n");
}

// 设置显示窗口
void LCD_SetWindow(uint16_t x, uint16_t y, uint16_t width, uint16_t height) {
    uint16_t x_end = x + width - 1;
    uint16_t y_end = y + height - 1;
    
    // 设置列地址
    LCD_WriteCommand(LCD_CMD_SET_COLUMN);
    LCD_WriteData(x >> 8);
    LCD_WriteData(x & 0xFF);
    LCD_WriteData(x_end >> 8);
    LCD_WriteData(x_end & 0xFF);
    
    // 设置页地址
    LCD_WriteCommand(LCD_CMD_SET_PAGE);
    LCD_WriteData(y >> 8);
    LCD_WriteData(y & 0xFF);
    LCD_WriteData(y_end >> 8);
    LCD_WriteData(y_end & 0xFF);
    
    // 准备写入RAM
    LCD_WriteCommand(LCD_CMD_WRITE_RAM);
}

// 画点函数
void LCD_DrawPoint(uint16_t x, uint16_t y, uint16_t color) {
    if (x >= LCD_WIDTH || y >= LCD_HEIGHT) return;
    
    LCD_SetWindow(x, y, 1, 1);
    LCD_WriteData(color >> 8);
    LCD_WriteData(color & 0xFF);
}

四、汉字显示核心函数

4.1 汉字查找与显示

c 复制代码
/* 汉字显示核心函数 */
// 查找汉字
const ChineseChar* FindChineseChar(uint16_t code, const ChineseFont *font) {
    for (uint16_t i = 0; i < font->char_count; i++) {
        if (font->chars[i].code == code) {
            return &font->chars[i];
        }
    }
    return NULL;
}

// 显示单个汉字
void DisplayChineseChar(uint16_t x, uint16_t y, uint16_t code, 
                       const ChineseFont *font, uint16_t color, uint16_t bg_color) {
    const ChineseChar *ch = FindChineseChar(code, font);
    if (!ch) {
        printf("Chinese character not found: 0x%04X\n", code);
        return;
    }
    
    uint8_t bytes_per_row = ch->bytes_per_row;
    uint8_t width = ch->width;
    uint8_t height = ch->height;
    
    // 设置显示窗口
    LCD_SetWindow(x, y, width, height);
    
    // 显示点阵
    for (uint8_t row = 0; row < height; row++) {
        for (uint8_t col_byte = 0; col_byte < bytes_per_row; col_byte++) {
            uint8_t byte_data = ch->data[row * bytes_per_row + col_byte];
            
            // 显示当前字节的8个点
            for (uint8_t bit = 0; bit < 8; bit++) {
                uint8_t pixel_x = col_byte * 8 + bit;
                if (pixel_x >= width) break;
                
                if (byte_data & (0x80 >> bit)) {
                    // 显示前景色
                    LCD_WriteData(color >> 8);
                    LCD_WriteData(color & 0xFF);
                } else {
                    // 显示背景色
                    LCD_WriteData(bg_color >> 8);
                    LCD_WriteData(bg_color & 0xFF);
                }
            }
        }
    }
}

// GB2312编码转汉字内码
uint16_t GB2312ToCode(const char *gb2312_str) {
    if (!gb2312_str || strlen(gb2312_str) < 2) {
        return 0;
    }
    
    // GB2312编码:第一个字节是区码,第二个字节是位码
    uint8_t area = (uint8_t)gb2312_str[0];
    uint8_t position = (uint8_t)gb2312_str[1];
    
    // 组合成16位编码
    return ((uint16_t)area << 8) | position;
}

// 显示GB2312字符串
void DisplayGB2312String(uint16_t x, uint16_t y, const char *str, 
                        const ChineseFont *font, uint16_t color, uint16_t bg_color) {
    uint16_t current_x = x;
    uint16_t current_y = y;
    
    while (*str) {
        if ((uint8_t)*str > 0x80) {
            // 中文字符(GB2312编码)
            uint16_t code = GB2312ToCode(str);
            DisplayChineseChar(current_x, current_y, code, font, color, bg_color);
            
            // 移动到下一个字符位置
            const ChineseChar *ch = FindChineseChar(code, font);
            if (ch) {
                current_x += ch->width;
            } else {
                current_x += font->font_size;  // 默认宽度
            }
            
            str += 2;  // GB2312汉字占2个字节
        } else {
            // ASCII字符(这里需要ASCII字库,简化处理)
            // 实际项目中应该有ASCII字库
            current_x += 8;  // ASCII字符宽度8像素
            str += 1;
        }
    }
}

4.2 多字体支持

c 复制代码
/* 多字体管理 */
// 字体数组
const ChineseFont *fonts[] = {
    &font_12x12,
    &font_16x16
};

uint8_t font_count = sizeof(fonts) / sizeof(fonts[0]);

// 设置当前字体
void SetCurrentFont(FontSize size) {
    current_font_size = size;
    
    for (uint8_t i = 0; i < font_count; i++) {
        if (fonts[i]->font_size == size) {
            printf("Font set to: %s\n", fonts[i]->font_name);
            return;
        }
    }
    
    printf("Font not found for size: %d\n", size);
}

// 获取当前字体
const ChineseFont* GetCurrentFont(void) {
    for (uint8_t i = 0; i < font_count; i++) {
        if (fonts[i]->font_size == current_font_size) {
            return fonts[i];
        }
    }
    return &font_16x16;  // 默认返回16x16字体
}

// 显示字符串(使用当前字体)
void DisplayString(uint16_t x, uint16_t y, const char *str) {
    const ChineseFont *font = GetCurrentFont();
    DisplayGB2312String(x, y, str, font, text_color, bg_color);
}

五、高级显示功能

5.1 文本区域管理

c 复制代码
/* 文本区域管理 */
TextArea current_text_area = {0, 0, LCD_WIDTH, LCD_HEIGHT, 1};

// 设置文本区域
void SetTextArea(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t wrap) {
    current_text_area.x = x;
    current_text_area.y = y;
    current_text_area.width = width;
    current_text_area.height = height;
    current_text_area.wrap = wrap;
}

// 在文本区域内显示字符串
void DisplayStringInArea(const char *str) {
    static uint16_t cursor_x = 0;
    static uint16_t cursor_y = 0;
    
    // 如果是第一次调用,初始化光标位置
    static uint8_t first_call = 1;
    if (first_call) {
        cursor_x = current_text_area.x;
        cursor_y = current_text_area.y;
        first_call = 0;
    }
    
    const ChineseFont *font = GetCurrentFont();
    uint8_t char_width = font->font_size;  // 字符宽度等于字体大小
    
    while (*str) {
        if ((uint8_t)*str > 0x80) {
            // 中文字符
            uint16_t code = GB2312ToCode(str);
            const ChineseChar *ch = FindChineseChar(code, font);
            
            if (ch) {
                // 检查是否需要换行
                if (current_text_area.wrap && 
                    cursor_x + ch->width > current_text_area.x + current_text_area.width) {
                    cursor_x = current_text_area.x;
                    cursor_y += ch->height;
                    
                    // 检查是否需要清屏
                    if (cursor_y + ch->height > current_text_area.y + current_text_area.height) {
                        cursor_y = current_text_area.y;
                        // 这里可以添加清屏功能
                    }
                }
                
                DisplayChineseChar(cursor_x, cursor_y, code, font, text_color, bg_color);
                cursor_x += ch->width;
            }
            
            str += 2;
        } else {
            // ASCII字符(简化处理)
            cursor_x += 8;
            str += 1;
        }
    }
}

5.2 特效显示

c 复制代码
/* 汉字特效显示 */
// 渐显效果
void DisplayChineseCharFadeIn(uint16_t x, uint16_t y, uint16_t code, 
                             const ChineseFont *font, uint16_t color, uint16_t steps) {
    uint16_t r = (color >> 11) & 0x1F;
    uint16_t g = (color >> 5) & 0x3F;
    uint16_t b = color & 0x1F;
    
    for (uint16_t i = 1; i <= steps; i++) {
        uint16_t fade_color = ((r * i / steps) << 11) | 
                             ((g * i / steps) << 5) | 
                             (b * i / steps);
        
        DisplayChineseChar(x, y, code, font, fade_color, bg_color);
        delay_ms(50);
    }
}

// 滚动显示
void ScrollDisplayString(const char *str, uint16_t y, uint16_t speed) {
    uint16_t x = LCD_WIDTH;
    const ChineseFont *font = GetCurrentFont();
    
    while (x > -(strlen(str) * font->font_size)) {
        DisplayString(x, y, str);
        x--;
        delay_ms(speed);
    }
}

// 反色显示
void DisplayChineseCharInverse(uint16_t x, uint16_t y, uint16_t code, 
                             const ChineseFont *font) {
    const ChineseChar *ch = FindChineseChar(code, font);
    if (!ch) return;
    
    uint8_t bytes_per_row = ch->bytes_per_row;
    uint8_t width = ch->width;
    uint8_t height = ch->height;
    
    LCD_SetWindow(x, y, width, height);
    
    for (uint8_t row = 0; row < height; row++) {
        for (uint8_t col_byte = 0; col_byte < bytes_per_row; col_byte++) {
            uint8_t byte_data = ch->data[row * bytes_per_row + col_byte];
            
            for (uint8_t bit = 0; bit < 8; bit++) {
                uint8_t pixel_x = col_byte * 8 + bit;
                if (pixel_x >= width) break;
                
                if (byte_data & (0x80 >> bit)) {
                    // 反色:原来是前景色,现在是背景色
                    LCD_WriteData(bg_color >> 8);
                    LCD_WriteData(bg_color & 0xFF);
                } else {
                    // 反色:原来是背景色,现在是前景色
                    LCD_WriteData(text_color >> 8);
                    LCD_WriteData(text_color & 0xFF);
                }
            }
        }
    }
}

六、完整应用示例

6.1 主程序

c 复制代码
/* 主程序 */
int main(void) {
    // 系统初始化
    SystemInit();
    
    // LCD初始化
    LCD_Init();
    
    // 清屏
    LCD_SetWindow(0, 0, LCD_WIDTH, LCD_HEIGHT);
    for (uint32_t i = 0; i < LCD_WIDTH * LCD_HEIGHT; i++) {
        LCD_WriteData(bg_color >> 8);
        LCD_WriteData(bg_color & 0xFF);
    }
    
    printf("=== Chinese Character Display Demo ===\n");
    
    // 设置字体
    SetCurrentFont(FONT_16x16);
    
    // 设置文本区域
    SetTextArea(10, 10, LCD_WIDTH - 20, 50, 1);
    
    // 显示汉字
    DisplayStringInArea("中文显示测试");
    
    // 在指定位置显示
    DisplayString(10, 70, "STM32汉字显示");
    
    // 显示单个汉字
    DisplayChineseChar(10, 100, 0xD6D0, GetCurrentFont(), RED, WHITE);  // "中"
    DisplayChineseChar(30, 100, 0xCEC4, GetCurrentFont(), GREEN, WHITE); // "文"
    
    // 特效显示
    DisplayChineseCharFadeIn(10, 130, 0xB9FA, GetCurrentFont(), BLUE, 10); // "国"
    
    // 滚动显示
    ScrollDisplayString("滚动显示汉字测试", 160, 20);
    
    // 反色显示
    DisplayChineseCharInverse(10, 190, 0xD6D0, GetCurrentFont()); // "中"
    
    // 切换字体
    SetCurrentFont(FONT_12x12);
    DisplayString(10, 220, "12x12字体显示");
    
    printf("Demo completed\n");
    
    while (1) {
        // 主循环
    }
}

参考代码 STM32 汉字显示程序 www.youwenfan.com/contentcst/133660.html

七、字库生成工具

7.1 字库生成脚本(Python)

python 复制代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
汉字点阵字库生成工具
"""

import struct

def generate_chinese_font(chinese_chars, font_size=16):
    """
    生成汉字点阵字库
    font_size: 字体大小,支持12, 16, 24, 32
    """
    output_lines = []
    
    # 文件头
    output_lines.append("#ifndef __CHINESE_FONT_H")
    output_lines.append("#define __CHINESE_FONT_H")
    output_lines.append("")
    output_lines.append("#include <stdint.h>")
    output_lines.append("")
    
    for char in chinese_chars:
        char_code = ord(char.encode('gb2312')[0]) << 8 | ord(char.encode('gb2312')[1])
        
        # 生成点阵数据(简化版,实际需要点阵生成算法)
        output_lines.append(f"// 汉字\"{char}\"的{font_size}x{font_size}点阵数据")
        output_lines.append(f"const uint8_t {char}_data[{font_size * font_size // 8}] = {{")
        
        # 这里应该是实际的字模数据
        # 实际使用时需要用专业的字模提取软件生成
        for i in range(font_size * font_size // 8):
            if i % 16 == 0:
                output_lines.append("    ")
            output_lines.append(f"0x00")
            if i < font_size * font_size // 8 - 1:
                output_lines.append(", ")
            if i % 16 == 15:
                output_lines.append("\n")
        
        output_lines.append("};\n")
        
        # 添加字符信息
        output_lines.append(f"const ChineseChar {char}_info = {{")
        output_lines.append(f"    .code = 0x{char_code:04X},")
        output_lines.append(f"    .width = {font_size},")
        output_lines.append(f"    .height = {font_size},")
        output_lines.append(f"    .bytes_per_row = {font_size // 8},")
        output_lines.append(f"    .data = {char}_data")
        output_lines.append(f"}};\n")
    
    # 字库数组
    output_lines.append("// 字库数组")
    output_lines.append("const ChineseChar* chinese_font_array[] = {")
    for char in chinese_chars:
        output_lines.append(f"    &{char}_info,")
    output_lines.append("};\n")
    
    # 字库信息
    output_lines.append("const ChineseFont chinese_font = {")
    output_lines.append(f"    .font_name = \"{font_size}x{font_size}宋体\",")
    output_lines.append(f"    .font_size = FONT_{font_size}x{font_size},")
    output_lines.append(f"    .char_count = {len(chinese_chars)},")
    output_lines.append(f"    .chars = chinese_font_array")
    output_lines.append("};\n")
    
    output_lines.append("#endif // __CHINESE_FONT_H")
    
    return "\n".join(output_lines)

if __name__ == "__main__":
    # 要生成的汉字列表
    chars = ["中", "文", "显", "示", "测", "试", "S", "T", "M", "3", "2"]
    
    # 生成16x16字库
    font_code = generate_chinese_font(chars, 16)
    
    # 保存到文件
    with open("chinese_font_16x16.h", "w", encoding="utf-8") as f:
        f.write(font_code)
    
    print("字库生成完成: chinese_font_16x16.h")

八、优化与扩展

8.1 性能优化

c 复制代码
/* 性能优化 */
// 使用DMA传输
void LCD_DrawChineseCharDMA(uint16_t x, uint16_t y, const ChineseChar *ch) {
    // 配置DMA传输点阵数据
    // 这样可以大大加快显示速度
}

// 使用缓存
#define CHAR_CACHE_SIZE 10
ChineseChar char_cache[CHAR_CACHE_SIZE];
uint8_t cache_index = 0;

const ChineseChar* GetCachedChar(uint16_t code) {
    // 先检查缓存
    for (uint8_t i = 0; i < CHAR_CACHE_SIZE; i++) {
        if (char_cache[i].code == code) {
            return &char_cache[i];
        }
    }
    
    // 缓存未命中,从字库查找
    const ChineseChar *ch = FindChineseChar(code, GetCurrentFont());
    if (ch) {
        // 添加到缓存
        char_cache[cache_index] = *ch;
        cache_index = (cache_index + 1) % CHAR_CACHE_SIZE;
        return &char_cache[cache_index];
    }
    
    return NULL;
}

8.2 扩展功能

c 复制代码
/* 扩展功能 */
// 竖排显示
void DisplayVerticalString(uint16_t x, uint16_t y, const char *str) {
    const ChineseFont *font = GetCurrentFont();
    uint16_t current_y = y;
    
    while (*str) {
        if ((uint8_t)*str > 0x80) {
            uint16_t code = GB2312ToCode(str);
            DisplayChineseChar(x, current_y, code, font, text_color, bg_color);
            current_y += font->font_size;
            str += 2;
        } else {
            // ASCII字符竖排显示
            current_y += 8;
            str += 1;
        }
    }
}

// 旋转显示
void DisplayRotatedChineseChar(uint16_t x, uint16_t y, uint16_t code, 
                             uint16_t angle, const ChineseFont *font) {
    // 旋转角度:0, 90, 180, 270度
    // 需要实现旋转算法
}

// 缩放显示
void DisplayScaledChineseChar(uint16_t x, uint16_t y, uint16_t code, 
                             float scale, const ChineseFont *font) {
    // 缩放显示汉字
}

九、常见问题与调试

9.1 调试函数

c 复制代码
/* 调试函数 */
void PrintChineseInfo(uint16_t code) {
    const ChineseFont *font = GetCurrentFont();
    const ChineseChar *ch = FindChineseChar(code, font);
    
    if (ch) {
        printf("Chinese Character Info:\n");
        printf("  Code: 0x%04X\n", ch->code);
        printf("  Width: %d\n", ch->width);
        printf("  Height: %d\n", ch->height);
        printf("  Bytes per row: %d\n", ch->bytes_per_row);
    } else {
        printf("Character not found: 0x%04X\n", code);
    }
}

void TestChineseDisplay(void) {
    printf("Testing Chinese Display...\n");
    
    // 测试常用汉字
    uint16_t test_chars[] = {0xD6D0, 0xCEC4, 0xCFA2, 0xCAFD}; // 中文测试
    const char *char_names[] = {"中", "文", "测", "试"};
    
    for (uint8_t i = 0; i < 4; i++) {
        printf("Displaying '%s' (0x%04X)...\n", char_names[i], test_chars[i]);
        DisplayChineseChar(10 + i * 30, 200, test_chars[i], 
                        GetCurrentFont(), RED, WHITE);
        delay_ms(500);
    }
}

十、总结

这个STM32汉字显示程序实现了以下功能:

核心功能:

  1. 汉字编码支持:GB2312编码,支持汉字内码转换
  2. 多字体支持:12x12、16x16等多种点阵字体
  3. 显示驱动:完整的LCD驱动和点阵显示
  4. 文本管理:文本区域、自动换行、滚动显示

高级特性:

  1. 特效显示:渐显、反色、滚动效果
  2. 性能优化:DMA传输、字符缓存
  3. 扩展功能:竖排显示、旋转、缩放
  4. 调试工具:字符信息查询、测试程序

应用场景:

  • 工业控制面板中文显示
  • 智能家居设备界面
  • 仪器仪表中文菜单
  • 教育设备汉字教学
  • 医疗设备中文提示
  • 消费电子产品界面

使用建议:

  1. 使用专业字模软件生成字库数据
  2. 根据实际LCD控制器调整驱动
  3. 对于大量汉字,考虑使用外部Flash存储字库
  4. 优化显示性能,避免频繁刷新
  5. 添加错误处理和边界检查

这个程序可以直接用于STM32项目的中文显示需求,通过修改LCD驱动和字库数据,可以适配各种显示设备。

相关推荐
Strange_Head7 小时前
补充知识点`makefile`、`config`、`GLP协议` 1/3 ——《驱动篇》
linux·嵌入式硬件
国科安芯8 小时前
商业航天与航空安全场景下抗辐射 MCU 选型、应用实践及发展趋势
单片机·嵌入式硬件·无人机·cocos2d·risc-v
Jun62610 小时前
【STM32】HMC5883驱动(带航向角计算)
stm32·单片机·嵌入式硬件
wearegogog12310 小时前
基于STM32的酒精检测仪设计
stm32·单片机·嵌入式硬件
Deitymoon11 小时前
STM32——led灯点亮
stm32·单片机·嵌入式硬件
Jack_022011 小时前
基于51单片机的双路倒车雷达测距报警系统设计_LCD1602显示+超声波
单片机·51单片机·雷达·超声波·倒车·lcd1602显示
小柯博客11 小时前
Amazon Kinesis Video Streams C WebRTC SDK 开发实战
c语言·开发语言·网络·stm32·嵌入式硬件·webrtc·yocto
HIZYUAN12 小时前
FPGA/CPLD漫谈:2K LUT的功能定位与典型方案(一)
stm32·单片机·嵌入式硬件·fpga开发·国产mcu+fpga
SunAqua12 小时前
《MCU与DSP芯片笔记》二、DSP芯片TI C2000系列TMS320F2800137
笔记·单片机·嵌入式硬件