OLED非等宽字体格式
陈拓 2021/07/02-2021/07/07
1. 概述
用Arduino IDE进行ESP32和ESP8266开发时可以使用内置字体:
这3种字体都是非等宽的,在OLED这样的小屏幕上非等宽字体可以显示更多的字符,也更美观。
如果我们使用ESP-IRF进行ESP32开发,或者用RTOS SDK进行ESP8266开发时要使用这些字体就需要自己写OLED的显示驱动。因此我们需要了解这些非等宽字体的结构。
在Arduino IDE安装目录下的
Arduino\arduino-1.8.10\libraries\esp8266-oled-ssd1306-master\src\OLEDDisplayFonts.h文件定义了这三种字体。
如果你没有安装Arduino IDE,也可以从下面的网址找到:
https://github.com/ThingPulse/esp8266-oled-ssd1306/blob/master/src/OLEDDisplayFonts.h
如果需要更多的字体可以通过官方给定的网页定制。网址为:http://oleddisplay.squix.ch
该网页除了可以生成Arduino字体,还可以生成Adafruit GFX字体。Arduino IED也支持Adafruit GFX字体。关于Adafruit GFX字体的规范见:
《Adafruit GFX Library字体规范》
https://zhuanlan.zhihu.com/p/385486474
https://blog.csdn.net/chentuo2000/article/details/118369058
下面我们说明Arduino IDE内置非等宽字体的结构。
2. 非等宽字体的结构
用任意文本编辑工具打开OLEDDisplayFonts.h文件。或者打开网页:
https://github.com/ThingPulse/esp8266-oled-ssd1306/blob/master/src/OLEDDisplayFonts.h
其中包含了三种字体对应的3个数组ArialMT_Plain_10[]、ArialMT_Plain_16[]和ArialMT_Plain_24[]。每种字体数组由3部分组成,我们以ArialMT_Plain_10[]为例进行说明。
2.1 数组和特征说明
前四个字节是字体说明:
0x0A:字符集宽度(可变值,每个字符的实际宽度小于等于字符集宽度)
0x0D:字模高度(固定值)
0x20:第一个字符的ASCII值,从ASCII表的空格开始,空格的ASCII为32。
0xE0:字符个数224
2.2 跳转表
每个字符一行,用4个字节表示:
- 前两个字节表示字符字模所在该数组的起始位置。第一个字节为高位,第二个字节为低位。0xFF表示无地址。
- 第三个字节是字模所占的字节数
- 第四个字节表示字符的宽度,因为宽度是可变的,这是字符的实际宽度
- 注释给出了十进制的ASCII码值和数据的起始地址。例如//35:9表示ASCII码35的数据从9开始。
我们看第1个字符ASCII的空格,其数据地址是0xFF,0xFF,表示这个字符没有数据,也就是空,所以该字符的字节数是0x00。第4个字节0x03表示该字符的宽度。
第2个字符是!,ASCII为33,数据地址为0x0000,字节数为0x04,字符宽度为0x03。
第3个字符是",ASCII为34,数据地址为0x0004,字节数为0x05,字符宽度为0x04。
第4个字符是#,ASCII为35,数据地址为0x0009,字节数为0x09,字符宽度为0x06。
以此类推。
2.3 字符数据
举例,我们看字符”,双引号,ASCII码是34。
先看跳转表:0x00, 0x04, 0x05, 0x04, // 34:4
数据是从// Font Data:的0x0004处开始的0x05个字节:
0x38,0x00,0x00,0x00,0x38, // 34
字模以逐列式排列点阵,因为字符的高是13,所以每列需要2个字节,第二个字节最高3个bit没有使用,总是0。用.代表0,用x代表1,将这5个字节展开成二进制,低位在上,高位在下,按列排列。每列2个字节,第一个字节在上,第二个字节在下,如图所示。
要注意的是,为了节省空间,每个字符最后全零的字节被省略了,例如本例,按照字符的宽和高计算需要8个字节的数据,实际上只有5个字节,后面3个全零字节被省略了。
- 显示效果
下图是ESP8266 RTOS SDK驱动0.96寸OLED显示屏的效果。
注意,要删除OLEDDisplayFonts.h文件中数组定义的关键字PROGMEM。
PROGMEM关键字被Arduino和AVR编程使用,在ESP8266和ESP32的官方开发环境RTOS SDK和ESP-IDF中要删除。
参考文档
- esp8266-oled-ssd1306/src/OLEDDisplayFonts.h
https://github.com/ThingPulse/esp8266-oled-ssd1306/blob/master/src/OLEDDisplayFonts.h - 有关SimpleGUI移植非等宽字符的介绍
https://blog.csdn.net/eaglewzw/article/details/107602173