本帖最后由 lemon1394 于 2022-9-29 08:57 编辑
在SSD1306等OLED屏上显示汉字
首先要取得汉字的点阵,再用得到的点阵制作一个framebuf,SSD1306再把framebuf用blit方法绘制到屏幕上。HZK16是用的区位码,但是micropython只支持UTF-8编码,所以需要在PC机上制作一个转码表,通过读表的方法取得区位码。
制作转码表
buf = bytearray()
for i in range(0x4e00, 0x9FA6): # 汉字的UTF—8编码范围从4E00到9FA5
data = chr(i).encode('GBK') # 把每个汉字的转成GBK编码
data[0] -= 160 # GBK转区位码,高低位都要-0xA0
data[1] -= 160
buf += data
with open('uni2gbk', 'wb') as f:
f.write(buf)
读HZK16
with open('/font/uni2gbk', 'rb') as f:
f.seek((ord('我') - 19968)*2) # 19968 = 0x4E00
offset = f.read(2)
with open('/font/HZK16', 'rb') as f:
f.seek((94*(offset[0]- 1) + (offset[1] - 1))*32) # 可以把这里的计算到要转码表里,提高效率
buf = f.read(32)
blit绘制
font = framebuf.FrameBuffer(bytearray(buf), 16, 16, framebuf.MONO_HLSB)
# 创建字体的framebuf,buf是刚才取出的汉字点阵,后面是宽度,高度,点阵格式
oled.blit(font,0,0) # 用blit方法把font绘制到oled的0,0位置
oled.show()
连续文字可以制作一个大的framebuf,把每个文字的frambuf用blit方绘制进去,再一起绘制到OLED。
中英文的混合显示只要判断一下ord(),小于128就用ASC16,大于就用HZK16,只要注意ASC16的framebuf是8x16的,不是汉字的16x16.
在TFT彩屏上显示汉字
第一步也获取点阵,还是一样的字库,一样的获取方法,只是framebuf的格式不一样,单色屏用的是MONO_HLSB格式,而TFT屏用的是RGB565,这个转换的方法我找遍全网,没有网友分享,我最后在micropython的官方Github上找到一个示例:
# Test blit between different color spaces
try:
import framebuf, usys
except ImportError:
print("SKIP")
raise SystemExit
# Monochrome glyph/icon
w = 8
h = 8
cbuf = bytearray(w * h // 8)
fbc = framebuf.FrameBuffer(cbuf, w, h, framebuf.MONO_HLSB)
fbc.line(0, 0, 7, 7, 1)
# RGB565 destination
wd = 16
hd = 16
dest = bytearray(wd * hd * 2)
fbd = framebuf.FrameBuffer(dest, wd, hd, framebuf.RGB565)
wp = 2
bg = 0x1234
fg = 0xF800
pal = bytearray(wp * 2)
palette = framebuf.FrameBuffer(pal, wp, 1, framebuf.RGB565)
palette.pixel(0, 0, bg)
palette.pixel(1, 0, fg)
fbd.blit(fbc, 0, 0, -1, palette)
print(fbd.pixel(0, 0) == fg)
print(fbd.pixel(7, 7) == fg)
print(fbd.pixel(8, 8) == 0) # Ouside blit
print(fbd.pixel(0, 1) == bg)
print(fbd.pixel(1, 0) == bg)
这个示例先制作一个palette,bg是背景色,fg是前景色,就是字体颜色。
制作一个接收彩色字体的framebuf,再用blit方法把刚才的字体绘制到接收framebuf里,再把接收framebuf绘制到TFT里可以了
palette = framebuf.FrameBuffer(bytearray(2*1*2), 2, 1, framebuf.RGB565) # 创建palette
palette.pixel(0, 0, bg) # 设置背景色
palette.pixel(1, 0, fg) # 设置字体颜色
buf_rgb565 = framebuf.FrameBuffer(bytearray(16 *16 * 2 ), 16, 16, framebuf.RGB565) # 接收framebuf
buf_rgb565.blit(font, 0, 0, -1, palette)
tft.blit(buf_rgb565, 0, 0)
tft.show()
用blit方法如果单片机反复重启,这时可能你获取到的点阵数据是空的。