用Arduino玩ESP32(03):TFT_eSPI 显示汉字

TFT_eSPI库的字符显示分析

在User_Setup.h文件内,定义要使用的系统自带字体,不用的直接省略掉

#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
//#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
//#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts

以7段数字显示为例,看TFT_eSPI.h文件的定义

// Create a null set in case some fonts not used (to prevent crash)
const  uint8_t widtbl_null[1] = {0};
PROGMEM const uint8_t chr_null[1] = {0};
PROGMEM const uint8_t* const chrtbl_null[1] = {chr_null};

typedef struct {
    const uint8_t *chartbl;
    const uint8_t *widthtbl;
    uint8_t height;
    uint8_t baseline;
    } fontinfo;

// Now fill the structure
const PROGMEM fontinfo fontdata [] = {
...
  #ifdef LOAD_FONT7   //通过预定义的字体号直接定义字体
   { (const uint8_t *)chrtbl_f7s, widtbl_f7s, chr_hgt_f7s, baseline_f7s},
  #else
   { (const uint8_t *)chrtbl_null, widtbl_null, 0, 0 },
  #endif
...
}

再看Font7srle.h文件

#include <Fonts/Font7srle.c>

#define nr_chrs_f7s 96   //字符总数,ASCII内可显示96个字符
#define chr_hgt_f7s 48   //字符高度
#define baseline_f7s 47  //基准线?目前还没搞懂什么意思
#define data_size_f7s 8  //一个字节
#define firstchr_f7s 32  //各个英文font都是从32(空格)开始

extern const unsigned char widtbl_f7s[96]; //font内96个字符各自的宽度数组
extern const unsigned char* const chrtbl_f7s[96]; //96个字符索引

再看Font7srle.c文件

PROGMEM const unsigned char widtbl_f7s[96] =          // character width table
{
        12, 12, 12, 12, 12, 12, 12, 12,     // char 32 - 39
        12, 12, 12, 12, 12, 32, 12, 12,     // char 40 - 47
        32, 32, 32, 32, 32, 32, 32, 32,     // char 48 - 55  48-57是10个数字,都是32位的像素宽度
        32, 32, 12, 12, 12, 12, 12, 12,     // char 56 - 63
        12, 12, 12, 12, 12, 12, 12, 12,     // char 64 - 71
        12, 12, 12, 12, 12, 12, 12, 12,     // char 72 - 79
        12, 12, 12, 12, 12, 12, 12, 12,     // char 80 - 87
        12, 12, 12, 12, 12, 12, 12, 12,     // char 88 - 95
        12, 12, 12, 12, 12, 12, 12, 12,     // char 96 - 103
        12, 12, 12, 12, 12, 12, 12, 12,     // char 104 - 111
        12, 12, 12, 12, 12, 12, 12, 12,     // char 112 - 119
        12, 12, 12, 12, 12, 12, 12, 12      // char 120 - 127
};

PROGMEM const unsigned char* const chrtbl_f7s[96] =        // 96个字符按顺序对应的点阵数组名称
{
        chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, 
        chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_2D, chr_f7s_2E, chr_f7s_20, 
        chr_f7s_30, chr_f7s_31, chr_f7s_32, chr_f7s_33, chr_f7s_34, chr_f7s_35, chr_f7s_36, chr_f7s_37, 
        chr_f7s_38, chr_f7s_39, chr_f7s_3A, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20,
        chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20,
        chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20,
        chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20,
        chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20,
        chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, 
        chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, 
        chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20,
        chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20, chr_f7s_20
};

显示汉字

取模略,使用的软件是PCtoLCD2002

建自己的汉字库

HanZi16.h,16X16大小,用的宋体,相当于12号字

#include <pgmspace.h>

