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汉字显示程序实现了以下功能:
核心功能:
- 汉字编码支持:GB2312编码,支持汉字内码转换
- 多字体支持:12x12、16x16等多种点阵字体
- 显示驱动:完整的LCD驱动和点阵显示
- 文本管理:文本区域、自动换行、滚动显示
高级特性:
- 特效显示:渐显、反色、滚动效果
- 性能优化:DMA传输、字符缓存
- 扩展功能:竖排显示、旋转、缩放
- 调试工具:字符信息查询、测试程序
应用场景:
- 工业控制面板中文显示
- 智能家居设备界面
- 仪器仪表中文菜单
- 教育设备汉字教学
- 医疗设备中文提示
- 消费电子产品界面
使用建议:
- 使用专业字模软件生成字库数据
- 根据实际LCD控制器调整驱动
- 对于大量汉字,考虑使用外部Flash存储字库
- 优化显示性能,避免频繁刷新
- 添加错误处理和边界检查
这个程序可以直接用于STM32项目的中文显示需求,通过修改LCD驱动和字库数据,可以适配各种显示设备。