树莓派51/100 - Pico下用MicroPython在ssd1306上显示汉字

Pico下用MicroPython编程在ssd1306芯片上显示英文很方便,但如何显示中文呢?

直接用oled.text()函数是无法显示中文的,因为系统里没有中文字体的点阵字库,一种常用的办法就是利用framebuf把汉字的字模准备好,用blit()函数直接画出汉字。

如果你不怕麻烦,可以自己把汉字画出来,比如下面这个“龙”字,用16x16点阵表示出来,需要32个字节。
树莓派51/100 - Pico下用MicroPython在ssd1306上显示汉字
字模有了,用blit()函数直接把它显示出来即可。

import machine
import ssd1306
import framebuf

i2c = machine.I2C(1, sda=machine.Pin(14), scl=machine.Pin(15), freq=400_000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)

pattern = [0x04,0x20,0x04,0x10,0x04,0x10,0x04,0x00,0xFF,0xFE,0x04,0x80,0x04,0x88,0x04,0x88,
           0x04,0x90,0x08,0xA0,0x08,0xC0,0x10,0x82,0x11,0x82,0x22,0x82,0x44,0x7E,0x80,0x00]
buf = framebuf.FrameBuffer(bytearray(pattern), 16, 16, framebuf.MONO_HLSB)
oled.blit(buf, 0, 0)
oled.show()

这里有一个参数 framebuf.MONO_HLSB 需要了解其含义,官方的函数说明在这里,H表示水平方向的(Horizontal),LSB应该对应着英文Least Significant Bit,指高位在左侧,即8个二进制位,b7位处于最左边。刚才的”龙“字,从上到下扫描,每个字节从b7到b0排列。

另外,还有HMSB(水平方向扫描,b7在右),VLSB(垂直扫描,高位在左)。

市面上有很多人已经写好了各种各样的取字模小软件,我试了好几款:

  • TS4 点阵字库(字模)生成器V4
  • PC2LCD2002
  • HZDotReader V3
  • 一个在线字模生成网站
  • 点阵造字Makech V2.1
  • 字模提取zimo V2.2
  • ZIMOIII

如果你只用16x16或24x24的字体,用那个在线网站也挺方便,最后,我个人还是比较喜欢TS4,操作还算简洁,它可以直接生成字模的C代码,稍微修改一下就可以用于MicroPython。
树莓派51/100 - Pico下用MicroPython在ssd1306上显示汉字
我用字典fontlib把小字库保存起来,方便取字,最后的代码:

import machine
import ssd1306
import framebuf

i2c = machine.I2C(1, sda=machine.Pin(14), scl=machine.Pin(15), freq=400_000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)

fontlib = {
    "申": [0x01,0x00,0x01,0x00,0x01,0x00,0x3F,0xF8,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,
           0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x08,0x01,0x00,0x01,0x00,0x01,0x00],
    "龙": [0x04,0x20,0x04,0x10,0x04,0x10,0x04,0x00,0xFF,0xFE,0x04,0x80,0x04,0x88,0x04,0x88,
           0x04,0x90,0x08,0xA0,0x08,0xC0,0x10,0x82,0x11,0x82,0x22,0x82,0x44,0x7E,0x80,0x00],
    "斌": [0x00,0x10,0x20,0x14,0x11,0xD2,0x00,0x12,0xFC,0x10,0x0B,0xFE,0x08,0x10,0x48,0x90,
           0x28,0x90,0x12,0xD0,0x12,0x90,0x2A,0x90,0x2A,0x8A,0x4A,0xEA,0x87,0x06,0x02,0x02],
    "的": [0x10,0x40,0x10,0x40,0x20,0x40,0x7E,0x7C,0x42,0x84,0x42,0x84,0x43,0x04,0x42,0x44,
           0x7E,0x24,0x42,0x24,0x42,0x04,0x42,0x04,0x42,0x04,0x7E,0x04,0x42,0x28,0x00,0x10],
    "程": [0x08,0x00,0x1D,0xFC,0xF1,0x04,0x11,0x04,0x11,0x04,0xFD,0xFC,0x10,0x00,0x30,0x00,
           0x39,0xFE,0x54,0x20,0x54,0x20,0x91,0xFC,0x10,0x20,0x10,0x20,0x13,0xFE,0x10,0x00],
    "序": [0x01,0x00,0x00,0x80,0x3F,0xFE,0x20,0x00,0x23,0xF8,0x20,0x10,0x20,0xA0,0x20,0x40,
           0x2F,0xFE,0x20,0x42,0x20,0x44,0x20,0x40,0x40,0x40,0x40,0x40,0x81,0x40,0x00,0x80],
    "人": [0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x02,0x80,0x02,0x80,
           0x04,0x40,0x04,0x40,0x08,0x20,0x08,0x20,0x10,0x10,0x20,0x08,0x40,0x04,0x80,0x02],
    "生": [0x01,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x3F,0xFC,0x21,0x00,0x41,0x00,0x81,0x00,
           0x01,0x00,0x3F,0xF8,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xFF,0xFE,0x00,0x00],   
}

def text_hz(hz, x, y):
    zm = bytearray(fontlib[hz])
    buf = framebuf.FrameBuffer(zm, 16, 16, framebuf.MONO_HLSB)
    oled.blit(buf, x, y)

(x, y) = (0, 0)
for hz in "申龙斌的程序人生":
    text_hz(hz, x, y)
    x += 16
oled.show()

树莓派51/100 - Pico下用MicroPython在ssd1306上显示汉字

参考文献:
http://bbs.eeworld.com.cn/thread-1176472-1-1.html

https://docs.micropython.org/en/latest/library/framebuf.html

https://github.com/jdhxyy/ssd1306py-micropython

上一篇:0x01背景知识


下一篇:#C51串口通讯5-#一串数据#中断定时+超时接收+CRC校验