PROGMEM const unsigned char hz16_20[] =
{
  0x04, 0x40, 0x0E, 0x50, 0x78, 0x48, 0x08, 0x48, 0x08, 0x40, 0xFF, 0xFE, 0x08, 0x40, 0x08, 0x44,
  0x0A, 0x44, 0x0C, 0x48, 0x18, 0x30, 0x68, 0x22, 0x08, 0x52, 0x08, 0x8A, 0x2B, 0x06, 0x10, 0x02
};
PROGMEM const unsigned char hz16_21[] =
{
  0x00, 0x08, 0x01, 0xFC, 0x7E, 0x10, 0x22, 0x10, 0x11, 0x20, 0x7F, 0xFE, 0x42, 0x02, 0x82, 0x04,
  0x7F, 0xF8, 0x04, 0x00, 0x07, 0xF0, 0x0A, 0x10, 0x11, 0x20, 0x20, 0xC0, 0x43, 0x30, 0x1C, 0x0E
};
PROGMEM const unsigned char hz16_22[] =
{
  0x08, 0x80, 0x08, 0x80, 0x08, 0x80, 0x11, 0xFE, 0x11, 0x02, 0x32, 0x04, 0x34, 0x20, 0x50, 0x20,
  0x91, 0x28, 0x11, 0x24, 0x12, 0x24, 0x12, 0x22, 0x14, 0x22, 0x10, 0x20, 0x10, 0xA0, 0x10, 0x40
};
PROGMEM const unsigned char hz16_23[] =
{
  0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x3F, 0xF8, 0x21, 0x08, 0x21, 0x08, 0x21, 0x08,
  0x21, 0x08, 0x21, 0x08, 0x3F, 0xF8, 0x21, 0x08, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00
};
PROGMEM const unsigned char hz16_24[] =
{
  0x00, 0x00, 0x7F, 0xFC, 0x40, 0x04, 0x40, 0x04, 0x5F, 0xF4, 0x41, 0x04, 0x41, 0x04, 0x4F, 0xE4,
  0x41, 0x04, 0x41, 0x44, 0x41, 0x24, 0x5F, 0xF4, 0x40, 0x04, 0x40, 0x04, 0x7F, 0xFC, 0x40, 0x04
};

struct  FNT_HZ16                 // 汉字字模数据结构
{
  char  Index[4];               // 汉字内码索引,存放内码,如"中",在UTF-8编码下,每个汉字占3个字节,第四个是结束符0
  const unsigned char* hz16_Id;                        // 点阵码数据       存放内码后对应的 点阵序列  每个字需要32个字节的点阵序列
  unsigned char hz_width;
};

PROGMEM const FNT_HZ16 hanzi16[] =
{
  {"我", hz16_20,16}, {"爱", hz16_21,16}, {"你", hz16_22,16}, {"中", hz16_23,16}, {"国", hz16_24,16}
};

主程序

#include <TFT_eSPI.h> // ST7735 or ST7735S驱动
#include <SPI.h>

#include "HanZi16.h"

TFT_eSPI tft = TFT_eSPI();

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  tft.init();
  tft.setRotation(0);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_YELLOW, TFT_BLACK); // 新字体不画背景色 Note: the new fonts do not draw the background colour
  drawHanzi(32, 8, "我", TFT_YELLOW);
  drawHanzi(32, 28, "爱", TFT_YELLOW);
  drawHanzi(32, 48, "你", TFT_YELLOW);
  drawHanzi(32, 68, "中", TFT_YELLOW);
  drawHanzi(32, 88, "国", TFT_YELLOW);

  char str[] = "中国我爱你";
  drawHanziS(52, 8, str, TFT_YELLOW);
}

void loop() {
  // put your main code here, to run repeatedly:

}
void drawHanzi(int32_t x, int32_t y, const char c[3], uint32_t color) {  //显示单一汉字

  for (int k = 0; k < 5; k++)
    if (hanzi16[k].Index[0] == c[0] && hanzi16[k].Index[1] == c[1] && hanzi16[k].Index[2] == c[2])
    { tft.drawBitmap(x, y, hanzi16[k].hz16_Id, hanzi16[k].hz_width, 16, color);
    }
}
void drawHanziS(int32_t x, int32_t y, const char str[], uint32_t color) { //显示整句汉字,字库目前有限,比较简单,没有换行功能,上下输出,左右输出是在函数内实现
  int y0 = y;
  for (int i = 0; i < strlen(str); i += 3) {
    drawHanzi(x, y0, str+i, color);
    y0 += 20;
  }
}
汉字显示效果.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270