欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > 2025 年最新树莓派 Pico 连接 OLED 显示字模汉字详细教程

2025 年最新树莓派 Pico 连接 OLED 显示字模汉字详细教程

2025/5/6 14:01:50 来源:https://blog.csdn.net/qq_47452807/article/details/146927670  浏览:    关键词:2025 年最新树莓派 Pico 连接 OLED 显示字模汉字详细教程

OLED 概述

OLED(Organic Light-Emitting Diode,有机发光二极管)是一种基于有机材料的发光技术,通过电流驱动有机薄膜发光,具有自发光、高对比度、柔性可弯曲等特点。

在这里插入图片描述

4 针脚 OLED 硬件电路如图所示,GND 接 GND,VCC 接 3.3V,给 OLED 供电,剩下的是 SCL 和 SDA 是 I2C 的通信引脚,需要接在单片机 I2C 通信的引脚上,由于驱动函数模块用的是 GPIO 口模拟的 I2C 通信,所以这两个端口就可以接在任意的 GPIO 口上。

在这里插入图片描述
附加:Arduino 连接

在这里插入图片描述

SCL / SDA

SCL 和 SDA 是 I²C(Inter-Integrated Circuit,集成电路总线) 通信协议中的两条关键信号线,用于连接主设备(Master)和从设备(Slave)进行数据交换。

SCL(Serial Clock Line,串行时钟线)

由主设备控制,用于同步数据传输的时钟信号。决定数据传输的速率(频率通常为 100kHz(标准模式)、400kHz(快速模式)、1MHz(高速模式)或更高)。

SDA(Serial Data Line,串行数据线)

双向数据线,用于主从设备之间的实际数据传输。数据在SCL的上升沿或下降沿被采样(具体取决于协议模式)。

数据传输概述

主机写数据到从机
在这里插入图片描述

主机由从机中读数据
在这里插入图片描述

12C 通讯复合格式
在这里插入图片描述
其中 S 表示由主机的 I2C 接口产生的传输起始信号(S),这时连接到 I2C 总线上的所有从机都会接收到这个信号。 起始信号产生后,所有从机就开始等待主机紧接下来广播的从机地址信号 (SLAVE_ADDRESS)。

在 I2C 总线上,每个设备的地址都是唯一的,当主机广播的地址与某个设备地址相同时,根据 I2C 协议,这个从机地址可以是 7 位或 10 位。 在地址位之后,是传输方向的选择位,该位为 0 即主机向从机写数据。该位为 1 时,则相反,即主机由从机读数据。在此传输后选择数据寄存器和命令寄存器两种,传输到对应寄存器表示要传输数据 / 命令。

从机接收到匹配的地址后,主机或从机会返回一个应答 (ACK) 或非应答 (NACK) 信号, 只有接收到应答信号后,主机才能继续发送或接收数据。重复这个过程,可以向从机传输 N 个数据, 这个 N 没有大小限制

① 起始信号与停止信号 ② 应答信号 ③ 数据的有效性 ④ 数据传输

SSD1306

# MicroPython SSD1306 OLED driver, I2C and SPI interfacesfrom micropython import const
import framebuf# register definitions
SET_CONTRAST = const(0x81)
SET_ENTIRE_ON = const(0xA4)
SET_NORM_INV = const(0xA6)
SET_DISP = const(0xAE)
SET_MEM_ADDR = const(0x20)
SET_COL_ADDR = const(0x21)
SET_PAGE_ADDR = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP = const(0xA0)
SET_MUX_RATIO = const(0xA8)
SET_COM_OUT_DIR = const(0xC0)
SET_DISP_OFFSET = const(0xD3)
SET_COM_PIN_CFG = const(0xDA)
SET_DISP_CLK_DIV = const(0xD5)
SET_PRECHARGE = const(0xD9)
SET_VCOM_DESEL = const(0xDB)
SET_CHARGE_PUMP = const(0x8D)# Subclassing FrameBuffer provides support for graphics primitives
# http://docs.micropython.org/en/latest/pyboard/library/framebuf.html
class SSD1306(framebuf.FrameBuffer):def __init__(self, width, height, external_vcc):self.width = widthself.height = heightself.external_vcc = external_vccself.pages = self.height // 8self.buffer = bytearray(self.pages * self.width)super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)self.init_display()def init_display(self):for cmd in (SET_DISP | 0x00,  # off# address settingSET_MEM_ADDR,0x00,  # horizontal# resolution and layoutSET_DISP_START_LINE | 0x00,SET_SEG_REMAP | 0x01,  # column addr 127 mapped to SEG0SET_MUX_RATIO,self.height - 1,SET_COM_OUT_DIR | 0x08,  # scan from COM[N] to COM0SET_DISP_OFFSET,0x00,SET_COM_PIN_CFG,0x02 if self.width > 2 * self.height else 0x12,# timing and driving schemeSET_DISP_CLK_DIV,0x80,SET_PRECHARGE,0x22 if self.external_vcc else 0xF1,SET_VCOM_DESEL,0x30,  # 0.83*Vcc# displaySET_CONTRAST,0xFF,  # maximumSET_ENTIRE_ON,  # output follows RAM contentsSET_NORM_INV,  # not inverted# charge pumpSET_CHARGE_PUMP,0x10 if self.external_vcc else 0x14,SET_DISP | 0x01,):  # onself.write_cmd(cmd)self.fill(0)self.show()def poweroff(self):self.write_cmd(SET_DISP | 0x00)def poweron(self):self.write_cmd(SET_DISP | 0x01)def contrast(self, contrast):self.write_cmd(SET_CONTRAST)self.write_cmd(contrast)def invert(self, invert):self.write_cmd(SET_NORM_INV | (invert & 1))def show(self):x0 = 0x1 = self.width - 1if self.width == 64:# displays with width of 64 pixels are shifted by 32x0 += 32x1 += 32self.write_cmd(SET_COL_ADDR)self.write_cmd(x0)self.write_cmd(x1)self.write_cmd(SET_PAGE_ADDR)self.write_cmd(0)self.write_cmd(self.pages - 1)self.write_data(self.buffer)class SSD1306_I2C(SSD1306):def __init__(self, width, height, i2c, addr=0x3C, external_vcc=False):self.i2c = i2cself.addr = addrself.temp = bytearray(2)self.write_list = [b"\x40", None]  # Co=0, D/C#=1super().__init__(width, height, external_vcc)def write_cmd(self, cmd):self.temp[0] = 0x80  # Co=1, D/C#=0self.temp[1] = cmdself.i2c.writeto(self.addr, self.temp)def write_data(self, buf):self.write_list[1] = bufself.i2c.writevto(self.addr, self.write_list)class SSD1306_SPI(SSD1306):def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):self.rate = 10 * 1024 * 1024dc.init(dc.OUT, value=0)res.init(res.OUT, value=0)cs.init(cs.OUT, value=1)self.spi = spiself.dc = dcself.res = resself.cs = csimport timeself.res(1)time.sleep_ms(1)self.res(0)time.sleep_ms(10)self.res(1)super().__init__(width, height, external_vcc)def write_cmd(self, cmd):self.spi.init(baudrate=self.rate, polarity=0, phase=0)self.cs(1)self.dc(0)self.cs(0)self.spi.write(bytearray([cmd]))self.cs(1)def write_data(self, buf):self.spi.init(baudrate=self.rate, polarity=0, phase=0)self.cs(1)self.dc(1)self.cs(0)self.spi.write(buf)self.cs(1)

