利用GB2312汉字库往LCD屏幕中间写入汉字”啊“

/*
 * ============================================================
 * 文件名:display_chinese.c
 * 功能:在 LCD 屏幕(1280x800)上显示一个 16x16 点阵汉字
 * 说明:
 *   - 使用 mmap 映射 /dev/fb0 显存,实现直接像素操作
 *   - 字库文件:HZK2312.Dzk(GB2312 16x16 点阵汉字库)
 *   - 当前显示汉字为“啊”(GB2312 编码 0xB0A1)
 *   - 字体颜色:红色(ARGB 格式 0xFF0000)
 * 作者:3360652783@qq.com
 * 编译命令:
 *   gcc display_chinese.c -o display_chinese
 * 运行命令:
 *   sudo ./display_chinese
 * 依赖文件:
 *   /home/yj/Desktop/HZK2312.Dzk(汉字库文件)
 * ============================================================
 */

#include <stdio.h>      // 标准输入输出:printf、fopen、fread、fseek、fclose
#include <sys/mman.h>   // 内存映射:mmap、munmap
#include <unistd.h>     // 系统调用:close
#include <sys/stat.h>   // 文件状态(本程序未直接使用,保留以供扩展)
#include <fcntl.h>      // 文件控制:open

/*
 * ============================================================
 * 主函数:程序入口
 * 返回值:0 表示成功,-1 表示失败
 * ============================================================
 */
int main()
{
    unsigned char buf[10] = "啊";                                       // 缓冲区暂存汉字


    int lcd_fp = open("/dev/fb0", O_RDWR);                             //打开LCD屏设备接口文件
    if (lcd_fp == -1) {
        printf("open fb0 failed");
        return -1;
    }

    FILE *font_fp = fopen("/home/yj/Desktop/HZK2312.Dzk", "rb");      //打开汉字库文件
    if (font_fp == NULL) {
        printf("open HZK2312 failed");
        close(lcd_fp);                                                // 关闭已打开的设备
        return -1;
    }

    int *lcd_mp = (int *)mmap(NULL, 1280 * 800 * 4,
                              PROT_READ | PROT_WRITE,
                              MAP_SHARED, lcd_fp, 0);


    int offset = ((buf[0] - 0xA0 - 1) * 94 +
                  (buf[1] - 0xA0 - 1)) * 32;


    fseek(font_fp, offset, SEEK_SET);            // 偏移至目标汉字位置
    unsigned char fonts[32] = {0};               // 存储 16x16 点阵数据
    fread(fonts, 1, 32, font_fp);               // 读取 32 字节字模

    unsigned char data;                         // 临时变量:存储当前字节

    // 显示位置:屏幕中央 (640, 399)
    for (int i = 0; i < 16; i++) {              // 逐行扫描
        for (int j = 0; j < 2; j++) {           // 每行 2 字节
            data = fonts[i * 2 + j];            // 取出当前字节

            for (int k = 0; k < 8; k++) {       // 逐位扫描
                if (data & 0x80) {              // 当前 bit 为 1(笔画)
                    lcd_mp[399 * 1280 + 640 + i * 1280 + j * 8 + k] = 0xFF0000;
                }
                data = data << 1;               // 左移一位,检查下一位
            }
        }
    }

    munmap(lcd_mp, 1280 * 800 * 4);     // 解除显存映射
    close(lcd_fp);                      // 关闭 LCD 设备
    fclose(font_fp);                    // 关闭字库文件

    return 0;
}
```c
posted @ 2026-08-25 20:08    阅读(13)  评论(0)    收藏  举报