SSD1306_I2C

import machine
import ssd1306i2c = machine.I2C(0, sda=machine.Pin(0), scl=machine.Pin(1), freq=400000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
oled.fill(1)
oled.show()oled.fill(0)
oled.show()oled.text("Hello World!", 0, 9, 1)
oled.text("Huanxingshouwan!", 0, 18, 1)
oled.show()

字模编码

推荐字模编码网站:https://www.23bei.com/tool/216.html

输出格式:C51
数据排列:从左到右从上到下
取模方式:横向8点左高位
黑白取反:正常
字体种类:[HZK1616宋体]
import machine
import ssd1306
import framebufi2c = machine.I2C(0, sda=machine.Pin(0), scl=machine.Pin(1), freq=400_000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)oled.fill(1)
oled.show()oled.fill(0)
oled.show()fontlib = {"唤": [0x00,0x40,0x08,0x40,0x7C,0xF8,0x49,0x10,0x4A,0x24,0x49,0xFE,0x49,0x24,0x49,0x24,
0x49,0x24,0x49,0x24,0x4F,0xFE,0x78,0x20,0x48,0x50,0x00,0x88,0x01,0x06,0x06,0x04],"醒": [0x04,0x04,0xFE,0xFE,0x28,0x84,0x28,0xFC,0xFE,0x84,0xAA,0xFC,0xAA,0x20,0xAE,0xA0,
0xC2,0xFC,0x83,0x20,0x82,0x20,0xFE,0xFC,0x82,0x20,0x82,0x24,0xFF,0xFE,0x82,0x00],"手": [0x00,0x10,0x00,0xF8,0x7F,0x00,0x01,0x00,0x01,0x10,0x3F,0xF8,0x01,0x00,0x01,0x00,
0x01,0x04,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00],"腕": [0x08,0x40,0x7C,0x20,0x4B,0xFE,0x4A,0x02,0x4D,0x04,0x79,0xDC,0x49,0x54,0x49,0x54,
0x4A,0x54,0x7A,0x54,0x4D,0x5C,0x48,0x94,0x48,0x90,0x49,0x12,0x4A,0x0E,0x9C,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 += 16oled.show()

OSError 常见问题

OSError: [Errno 5] EIO

Traceback (most recent call last):File "<stdin>", line 7, in <module>File "ssd1306.py", line 113, in __init__File "ssd1306.py", line 35, in __init__File "ssd1306.py", line 70, in init_displayFile "ssd1306.py", line 118, in write_cmd
OSError: [Errno 5] EIO

OSError: [Errno 110] ETIMEDOUT

Traceback (most recent call last):File "<stdin>", line 6, in <module>File "ssd1306.py", line 110, in __init__File "ssd1306.py", line 36, in __init__File "ssd1306.py", line 73, in init_displayFile "ssd1306.py", line 101, in showFile "ssd1306.py", line 119, in write_data
OSError: [Errno 110] ETIMEDOUT

解决方案

i2c = machine.I2C(0, sda=machine.Pin(0), scl=machine.Pin(1), freq=400000)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词